home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / misc / parser.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  10.8 KB  |  275 lines

  1. ::::::::::
  2. parser.pro
  3. ::::::::::
  4.  
  5. -------- SIMTEL20 Ada Software Repository Prologue ------------
  6. --                                                           -*
  7. -- Unit name    : PARSER
  8. -- Version      : 1.0
  9. -- Author       : Richard Conn
  10. --              : Texas Instruments, Ada Technology Branch
  11. --              : PO Box 801, MS 8007
  12. --              : McKinney, TX  75069
  13. -- DDN Address  : RCONN at SIMTEL20
  14. -- Copyright    : (c) 
  15. -- Date created :  21 July 85
  16. -- Release date :  30 July 85
  17. -- Last update  :  30 July 85
  18. -- Machine/System Compiled/Run on : DG MV10000 (ROLM ADE) and
  19. --                    DEC VAX 11/785 (DEC Ada)
  20. --                                                           -*
  21. ---------------------------------------------------------------
  22. --                                                           -*
  23. -- Keywords     :  parser, generic parser, UNIX, ARGC, ARGV
  24. ----------------:
  25. --
  26. -- Abstract     :  
  27. --
  28. --|   PARSER is a generic parser that functions in a manner similar to
  29. --| the ARGC/ARGV parser of UNIX.  It contains one procedure, PARSE,
  30. --| which accepts a string as input and returns ARGC, a count of the number
  31. --| of tokens in the string, and ARGV, a vector of strings, each string
  32. --| containing a token.
  33. --|
  34. --|   PARSER is instantiated with two strings (DEL for DELIMITER and
  35. --| DEL_TOKEN for DELIMITER_TOKEN).  The DEL string is composed of characters
  36. --| which delimit each token (and are not a part of the token).  All
  37. --| characters less than space are automatically delimiters, and the DEL
  38. --| string should contain at least one character (such as a space).
  39. --| DEL_TOKEN is a string composed of characters which delimit tokens and
  40. --| which are tokens themselves.  If "=" is a DEL_TOKEN, for example, then
  41. --| "CAT= DOG" is composed of three tokens, "CAT", "=", and "DOG", where if
  42. --| "=" is a DEL, then "CAT= DOG" is composed of two tokens, "CAT" and "DOG".
  43. --| This assumes that the space character is a DEL.
  44. --|
  45. --|   PARSER may also be instantiated with ARGC_LIMIT, which indicates the
  46. --| maximum number of tokens allowed.  If this limit is exceeded, then the
  47. --| last ARGV token contains the remainder of the string.  The default value
  48. --| of ARGC_LIMIT is 20.
  49. --|
  50. --|   ARG_STRING_LENGTH is the last instantiation option for PARSER.  It
  51. --| indicates the maximum length of an ARGV string, and it defaults to 80.
  52. --|
  53. --                                                           -*
  54. ------------------ Revision history ---------------------------
  55. --                                                           -*
  56. -- DATE         VERSION    AUTHOR                  HISTORY
  57. -- 19850730        1.0  Richard Conn            Initial Release
  58. --                                                           -*
  59. ------------------ Distribution and Copyright -----------------
  60. --                                                           -*
  61. -- This prologue must be included in all copies of this software.
  62. --
  63. -- This software is released to the Ada community.
  64. -- This software is released to the Public Domain (note:
  65. --   software released to the Public Domain is not subject
  66. --   to copyright protection).
  67. -- Restrictions on use or distribution:  NONE
  68. --                                                           -*
  69. ------------------ Disclaimer ---------------------------------
  70. --                                                           -*
  71. -- This software and its documentation are provided "AS IS" and
  72. -- without any expressed or implied warranties whatsoever.
  73. -- No warranties as to performance, merchantability, or fitness
  74. -- for a particular purpose exist.
  75. --
  76. -- Because of the diversity of conditions and hardware under
  77. -- which this software may be used, no warranty of fitness for
  78. -- a particular purpose is offered.  The user is advised to
  79. -- test the software thoroughly before relying on it.  The user
  80. -- must assume the entire risk and liability of using this
  81. -- software.
  82. --
  83. -- In no event shall any person or organization of people be
  84. -- held responsible for any direct, indirect, consequential
  85. -- or inconsequential damages or lost profits.
  86. --                                                           -*
  87. -------------------END-PROLOGUE--------------------------------
  88. ::::::::::
  89. parser.ada
  90. ::::::::::
  91. --|MODULE: PARSER
  92. --|AUTHOR: CONN
  93. --|LOCATION: COMPONENTS
  94. --|ABSTRACT:
  95. --|   PARSER is a generic parser that functions in a manner similar to
  96. --| the ARGC/ARGV parser of UNIX.  It contains one procedure, PARSE,
  97. --| which accepts a string as input and returns ARGC, a count of the number
  98. --| of tokens in the string, and ARGV, a vector of strings, each string
  99. --| containing a token.
  100. --|
  101. --|   PARSER is instantiated with two strings (DEL for DELIMITER and
  102. --| DEL_TOKEN for DELIMITER_TOKEN).  The DEL string is composed of characters
  103. --| which delimit each token (and are not a part of the token).  All
  104. --| characters less than space are automatically delimiters, and the DEL
  105. --| string should contain at least one character (such as a space).
  106. --| DEL_TOKEN is a string composed of characters which delimit tokens and
  107. --| which are tokens themselves.  If "=" is a DEL_TOKEN, for example, then
  108. --| "CAT= DOG" is composed of three tokens, "CAT", "=", and "DOG", where if
  109. --| "=" is a DEL, then "CAT= DOG" is composed of two tokens, "CAT" and "DOG".
  110. --| This assumes that the space character is a DEL.
  111. --|
  112. --|   PARSER may also be instantiated with ARGC_LIMIT, which indicates the
  113. --| maximum number of tokens allowed.  If this limit is exceeded, then the
  114. --| last ARGV token contains the remainder of the string.  The default value
  115. --| of ARGC_LIMIT is 20.
  116. --|
  117. --|   ARG_STRING_LENGTH is the last instantiation option for PARSER.  It
  118. --| indicates the maximum length of an ARGV string, and it defaults to 80.
  119. --|
  120. generic
  121.     DEL               : STRING;
  122.     DEL_TOKEN         : STRING;
  123.     ARGC_LIMIT        : NATURAL := 20;
  124.     ARG_STRING_LENGTH : NATURAL := 80;
  125.  
  126. package PARSER is
  127.  
  128. --
  129. -- The following defines the system-dependent types/constants used within this
  130. -- package.  It will probably be necessary to customize them for the
  131. -- application.
  132. --
  133.     subtype ARG_STRING is STRING (1 .. ARG_STRING_LENGTH);
  134.  
  135. --
  136. -- The following defines the PARSER-specific types which will be referenced
  137. -- externally.
  138. --
  139.     type ARGUMENT is
  140.         record
  141.             ARG_TEXT : ARG_STRING;
  142.             ARG_LAST : NATURAL;
  143.         end record;
  144.     type ARGS is array (1 .. ARGC_LIMIT) of ARGUMENT;
  145.  
  146. --
  147. -- The following is the parser routine
  148. --
  149.     procedure PARSE (INPUT_LINE : STRING;
  150.                      ARGC       : out NATURAL;
  151.                      ARGV       : out ARGS);
  152.  
  153. end PARSER;
  154.  
  155. package body PARSER is
  156.  
  157.     procedure PARSE (INPUT_LINE : STRING;
  158.                      ARGC       : out NATURAL;
  159.                      ARGV       : out ARGS) is
  160.         LARGC : NATURAL;
  161.         LARGV : ARGS;
  162.         POS   : NATURAL;
  163.         APOS  : NATURAL;
  164.         TPOS  : NATURAL;
  165.  
  166.         DELIM, DELIM_TOKEN, DELIM_TOKEN_FIRST : exception;
  167.  
  168.     begin
  169.         POS := INPUT_LINE'FIRST;
  170.         LARGC := 0;
  171.         loop
  172.             exit when POS > INPUT_LINE'LAST;
  173.             if INPUT_LINE (POS) > ' ' then
  174.                 LARGC := LARGC + 1;
  175.                 APOS := LARGV (LARGC).ARG_TEXT'FIRST;
  176.                 if LARGC = ARGC_LIMIT then
  177.                     while POS <= INPUT_LINE'LAST loop
  178.                         LARGV (LARGC).ARG_TEXT (APOS) := INPUT_LINE (POS);
  179.                         APOS := APOS + 1;
  180.                         POS := POS + 1;
  181.                     end loop;
  182.                     TPOS := POS;
  183.                 else
  184.                     begin
  185.                         for J in DEL_TOKEN'FIRST .. DEL_TOKEN'LAST loop
  186.                             if INPUT_LINE (POS) = DEL_TOKEN (J) then
  187.                                 raise DELIM_TOKEN_FIRST;
  188.                             end if;
  189.                         end loop;
  190.                         for I in POS .. INPUT_LINE'LAST loop
  191.                             TPOS := I;
  192.                             exit when INPUT_LINE (I) < ' ';
  193.                             for J in DEL'FIRST .. DEL'LAST loop
  194.                                 if INPUT_LINE (I) = DEL (J) then
  195.                                     raise DELIM;
  196.                                 end if;
  197.                             end loop;
  198.                             for J in DEL_TOKEN'FIRST .. DEL_TOKEN'LAST loop
  199.                                 if INPUT_LINE (I) = DEL_TOKEN (J) then
  200.                                     raise DELIM_TOKEN;
  201.                                 end if;
  202.                             end loop;
  203.                             if APOS <= LARGV (LARGC).ARG_TEXT'LAST then
  204.                                 LARGV (LARGC).ARG_TEXT (APOS) :=
  205.                                   INPUT_LINE (I);
  206.                                 APOS := APOS + 1;
  207.                             end if;
  208.                         end loop;
  209.                     exception
  210.                         when DELIM =>
  211.                             null;
  212.                         when DELIM_TOKEN =>
  213.                             TPOS := TPOS - 1;
  214.                         when DELIM_TOKEN_FIRST =>
  215.                             LARGV (LARGC).ARG_TEXT (APOS) := INPUT_LINE (POS);
  216.                             APOS := APOS + 1;
  217.                             TPOS := POS;
  218.                         when others =>
  219.                             raise;
  220.                     end;
  221.                 end if;
  222.                 LARGV (LARGC).ARG_LAST := APOS - 1;
  223.                 POS := TPOS;
  224.             end if;
  225.             POS := POS + 1;
  226.         end loop;
  227.         ARGC := LARGC;
  228.         ARGV := LARGV;
  229.     end PARSE;
  230.  
  231. end PARSER;
  232. ::::::::::
  233. ptest.ada
  234. ::::::::::
  235. with PARSER,
  236.      TEXT_IO;
  237. procedure PTEST is
  238.     INLINE : STRING (1 .. 80);
  239.     LAST   : NATURAL;
  240.     package NATIO is new TEXT_IO.INTEGER_IO (NATURAL);
  241. --
  242. -- Set up PARSER Package
  243. --
  244.     MY_DELIMITER       : STRING (1 .. 2) := " ,";
  245.     MY_DELIMITER_TOKEN : STRING (1 .. 22) := "!&'()*+-/:;<=>?[\]{|}~";
  246.     package MYPARSE is new PARSER
  247.                (ARGC_LIMIT => 10,
  248.                 DEL        => MY_DELIMITER,
  249.                 DEL_TOKEN  => MY_DELIMITER_TOKEN);
  250.     use MYPARSE;
  251.     ARGC : NATURAL;
  252.     ARGV : ARGS;
  253. --
  254. begin
  255.     loop
  256.         TEXT_IO.PUT ("Line> ");
  257.         TEXT_IO.GET_LINE (INLINE, LAST);
  258.         exit when LAST = 0;
  259.         PARSE (INLINE (1 .. LAST), ARGC, ARGV);
  260.         TEXT_IO.PUT ("Argument count = ");
  261.         NATIO.PUT (ARGC, 2);
  262.         TEXT_IO.NEW_LINE;
  263.         if ARGC > 0 then
  264.             for I in 1 .. ARGC loop
  265.                 NATIO.PUT (I, 2);
  266.                 TEXT_IO.PUT (" - ");
  267.                 NATIO.PUT (ARGV (I).ARG_LAST, 2);
  268.                 TEXT_IO.PUT ("> ");
  269.                 TEXT_IO.PUT (ARGV (I).ARG_TEXT (1 .. ARGV (I).ARG_LAST));
  270.                 TEXT_IO.NEW_LINE;
  271.             end loop;
  272.         end if;
  273.     end loop;
  274. end PTEST;
  275.