home *** CD-ROM | disk | FTP | other *** search
- ::::::::::
- parser.pro
- ::::::::::
-
- -------- SIMTEL20 Ada Software Repository Prologue ------------
- -- -*
- -- Unit name : PARSER
- -- Version : 1.0
- -- Author : Richard Conn
- -- : Texas Instruments, Ada Technology Branch
- -- : PO Box 801, MS 8007
- -- : McKinney, TX 75069
- -- DDN Address : RCONN at SIMTEL20
- -- Copyright : (c)
- -- Date created : 21 July 85
- -- Release date : 30 July 85
- -- Last update : 30 July 85
- -- Machine/System Compiled/Run on : DG MV10000 (ROLM ADE) and
- -- DEC VAX 11/785 (DEC Ada)
- -- -*
- ---------------------------------------------------------------
- -- -*
- -- Keywords : parser, generic parser, UNIX, ARGC, ARGV
- ----------------:
- --
- -- Abstract :
- --
- --| PARSER is a generic parser that functions in a manner similar to
- --| the ARGC/ARGV parser of UNIX. It contains one procedure, PARSE,
- --| which accepts a string as input and returns ARGC, a count of the number
- --| of tokens in the string, and ARGV, a vector of strings, each string
- --| containing a token.
- --|
- --| PARSER is instantiated with two strings (DEL for DELIMITER and
- --| DEL_TOKEN for DELIMITER_TOKEN). The DEL string is composed of characters
- --| which delimit each token (and are not a part of the token). All
- --| characters less than space are automatically delimiters, and the DEL
- --| string should contain at least one character (such as a space).
- --| DEL_TOKEN is a string composed of characters which delimit tokens and
- --| which are tokens themselves. If "=" is a DEL_TOKEN, for example, then
- --| "CAT= DOG" is composed of three tokens, "CAT", "=", and "DOG", where if
- --| "=" is a DEL, then "CAT= DOG" is composed of two tokens, "CAT" and "DOG".
- --| This assumes that the space character is a DEL.
- --|
- --| PARSER may also be instantiated with ARGC_LIMIT, which indicates the
- --| maximum number of tokens allowed. If this limit is exceeded, then the
- --| last ARGV token contains the remainder of the string. The default value
- --| of ARGC_LIMIT is 20.
- --|
- --| ARG_STRING_LENGTH is the last instantiation option for PARSER. It
- --| indicates the maximum length of an ARGV string, and it defaults to 80.
- --|
- -- -*
- ------------------ Revision history ---------------------------
- -- -*
- -- DATE VERSION AUTHOR HISTORY
- -- 19850730 1.0 Richard Conn Initial Release
- -- -*
- ------------------ Distribution and Copyright -----------------
- -- -*
- -- This prologue must be included in all copies of this software.
- --
- -- This software is released to the Ada community.
- -- This software is released to the Public Domain (note:
- -- software released to the Public Domain is not subject
- -- to copyright protection).
- -- Restrictions on use or distribution: NONE
- -- -*
- ------------------ Disclaimer ---------------------------------
- -- -*
- -- This software and its documentation are provided "AS IS" and
- -- without any expressed or implied warranties whatsoever.
- -- No warranties as to performance, merchantability, or fitness
- -- for a particular purpose exist.
- --
- -- Because of the diversity of conditions and hardware under
- -- which this software may be used, no warranty of fitness for
- -- a particular purpose is offered. The user is advised to
- -- test the software thoroughly before relying on it. The user
- -- must assume the entire risk and liability of using this
- -- software.
- --
- -- In no event shall any person or organization of people be
- -- held responsible for any direct, indirect, consequential
- -- or inconsequential damages or lost profits.
- -- -*
- -------------------END-PROLOGUE--------------------------------
- ::::::::::
- parser.ada
- ::::::::::
- --|MODULE: PARSER
- --|AUTHOR: CONN
- --|LOCATION: COMPONENTS
- --|ABSTRACT:
- --| PARSER is a generic parser that functions in a manner similar to
- --| the ARGC/ARGV parser of UNIX. It contains one procedure, PARSE,
- --| which accepts a string as input and returns ARGC, a count of the number
- --| of tokens in the string, and ARGV, a vector of strings, each string
- --| containing a token.
- --|
- --| PARSER is instantiated with two strings (DEL for DELIMITER and
- --| DEL_TOKEN for DELIMITER_TOKEN). The DEL string is composed of characters
- --| which delimit each token (and are not a part of the token). All
- --| characters less than space are automatically delimiters, and the DEL
- --| string should contain at least one character (such as a space).
- --| DEL_TOKEN is a string composed of characters which delimit tokens and
- --| which are tokens themselves. If "=" is a DEL_TOKEN, for example, then
- --| "CAT= DOG" is composed of three tokens, "CAT", "=", and "DOG", where if
- --| "=" is a DEL, then "CAT= DOG" is composed of two tokens, "CAT" and "DOG".
- --| This assumes that the space character is a DEL.
- --|
- --| PARSER may also be instantiated with ARGC_LIMIT, which indicates the
- --| maximum number of tokens allowed. If this limit is exceeded, then the
- --| last ARGV token contains the remainder of the string. The default value
- --| of ARGC_LIMIT is 20.
- --|
- --| ARG_STRING_LENGTH is the last instantiation option for PARSER. It
- --| indicates the maximum length of an ARGV string, and it defaults to 80.
- --|
- generic
- DEL : STRING;
- DEL_TOKEN : STRING;
- ARGC_LIMIT : NATURAL := 20;
- ARG_STRING_LENGTH : NATURAL := 80;
-
- package PARSER is
-
- --
- -- The following defines the system-dependent types/constants used within this
- -- package. It will probably be necessary to customize them for the
- -- application.
- --
- subtype ARG_STRING is STRING (1 .. ARG_STRING_LENGTH);
-
- --
- -- The following defines the PARSER-specific types which will be referenced
- -- externally.
- --
- type ARGUMENT is
- record
- ARG_TEXT : ARG_STRING;
- ARG_LAST : NATURAL;
- end record;
- type ARGS is array (1 .. ARGC_LIMIT) of ARGUMENT;
-
- --
- -- The following is the parser routine
- --
- procedure PARSE (INPUT_LINE : STRING;
- ARGC : out NATURAL;
- ARGV : out ARGS);
-
- end PARSER;
-
- package body PARSER is
-
- procedure PARSE (INPUT_LINE : STRING;
- ARGC : out NATURAL;
- ARGV : out ARGS) is
- LARGC : NATURAL;
- LARGV : ARGS;
- POS : NATURAL;
- APOS : NATURAL;
- TPOS : NATURAL;
-
- DELIM, DELIM_TOKEN, DELIM_TOKEN_FIRST : exception;
-
- begin
- POS := INPUT_LINE'FIRST;
- LARGC := 0;
- loop
- exit when POS > INPUT_LINE'LAST;
- if INPUT_LINE (POS) > ' ' then
- LARGC := LARGC + 1;
- APOS := LARGV (LARGC).ARG_TEXT'FIRST;
- if LARGC = ARGC_LIMIT then
- while POS <= INPUT_LINE'LAST loop
- LARGV (LARGC).ARG_TEXT (APOS) := INPUT_LINE (POS);
- APOS := APOS + 1;
- POS := POS + 1;
- end loop;
- TPOS := POS;
- else
- begin
- for J in DEL_TOKEN'FIRST .. DEL_TOKEN'LAST loop
- if INPUT_LINE (POS) = DEL_TOKEN (J) then
- raise DELIM_TOKEN_FIRST;
- end if;
- end loop;
- for I in POS .. INPUT_LINE'LAST loop
- TPOS := I;
- exit when INPUT_LINE (I) < ' ';
- for J in DEL'FIRST .. DEL'LAST loop
- if INPUT_LINE (I) = DEL (J) then
- raise DELIM;
- end if;
- end loop;
- for J in DEL_TOKEN'FIRST .. DEL_TOKEN'LAST loop
- if INPUT_LINE (I) = DEL_TOKEN (J) then
- raise DELIM_TOKEN;
- end if;
- end loop;
- if APOS <= LARGV (LARGC).ARG_TEXT'LAST then
- LARGV (LARGC).ARG_TEXT (APOS) :=
- INPUT_LINE (I);
- APOS := APOS + 1;
- end if;
- end loop;
- exception
- when DELIM =>
- null;
- when DELIM_TOKEN =>
- TPOS := TPOS - 1;
- when DELIM_TOKEN_FIRST =>
- LARGV (LARGC).ARG_TEXT (APOS) := INPUT_LINE (POS);
- APOS := APOS + 1;
- TPOS := POS;
- when others =>
- raise;
- end;
- end if;
- LARGV (LARGC).ARG_LAST := APOS - 1;
- POS := TPOS;
- end if;
- POS := POS + 1;
- end loop;
- ARGC := LARGC;
- ARGV := LARGV;
- end PARSE;
-
- end PARSER;
- ::::::::::
- ptest.ada
- ::::::::::
- with PARSER,
- TEXT_IO;
- procedure PTEST is
- INLINE : STRING (1 .. 80);
- LAST : NATURAL;
- package NATIO is new TEXT_IO.INTEGER_IO (NATURAL);
- --
- -- Set up PARSER Package
- --
- MY_DELIMITER : STRING (1 .. 2) := " ,";
- MY_DELIMITER_TOKEN : STRING (1 .. 22) := "!&'()*+-/:;<=>?[\]{|}~";
- package MYPARSE is new PARSER
- (ARGC_LIMIT => 10,
- DEL => MY_DELIMITER,
- DEL_TOKEN => MY_DELIMITER_TOKEN);
- use MYPARSE;
- ARGC : NATURAL;
- ARGV : ARGS;
- --
- begin
- loop
- TEXT_IO.PUT ("Line> ");
- TEXT_IO.GET_LINE (INLINE, LAST);
- exit when LAST = 0;
- PARSE (INLINE (1 .. LAST), ARGC, ARGV);
- TEXT_IO.PUT ("Argument count = ");
- NATIO.PUT (ARGC, 2);
- TEXT_IO.NEW_LINE;
- if ARGC > 0 then
- for I in 1 .. ARGC loop
- NATIO.PUT (I, 2);
- TEXT_IO.PUT (" - ");
- NATIO.PUT (ARGV (I).ARG_LAST, 2);
- TEXT_IO.PUT ("> ");
- TEXT_IO.PUT (ARGV (I).ARG_TEXT (1 .. ARGV (I).ARG_LAST));
- TEXT_IO.NEW_LINE;
- end loop;
- end if;
- end loop;
- end PTEST;
-