home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pccts1.zip / MANUAL.TXT < prev    next >
Text File  |  1993-03-30  |  164KB  |  5,767 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.                         PCCTS Reference Manual
  9.  
  10.  
  11.                              Version 1.00
  12.  
  13.  
  14.                T. J. Parr, H. G. Dietz, and W. E. Cohen
  15.  
  16.                    School of Electrical Engineering
  17.                           Purdue University
  18.                       West Lafayette, IN  47907
  19.                              August 1991
  20.                          pccts@ecn.purdue.edu
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.              This document describes the structure and use of the
  28.      Purdue Compiler-Construction Tool Set (PCCTS), a set of pub-
  29.      lic domain software tools designed to facilitate the  imple-
  30.      mentation of compilers and other translation systems.
  31.  
  32.              Distribution of PCCTS is managed by an email  server
  33.      that   reads  the  Subject:  line  of  each  email  sent  to
  34.      pccts@ecn.purdue.edu.       A     missing     or     undeci-
  35.      pherable  Subject:  line will cause the system to reply with
  36.      email explaining how to use the server.  Full C source  code
  37.      for  PCCTS,  various examples, and on-line documentation are
  38.      available.
  39.  
  40.              PCCTS was developed within the School of  Electrical
  41.      Engineering  at  Purdue University, supported in part by NSF
  42.      award number 8624385A3-CDR.  As  a  public  domain  software
  43.      release,  Purdue University and the authors provide the sys-
  44.      tem strictly on an "as-is" basis, without warranty  or  lia-
  45.      bility.  Despite this, bug reports and fixes are welcome.
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66. 1.  Introduction
  67.  
  68.      This  document  describes  structure  and  use  of   the   Purdue
  69. Compiler-Construction  Tool Set (PCCTS).  In many ways, PCCTS is simi-
  70. lar to a highly integrated version of YACC [Joh78]  and  LEX  [Les75];
  71. where  ANTLR  (ANother  Tool  for Language Recognition) corresponds to
  72. YACC and DLG (DFA-based Lexical  analyzer  Generator)  functions  like
  73. LEX.  However, PCCTS has many additional features which make it easier
  74. to use for a wide range of translation problems.
  75.  
  76.      PCCTS grammars contain specifications for lexical  and  syntactic
  77. analysis,  intermediate-form construction and error reporting.  Future
  78. releases will include an integrated code-generator generator  to  sup-
  79. port  code-generation and other intermediate-form translations.  Rules
  80. may employ Extended BNF  (EBNF)  grammar  constructs  and  may  define
  81. parameters, return values and local variables.  Languages described in
  82. PCCTS are recognized via Strong LL(k)  parsers  constructed  in  pure,
  83. human-readable, C code.
  84.  
  85.      The Version 1.00 Release  PCCTS  package  is  considered  public-
  86. domain and includes the following items:
  87.  
  88.  
  89.  
  90. o    C source code for antlr - parser generator.
  91.  
  92. o    C source code for dlg - DFA-based lexical analyzer generator.
  93.  
  94. o    C source for a symbol table manager with arbitrary scoping  capa-
  95.      bilities.
  96.  
  97. o    Grammars for ISO PASCAL and ANSI C with symbol table management.
  98.  
  99. o    C source for rexpr(char *expr, char *s) which answers  whether  s
  100.      is in the language (regular expression) described by expr.
  101.  
  102. o    On-line documents - PCCTS Version 1.00 Reference Manual
  103.  
  104.  
  105.      PCCTS was developed within the School of  Electrical  Engineering
  106. at Purdue University to aid in constructing various prototype and spe-
  107. cialized compilers.  After using  the  system  for  over  a  year,  we
  108. decided  that  it  was  mature enough to warrant release to a few test
  109. sites.  Hence, in Spring 1990, an experimental version of the  system,
  110. known  as PCCTS B, was made available via anonymous ftp.  Although the
  111. system was only announced via two  short  postings  in  network  news-
  112. groups,  by  January 1991, there were over 450 known user sites world-
  113. wide - and we were hopelessly behind in  responding  to  requests  for
  114. hardcopy manuals.
  115.  
  116.      Now, only a year older but much wiser, we are finally ready for a
  117. full  release  of PCCTS - Version 1.00.  Experience has proven that we
  118. are not able to deal with high-quantity  hardcopy  requests;  instead,
  119. the  basic  documentation  (this document) is being printed by SIGPLAN
  120.  
  121.  
  122.  
  123.                                                                 Page 1
  124.  
  125. PCCTS 1.00
  126.  
  127.  
  128. Notices and all documentation is available on-line.
  129.  
  130.      The rest of this section describes the overall characteristics of
  131. PCCTS  including  its programming interface, translation to C code and
  132. input file format.  Also, an example is presented  to  illustrate  the
  133. development of parsers using PCCTS.
  134.  
  135. 1.1.  PCCTS programming interface
  136.  
  137.      PCCTS accepts language descriptions in the form of a set of gram-
  138. matical  rules and token/lexeme definitions.  Significant emphasis was
  139. placed on making the PCCTS programming interface simple and  flexible.
  140. Much  of  the notation was derived from previous language tools and/or
  141. programming languages in order to bring a sense of familiarity and  to
  142. attenuate  the  learning  curve.  For example, attribute notation ($i)
  143. and grammar syntax were derived mainly from  YACC,  though  they  have
  144. been  augmented  for  use  in  the EBNF environment.  Rules may define
  145. return types, parameter lists and local variables just as  in  a  pro-
  146. gramming  language.   A mechanism for describing abstract-syntax-trees
  147. is also provided.
  148.  
  149.      PCCTS Grammars tend to be smaller and more readable than grammars
  150. written  for  other parser-generators because of the EBNF notation and
  151. because precedence rules are defined  inherently  within  the  grammar
  152. rather  than delineated via pseudo-instructions (e.g. %left, %right in
  153. YACC).  In addition, PCCTS translators (parser plus actions) are  gen-
  154. erally easier to develop because of the extensive programming support.
  155.  
  156.      For example, init-actions allow the user to define  local  stack-
  157. based variables or execute a piece of C initialization code.  Often, a
  158. distinct copy of a variable is required for each invocation of a rule.
  159. This  requires  the  overhead  of  a  software  stack when using other
  160. language tools.  PCCTS constructs  a  function  for  each  rule  which
  161. allows  each  rule  invocation to automatically create its own copy of
  162. the user variables on the hardware stack.
  163.  
  164.      PCCTS parsers are constructed in pure,  human-readable,  C  code.
  165. As  a  result, standard debugging tools can be used to trace and debug
  166. PCCTS parsers.  Breakpoints can be set so that parser execution  stops
  167. before or after certain grammar fragments of interest have been recog-
  168. nized.  PCCTS parsers consist of if, and while statements which can be
  169. easily traced by a human observer.
  170.  
  171.      PCCTS supports intermediate-form (such as expression-trees)  con-
  172. struction  via  a  flexible abstract-syntax-tree (AST) mechanism which
  173. allows trees to be built explicitly or automatically.  The user expli-
  174. citly  creates  trees  via a LISP-like tree constructor or directs the
  175. automatic tree construction facility via  simple  grammar  directives.
  176. AST tree nodes are user-defined and are generally a function of attri-
  177. butes    or    terminals.     A    default     transformation     from
  178. attributes/terminals  ($-variables)  to  AST  nodes  can be specified.
  179. Alternatively, each tree node can be defined  explicitly  via  an  AST
  180. node constructor.
  181.  
  182.  
  183.  
  184.  
  185.                                                                 Page 2
  186.  
  187. PCCTS 1.00
  188.  
  189.  
  190. 1.2.  PCCTS information flow
  191.  
  192.      PCCTS currently consists of  ANTLR  (ANother  Tool  for  Language
  193. Recognition) and DLG (DFA-based lexical analyzer generator) which con-
  194. struct parsers and lexical analyzers respectively.
  195.  
  196.      ANTLR accepts as input a complete language description  including
  197. rules for both lexical and syntactic analysis and produces a C program
  198. that recognizes sentences in that language.  A C file  is  constructed
  199. for  each  grammar  description  file.  Also, three additional files -
  200. err.c, tokens.h and parser.dlg (all of which can be renamed) are  gen-
  201. erated  as  support  files. err.c contains error information and token
  202. class definitions.  tokens.h is a list of #define's  representing  all
  203. of  the  token  names defined or referenced in the grammar description
  204. files as well as function prototypes for rules that have return types.
  205. parser.dlg  is  a  specification  of  the  lexical  analyzer generator
  206. derived from the user's language description and is translated to C by
  207. DLG.
  208.  
  209.      DLG creates an automaton  that  breaks  up  the  input  character
  210. stream  into  tokens used by the ANTLR-generated parser and it creates
  211. mode.h which is a list of  #define's  corresponding  to  the  separate
  212. automatons defined by your grammar.
  213.  
  214.      The following is a graphical representation  of  the  information
  215. flow during translation from parser description to executable parser.
  216.  
  217.  
  218.                            [Figure omitted]
  219.  
  220.  
  221.  
  222.  
  223.  
  224. _______________________________________________________________________
  225. _______________________________________________________________________|
  226. |f1 ... fn     ||Input ANTLR grammar description files                 |
  227. |______________||______________________________________________________|
  228. |______________||______________________________________________________|
  229. |tokens.h      ||List of token names found in f1 ... fn                |
  230. |______________||______________________________________________________|
  231. |______________||______________________________________________________|
  232. |parser.dlg    ||Scanner description prepared for DLG                  |
  233. |______________||______________________________________________________|
  234. |______________||______________________________________________________|
  235. |mode.h        ||Definitions for lexical modes (#lexclass's)           |
  236. |______________||______________________________________________________|
  237. |______________||______________________________________________________|
  238.  
  239.  
  240.  
  241. 1.3.  PCCTS file(s) format
  242.  
  243.      PCCTS descriptions adhere to a fairly flexible format and can  be
  244.  
  245.  
  246.  
  247.                                                                 Page 3
  248.  
  249. PCCTS 1.00
  250.  
  251.  
  252. spread out over many files.  The actual grammar for PCCTS input can be
  253. defined in itself as:
  254.  
  255.  
  256.  
  257.  
  258. grammar         :       { "#header" Action }
  259.                                 ( Action | tokenDef | eclassDef )*
  260.                                 ( rule | tokenDef | eclassDef )+
  261.                                 ( Action | tokenDef | eclassDef )*
  262.                                 Eof
  263.                         ;
  264.  
  265.  
  266.  
  267. where Action is a user action (C code), tokenDef is a  #token  defini-
  268. tion  and eclassDef is an #errclass definition.  Lexical actions found
  269. in a language description are passed on to the parser.dlg file.  The (
  270. )*  and  (  )+ EBNF operators indicate 0 or more and 1 or more respec-
  271. tively. { } implies that the items within are optional.  Rule  grammar
  272. indicates  that  a  PCCTS  file has a #header action first (if at all)
  273. followed by actions, token definitions  and  error  class  definitions
  274. with  the  except that actions may not appear between rules.  Also, at
  275. least one rule must be defined.  There is no start  symbol  specifica-
  276. tion since any rule can be invoked first.
  277.  
  278.      The minimum required user C code is a main program that  initial-
  279. izes the PCCTS-generated parser and calls the starting rule.  The lex-
  280. ical analyzer is  derived  automatically  (from  the  user's  language
  281. description)  by  ANTLR  and a user routine is not necessary to supply
  282. tokens to the parser.  The main program does not need to be located in
  283. a PCCTS grammar file.
  284.  
  285.      ANTLR descriptions may be broken up into  many  different  files,
  286. but  the  sequence mentioned above in grammar must be maintained.  For
  287. example, if file f1.g contained
  288.  
  289.  
  290.  
  291.  
  292. #header <<#include "int.h">>
  293.  
  294. << main() { ANTLR(start(), stdin); } >>
  295.  
  296.  
  297.  
  298. and file f2.g contained
  299.  
  300.  
  301.  
  302.  
  303. start   :   "begin" VAR "=" NUM ";" "end" "." "@" ;
  304.  
  305.  
  306.  
  307.  
  308.  
  309.                                                                 Page 4
  310.  
  311. PCCTS 1.00
  312.  
  313.  
  314. and file f3.g contained
  315.  
  316.  
  317.  
  318.  
  319. #token VAR "[a-z]+"
  320. #token NUM "[0-9]+"
  321.  
  322.  
  323.  
  324. the correct ANTLR invocation would be
  325.  
  326.  
  327.  
  328.  
  329. antlr f1.g f2.g f3.g
  330.  
  331.  
  332.  
  333. Note that the order of files f2.g and f3.g could be switched because a
  334. rule  is  either a #token or an actual rule definition.  In this case,
  335. to comply with ANTLR's grammar, the only restriction is that file f1.g
  336. must be mentioned first on the command line.
  337.  
  338.      Other files may be included into the parser  files  generated  by
  339. ANTLR via actions containing a #include directive.  For example,
  340.  
  341.  
  342.  
  343.  
  344. <<#include "support_code.h">>
  345.  
  346.  
  347.  
  348. If a file must be included in all parser files generated by ANTLR, the
  349. #include  directive  must  be  placed in the #header action.  In other
  350. words,
  351.  
  352.  
  353.  
  354.  
  355. #header <<#include "necessary_type_defs_for_all_files.h">>
  356.  
  357.  
  358.  
  359. Note that #include's can be used to define any ANTLR  object  (Attrib,
  360. AST, etc...) by placing it in the #header action.
  361.  
  362. 1.4.  Makefile template
  363.  
  364.      The template presented in this section can be used  to  construct
  365. makefiles  for single-file grammars.  The order of execution will fol-
  366. low that illustrated in section 1.2.
  367.  
  368.  
  369.  
  370.  
  371.                                                                 Page 5
  372.  
  373. PCCTS 1.00
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380. #
  381. # Makefile for a single-file grammar
  382. #
  383. ANTLR_H= path to antlr.h, dlgdef.h, dlgauto.h, standard attribute defs
  384. CFLAGS= -I$(ANTLR_H) -DLL_K = $(K)
  385. AFLAGS=
  386. GRM=user_grammar_file_name
  387. SRC=scan.c $(GRM).c err.c
  388. OBJ=scan.o $(GRM).o err.o
  389. K=number_of_tokens_of_lookahead
  390.  
  391. # build an executable with same name as grammar file minus .g
  392. proj: $(OBJ) $(SRC)
  393.         cc -o $(GRM) $(OBJ)
  394.  
  395. # how to build parser files from grammar files
  396. $(GRM).c parser.dlg : $(GRM).g
  397.         antlr $(AFLAGS) $(GRM).g
  398.  
  399. # how to build scanner from lex description built by ANTLR
  400. scan.c : parser.dlg
  401.         dlg -C2 parser.dlg scan.c
  402.  
  403.  
  404.  
  405. 1.5.  PCCTS component command-line options
  406.  
  407.      The PCCTS system is composed of ANTLR and DLG both of which  have
  408. command-line options.  Since each component is executed independently,
  409. each may be invoked with different options  which  are  summarized  in
  410. this section.
  411.  
  412.      ANTLR accepts the following command-line options
  413.  
  414. -cr  Generate cross reference of all rules.  The default is FALSE.
  415.  
  416. -e1  Only the first 3 tokens of any ambiguity set are  displayed  upon
  417.      warning/error.  i.e. { A B C ...}.
  418.  
  419. -e2  Every token in an ambiguity set is displayed upon warning/error.
  420.  
  421. -e3  Error levels 1 and 2 (-e1, -e2) are sometimes misleading for  the
  422.      sake  of  brevity.   For instance, when a block is ambiguous upon
  423.      the sequences
  424.  
  425.  
  426.  
  427.  
  428.      A B
  429.      C D
  430.  
  431.  
  432.  
  433.                                                                 Page 6
  434.  
  435. PCCTS 1.00
  436.  
  437.  
  438.      only { A C }, { B D } is displayed when in fact A D and  C B  are
  439.      not  ambiguous.   The -e3 option makes ANTLR generate permutation
  440.      trees in LISP-like notation
  441.  
  442.  
  443.  
  444.  
  445.      (root child1 child2 ... childn)
  446.  
  447.  
  448.  
  449.      The following grammar illustrates the difference
  450.  
  451.  
  452.  
  453.  
  454.      a   :   (A B|C D|A D|C B)
  455.          |   (A D|C B)
  456.          ;
  457.  
  458.  
  459.  
  460.      ANTLR with error level 1 or 2 reports
  461.  
  462.  
  463.  
  464.  
  465.      Antlr parser generator   Version 1.00   1989, 1990, 1991
  466.      "t.g", line 1: warning: alts 1 and 2 rule ambiguous upon { A C }, { B D }
  467.  
  468.  
  469.  
  470.      ANTLR with error level 3 reports
  471.  
  472.  
  473.  
  474.  
  475.      Antlr parser generator   Version 1.00   1989, 1990, 1991
  476.      "t.g", line 4: warning: alts 1 and 2 rule ambiguous upon ( C B ) ( A D )
  477.  
  478.  
  479.  
  480.      which indicates that rule  a  is  only  ambiguous  upon  the  two
  481.      sequences C B and A D.
  482.  
  483.  
  484. -fe fname
  485.      Rename the file where error information, token  sets,  and  zzto-
  486.      kens[] are placed.  Default is err.c.
  487.  
  488. -fl fname
  489.      Rename the file  where  ANTLR  places  the  lexical  description.
  490.      Default is parser.dlg.
  491.  
  492.  
  493.  
  494.  
  495.                                                                 Page 7
  496.  
  497. PCCTS 1.00
  498.  
  499.  
  500. -ft fname
  501.      Rename the file where ANTLR places the #define's for labeled con-
  502.      stants and the function prototypes.  Default is tokens.h.
  503.  
  504. -ga  Generate ANSI prototypes for functions  constructed  from  rules.
  505.      Default is not to generate ANSI-style prototypes.
  506.  
  507. -gt  Generate code for Abstract-Syntax-Trees.  Default is not to  gen-
  508.      erate trees.
  509.  
  510. -gc  Do  not  generate  output  parser  code  or  lexical  description
  511.      (implies  -gx).   This  option can be used to check a grammar for
  512.      ambiguities.  Default is to generate parsers.
  513.  
  514. -ge  Generate an error class for each non-terminal of the form
  515.  
  516.  
  517.  
  518.  
  519.      #errclass Rule { rule }
  520.  
  521.  
  522.  
  523.      Default is not to generate the classes.
  524.  
  525.  
  526. -gs  When a token in the  current  look-ahead  needs  to  be  compared
  527.      against  two or more tokens, code for set membership is generated
  528.      rather than a set  of  integer  comparisons.   This  renders  the
  529.      parsers  more  efficient,  but  much more difficult to read for a
  530.      human.  When debugging  an  ANTLR  parser  with  a  source  level
  531.      debugger,  this command-line option should be used to create more
  532.      readable parsers.  The default is to generate sets for any  token
  533.      expression list with two or more members.
  534.  
  535. -gd  Generate debugging code; trace rule  invocation.   This  command-
  536.      line  option  forces  ANTLR to generate code that calls zzTRACE()
  537.      with the rule name in which it appears as an argument.  zzTRACE()
  538.      can  be  a  macro  or a function.  The default is not to generate
  539.      debugging code.
  540.  
  541. -gl  Generate line information in PCCTS-generated parser that  associ-
  542.      ates  a  line  in  the  user's grammar with a line in the C code.
  543.      This is useful when the C compiler reports an  error  in  a  user
  544.      action.   It will report an error in the grammar file rather than
  545.      an error in the C file.  This dumps line information like  the  C
  546.      preprocessor.
  547.  
  548. -gx  Do not generate a lexical description (dlg-related  files).  This
  549.      is  useful if you are positive nothing has changed in the lexical
  550.      portion of your language description.  For example, if you simply
  551.      change  an action in one of your rules, nothing has changed lexi-
  552.      cally and you need not run DLG to recreate the lexical  analyzer.
  553.      The default is to generate a description.
  554.  
  555.  
  556.  
  557.                                                                 Page 8
  558.  
  559. PCCTS 1.00
  560.  
  561.  
  562. -k n
  563.      Set k, the number of look-ahead tokens, to n.  Default is 1.
  564.  
  565. -p   Print out the grammar to stdout without actions.  This option  is
  566.      useful   for   documentation   purposes   or   to   simply   make
  567.      viewing/understanding your grammar easier.  The default is not to
  568.      generate a grammar printout.
  569.  
  570. -pa  This option is identical to the -p option accept that the grammar
  571.      is  annotated with the results of grammar analysis.  For example,
  572.      the set of all tokens that can be matched at k  tokens  into  the
  573.      future  are  displayed  after  each point in your grammar where a
  574.      decision has to be made.  ANTLR  prints  out  only  the  sets  of
  575.      tokens  that would be needed to construct a parser.  Rule a below
  576.      illustrates the annotations.
  577.  
  578.  
  579.  
  580.  
  581.      #header <<;>>
  582.      a   :   (A B | A D)
  583.          |   Q
  584.          ;
  585.  
  586.  
  587.  
  588.      Executing ANTLR with
  589.  
  590.  
  591.  
  592.  
  593.      antlr -k 2 -pa t.g
  594.  
  595.  
  596.  
  597.      yields (cleaned up slightly)
  598.  
  599.  
  600.  
  601.  
  602.      Antlr parser generator   Version 1.00   1989, 1990, 1991
  603.  
  604.      a   :   ( A B       /* [1] { A }, { B } */
  605.              | A D       /* [2] { A }, { D } */
  606.              )           /* [1] { A } */
  607.              | Q         /* [2] { Q } */
  608.          ;
  609.  
  610.  
  611.  
  612.      The first alternative of rule a has a subrule with  two  alterna-
  613.      tives which requires a parsing decision.  Since both alternatives
  614.      start with an A, another token of look-ahead must be examined  to
  615.      determine  which alternative to choose.  In this case, the second
  616.  
  617.  
  618.  
  619.                                                                 Page 9
  620.  
  621. PCCTS 1.00
  622.  
  623.  
  624.      token in each alternative allows us to  choose.   Therefore,  two
  625.      sets  of  tokens  (singleton  sets here) are printed out for each
  626.      alternative in the subrule.  The alternatives of rule  a  can  be
  627.      matched  with  the  knowledge of only the first token and so only
  628.      one set is printed.  The default is not  to  generate  a  grammar
  629.      printout with annotations.
  630.  
  631.      DLG has the following command-line options.
  632.  
  633. -Cn
  634.      Specify  level  of  character  class  compression.   0  means  no
  635.      compression,  1  removes unused characters from DFA states, and 2
  636.      specifies that DLG is  to  combine  characters  into  equivalence
  637.      classes.   It  is suggested that -C2 be used since it will result
  638.      in much smaller output file and does not require much  additional
  639.      processing time.
  640.  
  641. -ga  Produce ANSI C compatible code.
  642.  
  643. -m filename
  644.      Uses filename rather than mode.h for the lexical mode  definition
  645.      file.
  646.  
  647. -i   Attempts to build a lexical  scanner  for  interactive  programs.
  648.      The  non-interactive  scanner always looks one character past the
  649.      end of a token.  This look-ahead is avoided whenever possible  in
  650.      the interactive version so that the pattern is recognized without
  651.      any additional characters being read.  Look-ahead is always  used
  652.      when necessary to correctly match input tokens.
  653.  
  654.  
  655. 1.6.  Introductory example
  656.  
  657.      As a simple concrete example of the PCCTS  system,  consider  the
  658. following translator which accepts a date in the typical American for-
  659. mat of mm/dd/yy and prints to stdout the same date, but in  the  Euro-
  660. pean format of dd/mm/yy.
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.                                                                Page 10
  682.  
  683. PCCTS 1.00
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690. #header <<#include "int.h">>
  691.  
  692. <<
  693. main()
  694. {
  695.     ANTLR(date(), stdin);
  696. }
  697. >>
  698.  
  699. #token "[\t\ \n]"     << zzskip(); >>          /* Ignore White */
  700. #token Digits2 "[0-9][0-9]"                    /* Define mm, dd or yy */
  701.  
  702. date    :   Digits2 "/" Digits2 "/" Digits2 "@"
  703.             <<printf("%02d/%02d/%02d\n", $3, $1, $5);>>
  704.                 ;
  705.  
  706.  
  707.  
  708. This example is complete in the sense that PCCTS can  generate  all  C
  709. files necessary to lexically and syntactically analyze a date and con-
  710. vert it to the European format.  An executable can be obtained by per-
  711. forming the following sequence of commands (assuming the above grammar
  712. is in file date.g and antlr.h, the standard ANTLR header,  is  in  the
  713. current directory).
  714.  
  715.  
  716.  
  717.  
  718. antlr date.g
  719. dlg parser.dlg scan.c
  720. cc date.c scan.c err.c
  721.  
  722.  
  723.  
  724. Executing the file a.out (on UNIX [Trademark AT&T] systems) will allow
  725. the  user  to type in a date and have the European version printed out
  726. (after end of file is typed).
  727.  
  728.      Rule date is defined to be a sequence of two digits followed by a
  729. / followed by a sequence of 2 digits, and so on, terminated by the end
  730. of the input file (represented by "@").  Note that  rule  names  begin
  731. with a lower-case letter.  The action
  732.  
  733.  
  734.  
  735.  
  736.             <<printf("%02d/%02d/%02d\n", $3, $1, $5);>>
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.                                                                Page 11
  744.  
  745. PCCTS 1.00
  746.  
  747.  
  748. contains C code that is executed after all elements in rule date  have
  749. been  recognized.   C  code  for  the action is delimited by << and >>
  750. (European quotes).  Because the >> delimiter otherwise would  be  con-
  751. fused  with  C's  right-shift operator within the C code of an action,
  752. right-shift is written as \>\>.  Similarly, the  $  and  #  characters
  753. normally  have  special  meanings within the C code of a PCCTS action;
  754. hence, the literal character $ in the C code would be  written  as  \$
  755. and # would be written as \#.
  756.  
  757.      Although the placement of an action within a  grammar  determines
  758. when  that  action  will  be applied, it must also be possible for the
  759. action to be a function of the text which has  been  recognized.   For
  760. example,  PCCTS  automatically  makes $1 in rule date have a value, or
  761. attribute, which is a function  of  the  text  matched  by  the  first
  762. occurrence  of Digits2.  In general, the attribute associated with the
  763. ith item in a rule is called $i.  Both the type of the attributes  and
  764. the mapping from text matched into its attribute value is specified by
  765. the user.  The directive
  766.  
  767.  
  768.  
  769.  
  770. #header <<#include "int.h">>
  771.  
  772.  
  773.  
  774. includes code that makes the values of "$ variables" be of the C  type
  775. int  with values defined by applying the C function atoi() to the text
  776. matched.
  777.  
  778.      Each item in the rules refers either to the  text  matched  by  a
  779. simple  pattern  (a  regular expression) or to the collection of items
  780. matched by a rule (represented by the rule's name).   Simple  patterns
  781. can  be  stated  directly, such as "/" in the example, or can be given
  782. names using the #token directive.  The token definitions
  783.  
  784.  
  785.  
  786.  
  787. #token "[\t\ \n]"     << zzskip(); >>          /* Ignore White */
  788. #token Digits2 "[0-9][0-9]"                    /* Define mm, dd or yy */
  789.  
  790.  
  791.  
  792. cause tab (\t), space (\ ), and newline (\n)  characters  between  the
  793. other  tokens  to  be  ignored, and allow use of the name Digits2 as a
  794. shorthand for "[0-9][0-9]".
  795.  
  796.      Since the above is meant to be a stand-alone complete example and
  797. PCCTS  does  not  generate  a C main function, the user must provide a
  798. main.  The main also specifies which rule is to be used  to  recognize
  799. the input and where that input will come from.  The code
  800.  
  801.  
  802.  
  803.  
  804.  
  805.                                                                Page 12
  806.  
  807. PCCTS 1.00
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.     ANTLR(date(), stdin);
  815.  
  816.  
  817.  
  818. specifies that the date rule will be used  to  recognize  input  taken
  819. from stdin (the standard input stream).
  820.  
  821.      Notice that, although there is no specification of how  incorrect
  822. input should be handled by the generated program, PCCTS will automati-
  823. cally generate appropriate error messages and attempt to recover  from
  824. the errors.
  825.  
  826.      The above example should give the reader a "feel" for  how  PCCTS
  827. can  be  used, however, the system supports much more than the example
  828. uses.  This document is organized into  six  major  sections:  lexical
  829. analysis,  syntactic  analysis,  attribute  handling, error detection,
  830. miscellaneous items and PCCTS history.
  831.  
  832. 2.  Lexical analysis and token definition
  833.  
  834.      The task of language recognition is conveniently broken down into
  835. two phases - lexical and syntactic analysis.  Each phase is considered
  836. a separate operation  and,  therefore,  most  language  tools  require
  837. separate  specifications.   For  example,  Coco-2 [DoP90] requires the
  838. user to create separate, but consistent, specifications  of  character
  839. sets,  keywords  and  tokens  (and  even non-terminals).  In contrast,
  840. PCCTS derives all this information from a  single  description.   This
  841. both ensures that the information is consistent and makes it easier to
  842. view a PCCTS language specification as a whole.
  843.  
  844.      This section of the manual describes general lexical issues asso-
  845. ciated  with  PCCTS'  integrated  description including lexical action
  846. definitions, regular expression specification, and resolution of ambi-
  847. guities.   Also,  more specialized issues such as multiple automatons,
  848. interactive scanners, token positional information and input character
  849. supply are presented.
  850.  
  851. 2.1.  Token Labeling and token actions
  852.  
  853.      Tokens are defined either explicitly with #token or implicitly by
  854. using  them as rule elements.  Implicitly defined tokens can be either
  855. regular expressions (non-labeled tokens)  or  token  names  (labeled).
  856. Token  names  begin  with  an  upper-case  letter  (rules begin with a
  857. lower-case letter).  More than one  occurrence  of  the  same  regular
  858. expression  in a grammar description produces a single regular expres-
  859. sion in parser.dlg and is assigned one token number.  Quoted and  non-
  860. quoted  tokens  that refer to the same lexical object (expression) may
  861. be used interchangeably.  Token names that  are  referenced,  but  not
  862. attached  to  a  regular  expression are assigned a number and given a
  863. #define definition in tokens.h.  It is  not  necessary  to  label  any
  864.  
  865.  
  866.  
  867.                                                                Page 13
  868.  
  869. PCCTS 1.00
  870.  
  871.  
  872. tokens  in  PCCTS.   However,  all  tokens that you wish to explicitly
  873. refer to in an action, must be declared  with  a  #token  instruction.
  874. From  PCCTS's  point of view, it merely needs to know that a word is a
  875. token (as opposed to a non-terminal).  Its value is irrelevant at  the
  876. symbolic level of PCCTS's meta-language.
  877.  
  878.      The user may introduce tokens, lexical/token actions,  and  token
  879. labels via the #token instruction.  Specifically,
  880.  
  881.  
  882.  
  883. o    Simply declare a token for use in a user action:
  884.  
  885.  
  886.  
  887. #token VAR
  888.  
  889.  
  890.  
  891. o    Associate a token with a regular expression and,  optionally,  an
  892.      action:
  893.  
  894.  
  895.  
  896. #token VAR "[a-zA-Z][a-zA-Z0-9]*"
  897. #token Eof "@" << printf("Eof Found\n"); >>
  898.  
  899.  
  900.  
  901. o    Specify what must occur upon a regular expression:
  902.  
  903.  
  904.  
  905. #token "[0-9]+"  << printf("Found int %s\n", zzlextext); >>
  906.  
  907.  
  908.  
  909.      Token  actions  may  employ  two  functions,   zzreplchar()   and
  910. zzreplstr(), to replace the text for the regular expression matched on
  911. the input stream.  For example, if \n is found in a string for  C,  it
  912. needs  to  be converted to the actual newline character.  Strings in C
  913. can be handled in the following manner.
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.                                                                Page 14
  930.  
  931. PCCTS 1.00
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938. /* START lexclass is in effect */
  939. #token "\""                      <<zzmode(STRINGS); zzmore();>>
  940.  
  941. #lexclass STRINGS   /* define a new automaton */
  942. #token STRING "\""  <<zzmode(START);>>
  943. #token "\\\""       <<zzmore();>>
  944. #token "\\n"        <<zzreplchar('\n'); zzmore();>>
  945. #token "\\r"        <<zzreplchar('\r'); zzmore();>>
  946. #token "\\t"        <<zzreplchar('\t'); zzmore();>>
  947. #token "\\[1-9][0-9]*"
  948.                     <<zzreplchar((char)strtol(zzbegexpr,NULL,10)); zzmore();>>
  949. #token "\\0[0-7]*"  <<zzreplchar((char)strtol(zzbegexpr,NULL,8)); zzmore();>>
  950. #token "\\0x[0-9a-fA-F]+"
  951.                                         <<zzreplchar((char)strtol(zzbegexpr,NULL,16)); zzmore();>>
  952. #token "\\~[\n\r]"  <<zzmore();>>
  953. #token "[\n\r]"     <<zzline++; zzmore(); /* print warning about \n in str */>>
  954. #token "~[\"\n\r\\]+" <<zzmore();>>
  955.  
  956. #lexclass START
  957.  
  958.  
  959.  
  960. Note the use of zzbegexpr which points to the beginning  of  the  text
  961. matched for the currently recognized regular expression.  zzendexpr is
  962. also available and points to the end  of  the  expression.   The  text
  963. always  has  a  '\0'  on the end and zzendexpr points to the character
  964. just before.
  965.  
  966.      There is a big difference between a token  action  and  a  normal
  967. action  found  outside  of  the  #token  instructions.   An action not
  968. included as part of one of the lexical commands is considered  a  syn-
  969. tactic  action and is placed in the C parser file associated with that
  970. grammar file.
  971.  
  972.      If a grammar action follows a #token definition with  no  associ-
  973. ated  lexical  action,  the  #token  instruction  will assume that the
  974. action is really meant as a lexical action.  This is sort of analogous
  975. to the dangling-else-clause dilemma.  Example:
  976.  
  977.  
  978.  
  979.  
  980. #token VAR "[a-zA-Z][a-zA-Z0-9]*"
  981.  
  982. <<
  983.     /*
  984.      * This will be associated with the #token even though it is
  985.      * probably a grammar action not a lexical action
  986.      */
  987. >>
  988.  
  989.  
  990.  
  991.                                                                Page 15
  992.  
  993. PCCTS 1.00
  994.  
  995.  
  996.      This ambiguity can be solved by appending a null  action  to  the
  997. #token:
  998.  
  999.  
  1000.  
  1001. #token VAR "[a-zA-Z][a-zA-Z0-9]*" << ; >>
  1002.  
  1003.  
  1004.  
  1005.  
  1006. 2.2.  Lexical actions via #lexaction
  1007.  
  1008.      Often, it is convenient to have a section of user C  code  placed
  1009. in  the  lexical  analyzer  constructed  automatically by DLG (PCCTS's
  1010. DFA-based lexical analyzer generator).  Normally, actions not  associ-
  1011. ated  with  a #token pseudo-op or embedded within a rule are placed in
  1012. the parser generated by ANTLR.  However, preceding an action appearing
  1013. outside  of any rule, with the #lexaction pseudo-op directs the C code
  1014. to the lexical analyzer.  For example,
  1015.  
  1016.  
  1017.  
  1018.  
  1019. << /* a normal action outside of the rules */ >>
  1020.  
  1021. #lexaction
  1022.     << /* this action is inserted into the lexical
  1023.         * analyzer created by DLG
  1024.         */
  1025.     >>
  1026.  
  1027.  
  1028.  
  1029. All #lexaction actions are collected and placed as a group into the  C
  1030. file  where the lexer resides.  Typically, this code consists of func-
  1031. tions or variable declarations needed by #token actions.
  1032.  
  1033. 2.3.  Multiple lexical classes
  1034.  
  1035.      ANTLR parsers  employ  DFA's  (Deterministic  Finite  Automatons)
  1036. created  by  DLG  to match tokens found on the character input stream.
  1037. More than one automaton (lexical class) may be defined in PCCTS.  Mul-
  1038. tiple  scanners  are useful in two ways.  First, more than one grammar
  1039. can be described within the same PCCTS input file(s).  Second,  multi-
  1040. ple automatons can be used to recognize tokens that seriously conflict
  1041. with other regular expressions within the same lexical analyzer  (e.g.
  1042. comments, quoted-strings, etc...).
  1043.  
  1044.      Actions attached to regular expressions (which are executed  when
  1045. that  expression has been matched on the input stream) may switch from
  1046. one lexical analyzer to another.  Each  analyzer  (lex  class)  has  a
  1047. label  which  is  used  to enter that automaton.  A predefined lexical
  1048. class called START is in  effect  from  the  beginning  of  the  PCCTS
  1049. description  until the user issues a #lexclass directive or the end of
  1050.  
  1051.  
  1052.  
  1053.                                                                Page 16
  1054.  
  1055. PCCTS 1.00
  1056.  
  1057.  
  1058. the description is found.
  1059.  
  1060.      When more than one lexical class is defined, it  is  possible  to
  1061. have  the  same regular expression and the same token label defined in
  1062. multiple automatons.  Regular expressions found in more than one auto-
  1063. maton  are  given different token numbers, but token labels are unique
  1064. across lexical class boundaries.  For instance,
  1065.  
  1066.  
  1067.  
  1068.  
  1069. #lexclass A
  1070. #token LABEL "expr1"
  1071.  
  1072. #lexclass B
  1073. #token LABEL "expr2"
  1074.  
  1075.  
  1076.  
  1077. In this case, LABEL is the same token number (#define in C)  for  both
  1078. "expr1"  and  "expr2".   A  reference  to  LABEL  within a rule can be
  1079. matched by two different regular expressions depending on which  auto-
  1080. maton is currently active.
  1081.  
  1082.      Hence, the #lexclass directive marks the start of a  new  set  of
  1083. lexical  definitions.   Rules  found  after  a  #lexclass can only use
  1084. tokens defined within that class - i.e. all tokens defined  until  the
  1085. next  #lexclass  or  the end of the PCCTS description, whichever comes
  1086. first.  Any regular expressions used  explicity  in  these  rules  are
  1087. placed  into  the current lexical class.  Since the default automaton,
  1088. START, is active upon parser startup, the start rule must  be  defined
  1089. within  the boundaries of the START automaton.  Typically, a multiple-
  1090. automaton PCCTS grammar will begin with
  1091.  
  1092.  
  1093.  
  1094.  
  1095. #lexclass START
  1096.  
  1097.  
  1098.  
  1099. immediately before the rule definitions to insure that the  rules  use
  1100. the token definitions in the "main" automaton.
  1101.  
  1102.      Tokens are given sequential  token  numbers  across  all  lexical
  1103. classes  so  that  no  conflicts  arise.  This also allows the user to
  1104. reference zztokens[token_num] (which  is  a  string  representing  the
  1105. label  or  regular  expression  defined  in the grammar) regardless of
  1106. which class token_num is defined in.
  1107.  
  1108. 2.3.1.  Multiple grammars, multiple lexical analyzers
  1109.  
  1110.      Different  grammars  will  generally  require  separate   lexical
  1111. analyzers  to  break  up  the input stream into tokens.  What may be a
  1112.  
  1113.  
  1114.  
  1115.                                                                Page 17
  1116.  
  1117. PCCTS 1.00
  1118.  
  1119.  
  1120. keyword in one language, may be a simple  variable  in  another.   The
  1121. #lexclass PCCTS meta-op is used to group tokens into different lexical
  1122. analyzers.  For example, to separate two  grammars  into  two  lexical
  1123. classes,
  1124.  
  1125.  
  1126.  
  1127.  
  1128. #lexclass GRAMMAR1
  1129.  
  1130. rules for grammar1
  1131.  
  1132. #lexclass GRAMMAR2
  1133.  
  1134. rules for grammar2
  1135.  
  1136.  
  1137.  
  1138. All tokens found beyond the #lexclass meta-op will  be  considered  of
  1139. that class.
  1140.  
  1141. 2.3.2.  Single grammar, multiple lexical analyzers
  1142.  
  1143.      Again the #lexclass meta-op is used to indicate the beginning  of
  1144. a  new lexical analyzer.  For instance to define C-style comments, the
  1145. following will suffice:
  1146.  
  1147.  
  1148.  
  1149.  
  1150. /* lexclass START is in effect by default */
  1151. /* switch to COMMENT automaton */
  1152. #token "/\*"         <<zzmode(COMMENT); zzskip();>>
  1153.  ...
  1154. #lexclass COMMENT
  1155. #token "\*/"         <<zzmode(START); zzskip();>>  /* switch back */
  1156. #token "~[\*]*"      <<zzskip();>>  /* ignore all stuff inside */
  1157. #token "\*~[/]"       <<zzskip();>>
  1158.  ...
  1159.  
  1160.  
  1161.  
  1162. 2.4.  Handling end of input
  1163.  
  1164.      There is only one  automatically  defined  regular  expression  -
  1165. end-of-file  which  is  represented  by  the regular expression @.  An
  1166. implicit
  1167.  
  1168.  
  1169.  
  1170.  
  1171. #token "@"
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.                                                                Page 18
  1178.  
  1179. PCCTS 1.00
  1180.  
  1181.  
  1182. is executed at the start of each lexical class (#lexclass).   A  label
  1183. may be attached via the following in the user's grammar:
  1184.  
  1185.  
  1186.  
  1187.  
  1188. #token Eof "@"
  1189.  
  1190.  
  1191.  
  1192. A user could then refer to end-of-file as the #define constant Eof.
  1193.  
  1194. 2.5.  Token order and lexical ambiguities
  1195.  
  1196.      The order in which regular expressions are found in  the  grammar
  1197. description  file(s) is significant.  When the input stream contains a
  1198. sequence of characters that match more than  one  regular  expression,
  1199. (e.g. one regular expression is a subset of another) DLG is confronted
  1200. with a dilemma.  DLG does not know which regular expression to  match,
  1201. hence,  it does not know which action should be performed.  To resolve
  1202. the ambiguity, DLG  assumes  that  the  regular  expression  which  is
  1203. defined  earliest  in  the DLG input should take precedence over later
  1204. definitions.  Therefore, tokens that are special cases of other  regu-
  1205. lar  expressions  should  be  defined  before the more general regular
  1206. expressions.
  1207.  
  1208.      ANTLR automatically constructs the input to DLG by copying  regu-
  1209. lar  expressions  into  the  file  parser.dlg.   These definitions are
  1210. copied in the order in which they are encountered among the rules  and
  1211. #token  definitions.   For  example,  a keyword is a special case of a
  1212. variable and thus needs to occur before the variable definition.
  1213.  
  1214.  
  1215.  
  1216.  
  1217. #token KBegin "begin"
  1218.         .
  1219.         .
  1220.         .
  1221. #token VAR "[a-zA-Z][a-zA-Z0-9]*"
  1222.  
  1223.  
  1224.  
  1225.  
  1226. 2.6.  Quoted tokens
  1227.  
  1228.      The regular expressions in a PCCTS grammar appear  between  quote
  1229. marks and are literally copied into the input for DLG.  Therefore, the
  1230. regular expressions must use the notation accepted by DLG  -  a  rela-
  1231. tively standard notation using a few meta-symbols.
  1232.  
  1233. "a|b"Matches either the pattern a or the pattern b.
  1234.  
  1235. "(a)"Matches the pattern a.  Pattern a is kept as an indivisible unit.
  1236.  
  1237.  
  1238.  
  1239.                                                                Page 19
  1240.  
  1241. PCCTS 1.00
  1242.  
  1243.  
  1244. "{a}"Matches a or nothing, i.e., the same as "(a|)".
  1245.  
  1246. "[a]"Matches any single character in character list a.  e.g.   "[abc]"
  1247.      matches either an a, b or c and is equivalent to "(a|b|c)".
  1248.  
  1249. "[a-b]"
  1250.      Matches any of  the  single  characters  whose  ASCII  codes  are
  1251.      between a and b inclusively, i.e., the same as "(a|...  |b)".
  1252.  
  1253. "~[a]"
  1254.      Matches any single character except for those in  character  list
  1255.      a.
  1256.  
  1257. "~[]"
  1258.      Matches any single character; literally "not nothing."
  1259.  
  1260. "a*" Matches zero or more occurrences of pattern a.
  1261.  
  1262. "a+" Matches one or more occurrences of pattern a, i.e., the  same  as
  1263.      "aa*".
  1264.  
  1265. "\a" Matches the single character a - even if a by itself would have a
  1266.      different  meaning, e.g., "\+" would match the + character.  This
  1267.      is consistent with the use of \ in the C language.
  1268.  
  1269. In addition, the symbols %%, <<, and >> are used  to  specify  control
  1270. for  DLG;  hence, these patterns must be escaped if they are to appear
  1271. as literals within a regular expression.  For  example,  <<  would  be
  1272. \<\<.  The following characters are also special.
  1273.  
  1274. @    Matches end-of-file.
  1275.  
  1276. \t   Tab character
  1277.  
  1278. \n   Newline character
  1279.  
  1280. \r   Carriage return character
  1281.  
  1282. \b   Backspace character
  1283.  
  1284. \0nnnMatches character that has octal value nnn
  1285.  
  1286. \0xnnMatches character that has hexadecimal value nnn
  1287.  
  1288. \mnn
  1289.      Matches character with decimal value mnn, 1<m<9
  1290.  
  1291. \c   Character escape
  1292.  
  1293. White space characters (tab and space) are ignored within  the  quota-
  1294. tion marks.  To specify the actual space character use "\ ".
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.                                                                Page 20
  1302.  
  1303. PCCTS 1.00
  1304.  
  1305.  
  1306. 2.7.  Interactive lexical analyzers
  1307.  
  1308.      Normally, the scanners produced by DLG always have one  character
  1309. of  look-ahead  available.  This look-ahead causes the scanner to look
  1310. one character past the end of the current pattern  and  wait  for  the
  1311. next character if it is not yet available.
  1312.  
  1313.      This can cause unexpected behavior from interactive programs such
  1314. as command line interpreters which must respond to input upon newline.
  1315. Normally, the scanner would seek a character beyond the newline; forc-
  1316. ing the user to type an additional character before returning the car-
  1317. riage return token to the parser.
  1318.  
  1319.      The user may employ the DLG -i  command-line  option  to  request
  1320. that  unneeded  look-ahead  be removed whenever possible.  This allows
  1321. interactive parsers such as the interpreter  mentioned  above  to  get
  1322. tokens without the user having to type additional characters.  On some
  1323. systems special flags need to be set, so  that  the  scanner  actually
  1324. gets  the  characters  when  they  are received rather than having the
  1325. operating system buffer them.  On BSD unix the cbreak mode needs to be
  1326. used to accomplish this (e.g. stty cbreak).
  1327.  
  1328.      There are situations where  the  character  look-ahead  is  still
  1329. required.  Typically, this occurs when two patterns have the same pre-
  1330. fix.  For example, patterns A and Ab can only be distinguished by exa-
  1331. mining  the  character following pattern A.  A b character would indi-
  1332. cate that the token associated  with  the  second  pattern  should  be
  1333. returned.   Also,  any  pattern  that has a closure, + or *, must have
  1334. look-ahead to determine the end of the pattern, since the  pattern  by
  1335. definition can be repeated indefinitely.
  1336.  
  1337. 2.8.  DLG lexical input
  1338.  
  1339.      The user can specify that DLG is to take its input from a  stream
  1340. or  from  a  function.   The  function  must  behave like getchar() by
  1341. returning a new character per invocation.  The function must return -1
  1342. when  no  more  characters  are  available  to  signal  "end-of-file."
  1343. Presumably, the function would read characters from  some  buffer  and
  1344. hand  them  one by one to DLG upon request.  For example, a user might
  1345. define the following.
  1346.  
  1347.  
  1348.  
  1349.  
  1350. char text_edit_buf[BIG];
  1351.  
  1352. int nextchar()
  1353. {
  1354.     static char *p = &text_edit_buf[0];
  1355.     return (p < &text_edit_buf[BIG]) ? *(p++) : -1;
  1356. }
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.                                                                Page 21
  1364.  
  1365. PCCTS 1.00
  1366.  
  1367.  
  1368. Then, when invoking the parser, the user would call:
  1369.  
  1370.  
  1371.  
  1372.  
  1373. {
  1374.         ...
  1375.     ANTLRf(start_symbol(), nextchar);
  1376.     ...
  1377. }
  1378.  
  1379.  
  1380.  
  1381. 2.9.  Tracking pattern position
  1382.  
  1383.      There are several global variables available in the scanners pro-
  1384. duced  by  DLG  to  keep  track of the position of a pattern within an
  1385. input stream.  zzline tracks vertical position and must be  explicitly
  1386. updated  by the user's grammar. zzbegcol and zzendcol track horizontal
  1387. position-column number within a line.  They are maintained by the  DLG
  1388. automaton  for  characters  that  are  normally  one  character  wide.
  1389. zzendcol needs to be corrected for cases when the character is not one
  1390. character wide, e.g. tabs or carriage return.
  1391.  
  1392.      To enable the position tracking, a #define ZZCOL needs to be  put
  1393. in  an  action  in  the  lexical  specification or -DZZCOL needs to be
  1394. included in the command line when compiling the C code for the lexical
  1395. analyzer.
  1396.  
  1397.      This section described how a stream of input  characters  can  be
  1398. collected  into  a  sequence  of  tokens  and how one can act upon the
  1399. recognition of particular tokens.  Sentences in a  language  are  com-
  1400. posed of tokens and are described using a set of rules.  The next sec-
  1401. tion presents the PCCTS meta-language for describing language syntax.
  1402.  
  1403. 3.  Syntactic analysis
  1404.  
  1405.      Once the lexical structure of a language has been specified,  the
  1406. way  in  which  tokens  can  be  combined  to  form  sentences must be
  1407. described.  The set of valid sentences in a language is described by a
  1408. set  of  rules, written in an appropriate meta-language, that impose a
  1409. structure on the sequence of input tokens.
  1410.  
  1411.      In most parser-generator tools, context-free grammars are  speci-
  1412. fied  in  a  notation which is equivalent to BNF [Nau63]. However, the
  1413. notation used in regular expressions to  permit  repetition,  alterna-
  1414. tives,  etc.  can  be  used  to extend BNF (EBNF) so that context-free
  1415. grammars can be expressed more concisely.  This also has the advantage
  1416. of being more consistent with the regular expression notation and pro-
  1417. viding additional information which can be used to create a more effi-
  1418. cient  parser.   For these reasons, PCCTS accepts an EBNF-like grammar
  1419. notation.
  1420.  
  1421.      The input for PCCTS differs from EBNF primarily in  that  ::=  is
  1422.  
  1423.  
  1424.  
  1425.                                                                Page 22
  1426.  
  1427. PCCTS 1.00
  1428.  
  1429.  
  1430. replaced  by  :  and non-terminals are distinguished from terminals by
  1431. requiring all non-terminals to begin with a lowercase  letter,  rather
  1432. than  by  bracketing  non-terminals with <>.  Further, since rules can
  1433. become long when actions are embedded, each rule is terminated by a  ;
  1434. symbol.  These modifications are not arbitrary, but mirror the differ-
  1435. ences between YACC grammars and BNF (although PCCTS provides a  number
  1436. of extensions beyond YACC).
  1437.  
  1438.      As an example rule, consider:
  1439.  
  1440.  
  1441.  
  1442.  
  1443. block: "begin" (statement)* "end" ;
  1444.  
  1445.  
  1446.  
  1447. It indicates that rule a is defined to be the word  "begin",  followed
  1448. by zero or more statement's, followed by the word "end".
  1449.  
  1450.      This section describes the syntax of PCCTS rules and  the  method
  1451. by which rules communicate at run-time.
  1452.  
  1453. 3.1.  PCCTS rule definitions
  1454.  
  1455.      A rule is formally defined, in PCCTS's own notation, as:
  1456.  
  1457.  
  1458.  
  1459.  
  1460. rule    :   NonTerminal                 /* rule name */
  1461.             { "!" }                     /* turn off automatic AST construction */
  1462.             { {"\<"} InheritAction }    /* downward-inheritance ("input") */
  1463.             { "\>" InheritAction }      /* upward-inheritance ("output") */
  1464.             { QuotedTerm }              /* name for error reporting */
  1465.             ":" block ";"               /* actual rule elements */
  1466.             { Action }                  /* fail action */
  1467.         ;
  1468.  
  1469. block   :   alt ("\|" alt)*
  1470.         ;
  1471.  
  1472. alt     :   ( element )*
  1473.         ;
  1474.  
  1475. element :   TokenTerm  { "^" | "!" }
  1476.         |   QuotedTerm { "^" | "!" }
  1477.         |   NonTerminal { "!" }
  1478.             { {"\<"} InheritAction } { "\>" InheritAction }
  1479.         |   Action
  1480.         |   "\(" block "\)" { "\*" | "\+" } { InheritAction }
  1481.         |   "\{" block "\}" { InheritAction }
  1482.         ;
  1483.  
  1484.  
  1485.  
  1486.  
  1487.                                                                Page 23
  1488.  
  1489. PCCTS 1.00
  1490.  
  1491.  
  1492. where InheritAction is a C expression enclosed in [ ]  used  for  both
  1493. upward-  and downward-inheritance.  QuotedTerm is a regular expression
  1494. and TokenTerm is a label associated with some lexeme.
  1495.  
  1496. 3.1.1.  Subrules
  1497.  
  1498.      Rules that employ  EBNF  constructs  implicitly  define  subrules
  1499. according to the following syntax:
  1500.  
  1501. (i)  b  =(a  | a  | ... | a ); match 1 time
  1502.       i    1    2          m
  1503. [Figure omitted]
  1504.  
  1505. (ii) b  ={a  | a  | ... | a }; match 0 or 1 times
  1506.       i    1    2          m
  1507. [Figure omitted]
  1508.  
  1509. (iii)b  =(a  | a  | ... | a )*; match 0 or more times
  1510.       i    1    2          m
  1511. [Figure omitted]
  1512.  
  1513. (iv) b  =(a  | a  | ... | a )+; match 1 or more times
  1514.       i    1    2          m
  1515. [Figure omitted]
  1516.  
  1517.  
  1518. where a  represents an alternative (list of rule elements).
  1519.        i
  1520.      With each enclosing set of meta-symbols, a new level of  alterna-
  1521. tives  is  permitted.   Each  rule or subrule thus created is called a
  1522. "block." In terms of the recognizer generated,  blocks  generated  for
  1523. rules and subrules are virtually indistinguishable.  Subrules are like
  1524. macro expansions of rules.  However, there is no label associated with
  1525. a subrule and thus cannot be referred to by another rule or from else-
  1526. where within that rule.
  1527.  
  1528.      Consider the following rule which uses EBNF constructs:
  1529.  
  1530.  
  1531.  
  1532.  
  1533. e12 :   {"\+" | "\-"} VAR
  1534.     |   (FuncName | ProcName) parameterList
  1535.     |   "[0-9]+"
  1536.     ;
  1537.  
  1538.  
  1539.  
  1540.      Rule e12 has  3  alternatives.   The  first  alternative  has  an
  1541. optional  block  with 2 alternatives as its first element.  The { } is
  1542. an optional subrule.  VAR is a simple token.  The optional block  says
  1543. that a VAR can have a plus or minus in front, but it is not necessary.
  1544. The second alternative of rule a also  begins  with  a  subrule.   The
  1545. block  indicates  that  this alternative must begin with a function or
  1546.  
  1547.  
  1548.  
  1549.                                                                Page 24
  1550.  
  1551. PCCTS 1.00
  1552.  
  1553.  
  1554. procedure name.  parameterList is some  other  rule  which  presumably
  1555. looks for a list of parameters.  Alternative 3 is simply a token which
  1556. recognizes an integer number.
  1557.  
  1558.      Subrule meta-symbols alter the associativity of the | alternative
  1559. operator  and  can  be  nested  to any number of levels.  |'s have the
  1560. lowest precedence.
  1561.  
  1562.  
  1563.  
  1564.  
  1565. a: B | C  D ;
  1566.  
  1567.  
  1568.  
  1569.      Rule a specifies that the parser should match either B  or  C  D.
  1570. It  will not match a D preceded by a B or C.  The following version of
  1571. a will accomplish that:
  1572.  
  1573.  
  1574.  
  1575.  
  1576. a: (B | C) D;
  1577.  
  1578.  
  1579.  
  1580.      Empty alternatives called epsilon transfers can also be  used  to
  1581. imply optionality.  They are useful when you want an action to be per-
  1582. formed when nothing is matched by the other alternatives of the block.
  1583.  
  1584.  
  1585.  
  1586.  
  1587. a: B | C | ;
  1588. b: { B | C } ;
  1589.  
  1590.  
  1591.  
  1592.      Rules a and b are identical in what  they  match.   However,  the
  1593. resulting C code could be very different.  Also note that with rule a,
  1594. an action can placed in the empty alternative to be executed when a  B
  1595. or C is not matched.  Rule b does not have this capability.
  1596.  
  1597.      Subrules are allowed at most one parameter which must be of  type
  1598. Attrib.   The  attribute  $0  receives  the  inherited  parameter  for
  1599. subrules.  Subrules return values in $0  as  well  (which  become  the
  1600. appropriate $i in the enclosing subrule/scope above).  $0 is initially
  1601. undefined in rules and in  subrules  with  no  explicit  parameter  or
  1602. default $0 initialization.  See section 3.1.2.
  1603.  
  1604. 3.1.2.  Rule communication
  1605.  
  1606.      An advantage of LL parsers over LR parsers  is  that  inheritance
  1607. (rule/subrule  communication)  is  relatively  simple  and  efficient.
  1608.  
  1609.  
  1610.  
  1611.                                                                Page 25
  1612.  
  1613. PCCTS 1.00
  1614.  
  1615.  
  1616. PCCTS allows each non-terminal to have an arbitrary set  of  downward-
  1617. inherited  (parameters) and upward-inherited (return value) attributes
  1618. (see section 4.1.6).  The specification syntax is  presented  in  this
  1619. section  whereas  the use of rule communication is illustrated in sec-
  1620. tion 4.1.6.2:
  1621.  
  1622.  
  1623.  
  1624.  
  1625. rule[parameters] > [return_type(s)] : X  | X  | ... | X  ;
  1626.                                        1    2          m
  1627.  
  1628.  
  1629. which provide more powerful attribute handling than  can  be  achieved
  1630. with  the "$ variables" found in systems like YACC (and also supported
  1631. in PCCTS, primarily to ease the transition  for  users  familiar  with
  1632. YACC and to communicate with the lexical analyzer).
  1633.  
  1634.      Communicating with other rules should be as flexible as it is  in
  1635. a  programming language.  Hence, in addition to the standard attribute
  1636. mechanism, PCCTS supports the familiar high-level  language  parameter
  1637. passing  scheme.   The arguments to a rule must be consistent with the
  1638. parameter specifications given with the definition of the  rule.   For
  1639. example,
  1640.  
  1641.  
  1642.  
  1643.  
  1644. <<
  1645. #define GLOBAL 1
  1646. #define LOCAL 2
  1647. >>
  1648.  
  1649. prog    :    <<Sym *vars;>>
  1650.              TYPE dlist[GLOBAL] > [vars]
  1651.              <<OperateOn(vars);>>
  1652.              ...
  1653.         ;
  1654.  
  1655. /* Recognize a list of declarations.  The scoping level is passed
  1656.  * in and the list of symbols is returned.
  1657.  */
  1658. dlist[int level] > [Sym *list]
  1659.         :    <<$list=NULL;>>
  1660.              VAR           <<add($list, $1, $level);>>
  1661.              (    ","
  1662.                  VAR       <<add($list, $2, $level);>>
  1663.              )*
  1664.         ;
  1665.  
  1666.  
  1667.  
  1668. where add() is some function that adds an element to a list.  Here  we
  1669. have  used  the  attributes  only as a means of communicating with the
  1670.  
  1671.  
  1672.  
  1673.                                                                Page 26
  1674.  
  1675. PCCTS 1.00
  1676.  
  1677.  
  1678. lexical analyzer.
  1679.  
  1680.      In contrast to most programming languages, more  than  one  value
  1681. can  be  returned.  Each return value is set by simply referring to it
  1682. by the name given in the return value definition (prefixed  with  $) -
  1683. e.g.  $list in the dlist example.
  1684.  
  1685.      Subrules may not have return types  nor  parameter  list  defini-
  1686. tions.   They  may only pass a single attribute which becomes the ini-
  1687. tial value of $0 in the subrule.[1]
  1688.  
  1689.      To illustrate the effect of rule communications upon local  vari-
  1690. ables and scoping, consider:
  1691.  
  1692.  
  1693.  
  1694.  
  1695. rule[int a, Attrib b] > [float q, int r]        /* a,b visible to rule */
  1696.    :  <<int i,j; printf("starting rule a\n");>> /* i,j visible to rule  */
  1697.       ...
  1698.       (   <<int i;>>        /* i hides rule-local i */
  1699.           ...
  1700.           (    <<int i,r;>> /* def hides outer scope i; local r can't be used */
  1701.                <<$r=5;>>    /* $r is return value not local var */
  1702.           )
  1703.       )
  1704.    ;
  1705.  
  1706.  
  1707.  
  1708. Note that return values and parameters are always given priority  over
  1709. local  variables.  While generating C code for a rule, ANTLR scans the
  1710. actions and translates references  to  return  values  and  parameters
  1711. irrespective of scope.
  1712.  
  1713. 3.1.3.  Miscellaneous notes
  1714.  
  1715.      The user may attach a string to a non-terminal that is passed  on
  1716. to the error reporting macro/function zzsyn().  See section 5 on error
  1717. reporting for more details.
  1718.  
  1719.      The  user  may  elect  to  have  PCCTS  automatically   construct
  1720. abstract-syntax-trees  (AST's).  To disable automatic AST construction
  1721. for a rule, employ the ! as indicated above in the rule grammar.   See
  1722. section 4.2 on abstract-syntax-trees.
  1723.  
  1724.  
  1725.  
  1726. _________________________
  1727.   [1] An earlier version of PCCTS treated subrules  and
  1728. rules identically with respect to parameters and return
  1729. values.   The   current   distinction   represents   an
  1730. extension to the handling of rules.
  1731.  
  1732.  
  1733.  
  1734.  
  1735.                                                                Page 27
  1736.  
  1737. PCCTS 1.00
  1738.  
  1739.  
  1740. 3.1.4.  LL(k) parsing
  1741.  
  1742.      ANTLR attempts to build parsers that use as little look-ahead  as
  1743. possible.   Ambiguities  force  ANTLR to attempt resolution using more
  1744. and more tokens of look-ahead.  For example, ANTLR  tries  to  resolve
  1745. LL(1) ambiguities with LL(2).  If the grammar construct is still ambi-
  1746. guous, LL(k>2) is tried until either all ambiguities are  resolved  or
  1747. the  user-defined maximum k has been reached.  A subrule or rule which
  1748. requires LL(k>1) does not constrain  all  others  to  LL(k>1).   ANTLR
  1749. builds  mixed  model  parsers where each parsing decision is made with
  1750. the smallest of amount of look-ahead possible.   The  -k  command-line
  1751. option  is used to bound the maximum number of tokens of look-ahead to
  1752. be used by ANTLR-generated parsers.
  1753.  
  1754.      Most programming language constructs that cannot be described  in
  1755. LL(1)  can  be  easily  described  in LL(2).  Typically, LL(2) is only
  1756. required in a handful of rules yielding a general LL(1) parser with  a
  1757. few  anomalies.  For example, when parsing the C programming language,
  1758. a left-parenthesis could be the beginning of a type-cast or the begin-
  1759. ning  of  an expression.  With two tokens of look-ahead a parser could
  1760. use the token  following  the  parenthesis  to  determine  whether  an
  1761. expression  or  type-cast followed.  A more common problem lies in the
  1762. definition of labels.  The following grammar fragment illustrates  the
  1763. problem.
  1764.  
  1765.  
  1766.  
  1767.  
  1768. stat    :    { WORD ":" }          /* label definition */
  1769.              (
  1770.              |    "if" ...
  1771.              |    "while" ...
  1772.              .
  1773.              .
  1774.              |    WORD "\(" ...    /* forward ref to function */
  1775.              |    FUNC "\(" ...    /* ref to function already seen */
  1776.              )
  1777.         ;
  1778.  
  1779.  
  1780.  
  1781. With only one token of look-ahead, function stat() could not determine
  1782. whether  a  WORD on the input stream was to be matched as a label or a
  1783. yet to be seen function.  However, if two tokens or more  were  avail-
  1784. able, the colon or left-parenthesis following WORD would unambiguously
  1785. indicate which alternative to match.
  1786.  
  1787. 3.2.  Grammar ambiguities
  1788.  
  1789.      PCCTS parsers are of  the  top-down,  recursive  descent  variety
  1790. which  implies  that  all  parsing  decisions  must be left-decidable-
  1791. decidable given a finite sequence of input tokens looking from left to
  1792. right across productions.  Because of this limitation, there are gram-
  1793. mars for which PCCTS cannot construct a parser.  However, any language
  1794.  
  1795.  
  1796.  
  1797.                                                                Page 28
  1798.  
  1799. PCCTS 1.00
  1800.  
  1801.  
  1802. can  be  described  by several, equivalent grammars.  Ambiguities that
  1803. arise in a grammar may often be circumvented by modifying that grammar
  1804. while still recognizing the same language.
  1805.  
  1806.      A grammar is considered ambiguous (in  PCCTS's  opinion)  if  one
  1807. input   sequence   of  k  tokens  can  be  matched  by  two  different
  1808. productions/alternatives within the same block.   For  example,  if  k
  1809. equals one,
  1810.  
  1811.  
  1812.  
  1813.  
  1814. a   :   A B
  1815.         |   A C
  1816.         ;
  1817.  
  1818.  
  1819.  
  1820. is ambiguous because if all the parser "sees" is A, it will be  unable
  1821. to choose between alternatives one and two.  ANTLR reports the follow-
  1822. ing error message:
  1823.  
  1824.  
  1825.  
  1826.  
  1827. Antlr parser generator   Version 1.00   1989, 1990, 1991
  1828. "t.g", line 1: warning: alts 1 and 2 ambiguous upon { A }
  1829.  
  1830.  
  1831.  
  1832. If we allow two tokens of look-ahead (with -k 2), a parser  would  see
  1833. either  A B  or  A C  and could uniquely determine which production to
  1834. match.  If subrules and/or rule references are used, the set of possi-
  1835. ble input permutations grows quickly.
  1836.  
  1837.  
  1838.  
  1839.  
  1840. a   :   A (B | D) E F H
  1841.         |   A b E G H
  1842.         ;
  1843.  
  1844. b   :   B
  1845.         ;
  1846.  
  1847.  
  1848.  
  1849. Rule a is ambiguous when k equals one  or  two  since  A B  can  start
  1850. either production.  If we increase k to three, rule a is still ambigu-
  1851. ous because A B E begins both productions.  Only when k is set to four
  1852. is  a  unambiguous.   ANTLR  applies a similar logic when constructing
  1853. parsers.  When an ambiguity occurs  at  k==i,  k=i+1  is  tried  until
  1854. either  the ambiguity is resolved or the maximum look-ahead defined by
  1855. the user is reached (in which case the ambiguity is  reported  to  the
  1856.  
  1857.  
  1858.  
  1859.                                                                Page 29
  1860.  
  1861. PCCTS 1.00
  1862.  
  1863.  
  1864. user).  ANTLR reports the following for k==2,
  1865.  
  1866.  
  1867.  
  1868.  
  1869. Antlr parser generator   Version 1.00   1989, 1990, 1991
  1870. "t.g", line 1: warning: alts 1 and 2 ambiguous upon { A }, { B }
  1871.  
  1872.  
  1873.  
  1874. Note the sequence A B is denoted by the singleton set  { A }  followed
  1875. by  the singleton set { B }.  In general, ambiguous input sequences of
  1876. k tokens are represented by a sequence of k sets.
  1877.  
  1878.      The -pa command-line option can be used to print out  the  user's
  1879. grammar  (minus  actions) annotated with the input token permutations.
  1880. The set sequence { A B }, { C D } means that the following four  input
  1881. token permutations are possible:
  1882.  
  1883.  
  1884.  
  1885.  
  1886. A C
  1887. A D
  1888. B C
  1889. B D
  1890.  
  1891.  
  1892.  
  1893. 3.3.  Look-ahead size
  1894.  
  1895.      The user's grammar can be analyzed  using  any  integer  k  value
  1896. (limited  by  machine size and how long the user wants to wait).  How-
  1897. ever, parsers constructed by ANTLR always use k values  equal  to  the
  1898. nearest  power  of two greater than or equal to the k specified by the
  1899. user.  ANTLR parsers treat the look-ahead  as  a  circular  buffer  in
  1900. which a "modulo k" operation is performed repeatedly.  If k is a power
  1901. of two, this operation reduces  to  a  logical-and  operation  whereas
  1902. other values generally require a divide - i.e. a time consuming opera-
  1903. tion.  Since the modulo operation is performed at least once for  each
  1904. input token, a divide operation would seriously degrade parser perfor-
  1905. mance.  The #define constant LL_K is set by ANTLR to the k  associated
  1906. with  parser execution.  Note that files not constructed by ANTLR will
  1907. need to define LL_K if they include antlr.h.  This can be handled with
  1908. a "-DLL_K=k" command-line option on most C compilers.
  1909.  
  1910. 3.4.  ANTLR parser construction
  1911.  
  1912.      ANTLR generates parsers in pure  C  code--i.e.  non-interpretive,
  1913. mutually-recursive sets of functions.  There is exactly one C function
  1914. for every rule present in an ANTLR  grammar  description.  Transforma-
  1915. tions  exist  to  convert grammar constructs to C language constructs.
  1916. To perform lexical analysis, ANTLR prepares a DLG input file that will
  1917. be  converted  to  a C scanner by DLG and then linked into the parser.
  1918.  
  1919.  
  1920.  
  1921.                                                                Page 30
  1922.  
  1923. PCCTS 1.00
  1924.  
  1925.  
  1926. Because of ANTLR's  flexibility,  C  code  generation  templates  vary
  1927. depending  on  command-line  options  and  #define's  [Par90].   ANTLR
  1928. parsers are fast primarily because they never have to back up and  map
  1929. EBNF  grammar constructs to efficient target language constructs.  The
  1930. current k tokens of look-ahead always tells the parser which  alterna-
  1931. tive  to  choose.   Also,  C's efficient function invocation mechanism
  1932. allows references to other rules to be handled quickly.
  1933.  
  1934. 3.4.1.  Efficiency
  1935.  
  1936.      The way grammars are described has a big impact on phrase  recog-
  1937. nition  speed.  Rules invoking other rules with tail-recursion (right-
  1938. recursion) like
  1939.  
  1940.  
  1941.  
  1942.  
  1943. /* S l o w  A n d  U g l y */
  1944. a: B c ;
  1945. c: a | ;
  1946.  
  1947.  
  1948.  
  1949. can be replaced with
  1950.  
  1951.  
  1952.  
  1953.  
  1954. /* F a s t e r  B u t  S t i l l  U g l y */
  1955. a: B (a | ) ;
  1956.  
  1957.  
  1958.  
  1959. or, better yet,
  1960.  
  1961.  
  1962.  
  1963.  
  1964. /* F a s t e s t  A n d  R e a d a b l e */
  1965. a: B (B)* ;
  1966.  
  1967.  
  1968.  
  1969. which is more concise and infinitely more readable.
  1970.  
  1971.      This example leads us to two important generalizations:
  1972.  
  1973.  
  1974.  
  1975. o    Subrules are much faster than invoking another rule to match  the
  1976.      same subgrammar.
  1977.  
  1978. o    Use the ( )* and ( )+ closure operators instead  of  tail  recur-
  1979.      sion.   This generates a while loop instead of recursive function
  1980.  
  1981.  
  1982.  
  1983.                                                                Page 31
  1984.  
  1985. PCCTS 1.00
  1986.  
  1987.  
  1988.      calls.
  1989.  
  1990.  
  1991.      Rules or subrules with many alternatives tend to generate  bigger
  1992. and  slower  programs.  This arises from the fact that a linear search
  1993. implemented by a sequence of if statements is used to determine  which
  1994. alternative to choose.  Although general LL(k) parsing makes it diffi-
  1995. cult to optimize this search for the correct alternative, future  ver-
  1996. sions  of  PCCTS  will probably make a number of special-case improve-
  1997. ments, such as generating a  switch  statement  for  each  alternative
  1998. selection problem which is LL(1).
  1999.  
  2000.      In many parser-generators, such as  YACC,  adding  actions  to  a
  2001. grammar  can  cause  rules to be split, introducing ambiguities and/or
  2002. extra states in the generated parser.  In contrast,  actions  have  no
  2003. affect  on  the  structure  of  the  recognizers constructed by PCCTS.
  2004. PCCTS simply generates C code templates that implement the  recognizer
  2005. and  embeds C code for the user-supplied actions at the proper points.
  2006. User actions have no significant affect on parsing speed.
  2007.  
  2008. 3.4.2.  Debugging parsers
  2009.  
  2010.      PCCTS parsers have one function for each rule.  The function name
  2011. will  coincide with the rule it was constructed from and therefore can
  2012. be referenced from within a source-level debugger.  Breakpoints can be
  2013. set  so  that  parser  execution stops before or after certain grammar
  2014. fragments of interest have been recognized.  PCCTS parsers are easy to
  2015. follow  because  parsing  decisions are made using simple if and while
  2016. statements.
  2017.  
  2018.      Often it is convenient to track the sequence of rule  invocations
  2019. made  in an PCCTS parser.  The -gd command-line option forces PCCTS to
  2020. generate code that calls zzTRACE() with the  rule  name  in  which  it
  2021. appears as an argument.  zzTRACE() can be a macro or a function.
  2022.  
  2023. 3.5.  PCCTS parser template
  2024.  
  2025.      The following code template can be used to begin parser  develop-
  2026. ment.
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.                                                                Page 32
  2046.  
  2047. PCCTS 1.00
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054. /*
  2055.  * A N T L R  P a r s e r  T e m p l a t e
  2056.  *
  2057.  * Terence Parr, Hank Dietz and Will Cohen
  2058.  * CARP Research Group
  2059.  * Purdue University Electrical Engineering
  2060.  * PCCTS Version 1.00
  2061.  */
  2062. #header << /* Define Attrib/AST or include standard package */ >>
  2063.  
  2064. /* O p t i o n a l */
  2065. #token "[\t\ ]+"    << zzskip(); >>                /* Ignore White */
  2066. #token "\n"         << zzline++; zzskip(); >>      /* Track Line # */
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073. <<
  2074. main() { ANTLR(startSymbol(), stdin); }
  2075.  
  2076. zzcr_attr(attr, token, text)
  2077. Attrib *attr;
  2078. int token;
  2079. char *text;
  2080. {
  2081.     /* *attr = Function(text, token) */
  2082. }
  2083.  
  2084. zzd_attr(attr) Attrib *attr; { /* destroy attribute */ }
  2085.  
  2086. zzcr_ast(ast, attr, tok, text)
  2087. AST *ast;
  2088. Attrib *attr;
  2089. int tok;
  2090. char *text;
  2091. {
  2092.     /* *ast = Function(attr) */
  2093. }
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.                                                                Page 33
  2108.  
  2109. PCCTS 1.00
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116. /* node constructor for use with #[] */
  2117. AST zzmk_ast(node, user_args)
  2118. AST *node;               /* newly created node */
  2119. {
  2120.     /* fill in node->fields */
  2121.     return node;
  2122. }
  2123.  
  2124. zzd_ast(ast) AST *ast; { /* destroy AST node pointed to by 'ast' */ }
  2125.  
  2126. #define zzdef0(zero)    /* *(zero) = initial $0 attrib */
  2127. >>
  2128.  
  2129. /* P u t  R u l e s  H e r e */
  2130.  
  2131.  
  2132.  
  2133. 3.6.  Grammatical actions
  2134.  
  2135.      Actions are blocks of C code enclosed in <<  and  >>.   They  are
  2136. placed  in  the  ANTLR-generated  C files according to position in the
  2137. corresponding grammar file.  In general, an action following  a  token
  2138. or  non-terminal  reference is executed after that grammar element has
  2139. been recognized.  There is no restriction concerning  their  placement
  2140. within  rules.   However,  actions  cannot be specified between rules.
  2141. They may only be used before and after the set of rules.
  2142.  
  2143. 3.6.1.  Init Actions
  2144.  
  2145.      If an action is specified before any  grammar  element  is  found
  2146. after  the  : in a rule definition or after the start of a subrule, it
  2147. is placed before any ANTLR generated C code for that rule or  subrule.
  2148. This allows the user to define variables and execute C code in a scope
  2149. local to that rule or subrule; any  C  code  given  is  executed  just
  2150. before  the  rule  or  subrule  is applied.  For example, consider the
  2151. definition of a rule a:
  2152.  
  2153.  
  2154.  
  2155.  
  2156. a   :   <<List *p=NULL;>>   /* Get a type followed by a list of vars */
  2157.         Type
  2158.         (   <<int i=0;>>
  2159.             Var <<append(p, i++, $1);>>
  2160.         )*
  2161.                 <<OperateOn(p);>>
  2162.     ;
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.                                                                Page 34
  2170.  
  2171. PCCTS 1.00
  2172.  
  2173.  
  2174. The init action <<List *p=NULL;>> defines a local auto variable called
  2175. p  and  initializes  it to NULL.  The subrule also has an init action,
  2176. <<int i=0;>>, which is executed every time the subrule is entered.
  2177.  
  2178.      The init actions of optional blocks are executed whether  or  not
  2179. the  elements  in  the  block are recognized.  This is due to the fact
  2180. that subrules (C code block) must be entered  in  order  to  determine
  2181. whether  or  not  that  grammar  construct can be matched on the input
  2182. stream.  This can be confusing, but on the other hand, we can force  a
  2183. variable  to  have  a  value even if nothing is matched in an optional
  2184. block.  For example,
  2185.  
  2186.  
  2187.  
  2188.  
  2189. a   :   <<Sym *p;>>
  2190.         ...
  2191.         { <<p=NULL;>> ":" Type <<p=$2;>> }
  2192.         <<OperateOn(p);>>
  2193.         ...
  2194.     ;
  2195.  
  2196.  
  2197.  
  2198.      The init-actions of closure blocks (( )* subrules)  are  executed
  2199. only  once - upon entry to the block.  This allows local variable ini-
  2200. tialization within closure blocks.
  2201.  
  2202.      Only $0 can be referenced in an init-action  since  nothing  will
  2203. have been matched when the action executes.  Default $0 initialization
  2204. occurs before init-actions are executed.
  2205.  
  2206.  
  2207. 3.6.2.  Fail actions
  2208.  
  2209.      Fail actions are actions that are  placed  immediately  following
  2210. the  ;  rule  terminator.   They are executed after a syntax error has
  2211. been detected but before a message is printed and the attributes  have
  2212. been  destroyed (optionally with zzd_attr(); see the section on attri-
  2213. butes).  However, attributes are not valid here because one  does  not
  2214. know at what point the error occurred and which attributes even exist.
  2215. Fail actions are often useful for cleaning up data structures or free-
  2216. ing memory.  For example,
  2217.  
  2218.  
  2219.  
  2220.  
  2221. a   :   <<List *p=NULL;>>
  2222.         ( Var <<append(p, $1);>> )+
  2223.                 <<OperateOn(p); rmlist(p);>>
  2224.     ;
  2225.     <<rmlist(p);>>
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.                                                                Page 35
  2232.  
  2233. PCCTS 1.00
  2234.  
  2235.  
  2236. The ( )+ loop matches a lists of  variables  (Var's)  and  collections
  2237. them  in a list.  The fail-action <<rmlist(p);>> specifies that if and
  2238. when a syntax error occurs, the elements are to be free()'ed.
  2239.  
  2240. 3.6.3.  Actions appearing outside of rules
  2241.  
  2242.      When PCCTS is used to construct a complete compiler, it is useful
  2243. to  be able to incorporate support code written in C in the same file.
  2244. For example, there must always be a  main  specified  and  the  ANTLR-
  2245. generated  parser must be invoked using the ANTLR macro.  Hence, PCCTS
  2246. allows arbitrary C code to appear as "actions" outside of the  grammar
  2247. rules.  The PCCTS description
  2248.  
  2249.  
  2250.  
  2251.  
  2252. <<
  2253. #include "junk"
  2254. static int local_to_the_parser;
  2255. main() {ANTLR(a(), stdin);}
  2256. >>
  2257.  
  2258. a: a_stuff ;
  2259. b: b_stuff ;
  2260.  
  2261. << hello() { printf("Hello?"\n"); } >>
  2262.  
  2263.  
  2264.  
  2265. will result in the following output C code:
  2266.  
  2267.  
  2268.  
  2269.  
  2270. #include "junk"
  2271. static int local_to_the_parser;
  2272. main() {ANTLR(a(), stdin);}
  2273.  
  2274. a()
  2275. {
  2276.     ... code to recognize a_stuff ...
  2277. }
  2278.  
  2279. b()
  2280. {
  2281.     ... code to recognize b_stuff ...
  2282. }
  2283.  
  2284. hello() { printf("Hello?"\n"); }
  2285.  
  2286.  
  2287.  
  2288.      Note that although these segments of C code look like  "actions,"
  2289. and the same rules apply concerning the use of escape characters, they
  2290.  
  2291.  
  2292.  
  2293.                                                                Page 36
  2294.  
  2295. PCCTS 1.00
  2296.  
  2297.  
  2298. are not actions per se.  Hence, no attribute values are accessible.
  2299.  
  2300. 4.  Attribute handling
  2301.  
  2302.      Given a grammar, PCCTS constructs a  C  program  that  recognizes
  2303. phrases  in  the  language  described by that grammar.  No translation
  2304. from source language to output language is  performed;  the  resulting
  2305. parser  merely  complains  if a syntax error is detected.  To effect a
  2306. transformation, actions must  be  embedded  within  the  grammar  that
  2307. either perform an immediate translation or create an intermediate-form
  2308. which is translated at a later time.  Grammar actions have  access  to
  2309. lexical information via run-time objects called attributes which are a
  2310. function of the token number and the text of the lexeme found  on  the
  2311. input  stream.   PCCTS  also supports the creation and manipulation of
  2312. abstract-syntax-trees (AST's) to handle more  complicated  transforma-
  2313. tions.  This section describes the use of attributes, attribute inher-
  2314. itance as well as other forms of rule communication, and the  handling
  2315. of AST's.
  2316.  
  2317. 4.1.  General attribute handling
  2318.  
  2319.      Attributes are objects that are associated  with  all  rules  and
  2320. rule  elements including block elements like { }.  Attributes are gen-
  2321. erally identified by $i (where i is a positive integer) and  are  used
  2322. in actions to identify the values of rule elements.  Attributes behave
  2323. like variables.  They are mentioned and labeled at analysis-time,  but
  2324. have values only at run-time.  The positive integers uniquely identify
  2325. an element within the currently active block and  within  the  current
  2326. alternative  of  that block.  With the invocation of each new block, a
  2327. new set of attributes becomes active and the previously active set  is
  2328. temporarily  inactive (unless $i.j, $$ or $inheritance_attr attributes
  2329. are used; see sections 4.1.4).  Attributes  are  scoped  exactly  like
  2330. local stack-based variables in C.
  2331.  
  2332.      $-variables refer to user-defined objects  associated  with  each
  2333. rule  element.   The  zzcr_attr()  function transforms lexical objects
  2334. into grammar attributes.  Attributes  associated  with  terminals  are
  2335. implicitly created and are a function of lexemes.  However, attributes
  2336. of non-terminals and subrules are explicitly  manipulated  by  actions
  2337. provided  by  the  user.   Terminals, which are lexical tokens, simply
  2338. have a value associated with them and  are  generally  referenced  not
  2339. reset  by  actions.   Attributes  that  are returned from or passed to
  2340. blocks are considered synthetic attributes.  Rules  and  subrules  may
  2341. communicate via attributes or with familiar high-level language param-
  2342. eter passing techniques (see sections 3.1.2 and 4.1.6).
  2343.  
  2344.      PCCTS requires that the user define the data type or structure of
  2345. the  attributes  as  well  as  specify  how to convert from lexemes to
  2346. attributes.  This provides significant control over  what  information
  2347. attributes  carry and how the lexical analyzer should react to lexical
  2348. objects found on the input stream.  The  type  of  the  attributes  is
  2349. always  defined by a C typedef named Attrib and must be defined before
  2350. antlr.h is included in  your  C  program.   Using  the  PCCTS  #header
  2351. instruction,  the  user  may  specify the C definition or #include the
  2352.  
  2353.  
  2354.  
  2355.                                                                Page 37
  2356.  
  2357. PCCTS 1.00
  2358.  
  2359.  
  2360. file needed to define Attrib.  The action associated with  #header  is
  2361. placed  in every C file generated from the input grammar files.  Any C
  2362. file created by the user that includes antlr.h must once again  define
  2363. Attrib before #include'ing antlr.h.
  2364.  
  2365.      Attributes are stored and accessed in stack  fashion.   With  the
  2366. recognition  of  each  element in a rule, a new attribute is pushed on
  2367. the stack-i.e.  becomes available.  In other words, the ith  attribute
  2368. is  not  available  until the ith rule element has been matched.  If a
  2369. rule element is something other than a simple token,  many  attributes
  2370. may  be  pushed  on  the attribute stack until they reduce to a single
  2371. attribute for that rule reference or subrule.
  2372.  
  2373.      For example, if attributes are to be simple integers, the follow-
  2374. ing C definition is sufficient and necessary
  2375.  
  2376.  
  2377.  
  2378.  
  2379. typedef int Attrib;.
  2380.  
  2381.  
  2382.  
  2383. However, this does not specify how those integer attributes  are  con-
  2384. verted from character strings in the input stream.
  2385.  
  2386. 4.1.1.  Attribute creation
  2387.  
  2388.      The attributes associated with terminals must be  a  function  of
  2389. the  text  and  the  token  number associated with that lexeme.  These
  2390. values are passed to zzcr_attr() which computes the  attribute  to  be
  2391. associated with that lexeme.  The user must define a function or macro
  2392. that has the following form:
  2393.  
  2394.  
  2395.  
  2396.  
  2397. zzcr_attr(attr, token, text)
  2398. Attrib *attr;   /* Pointer to attribute associated with this lexeme */
  2399. int token;
  2400. char *text;     /* text associated with lexeme */
  2401. {
  2402.     /* *attr = F(text,token); */
  2403. }
  2404.  
  2405.  
  2406.  
  2407. Consider the following Attrib and zzcr_attr() definition.
  2408.  
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.                                                                Page 38
  2418.  
  2419. PCCTS 1.00
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426. typedef union {int ival; float fval;} Attrib;
  2427.  
  2428. zzcr_attr(attr, token, text)
  2429. Attrib *attr;
  2430. int token;
  2431. char *text;
  2432. {
  2433.         switch ( token )
  2434.         {
  2435.                 case INT   : attr->ival = atoi(text); break;
  2436.                 case FLOAT : attr->fval = atof(text); break;
  2437.         }
  2438. }
  2439.  
  2440.  
  2441.  
  2442. The typedef specifies that attributes are integer  or  floating  point
  2443. values.   When  the  regular  expression  for  a floating point number
  2444. (which has been  labeled  FLOAT)  is  matched  on  the  input  stream,
  2445. zzcr_attr() converts the string of characters representing that number
  2446. to a C float.
  2447.  
  2448.      The next attribute example  is  more  involved.   Attributes  are
  2449. either  symbol  table  entries  or  integer  values.  Variables (VAR),
  2450. intrinsic types (BuiltInType) and parameters (PARAMETER) found on  the
  2451. input  stream  are  converted  to symbol table pointers.  Integers are
  2452. converted to C int's.
  2453.  
  2454.  
  2455.  
  2456.  
  2457. /* Assume Sym, zzsymget() are defined elsewhere */
  2458. #header <<typedef union { Sym *var; int val; } Attrib;>>
  2459.  
  2460. <<
  2461. Sym *cursym;
  2462.  
  2463. main() { ANTLR(prog(), stdin); }
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.  
  2476.  
  2477.  
  2478.  
  2479.                                                                Page 39
  2480.  
  2481. PCCTS 1.00
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488. zzcr_attr(attr, token, text)
  2489. Attrib *attr;
  2490. int token;
  2491. char *text;
  2492. {
  2493.     switch ( token )
  2494.     {
  2495.         case WORD :
  2496.         case BuiltInType :
  2497.         case PARAMETER :
  2498.         case VAR : attr->var = cursym;
  2499.                    break;
  2500.         case INT : attr->val = atoi(text);
  2501.                    break;
  2502.     }
  2503. }
  2504. >>
  2505.  
  2506.  
  2507.  
  2508.  
  2509.  
  2510.  
  2511. #token WORD "[a-zA-Z_][a-zA-Z_]*"
  2512.                 <<{ extern Sym *cursym;
  2513.  
  2514.                                 cursym = zzsymget(zzlextext);
  2515.                                 if ( cursym == NULL ) cursym = zzsymnew(zzlextext);
  2516.                                 else LA(1) = cursym->token;
  2517.                         }>>
  2518.  
  2519. prog :   ... VAR ... ;
  2520.  
  2521.  
  2522.  
  2523.  
  2524.      When a WORD is matched on the input stream, the character  string
  2525. is  looked  up  in the symbol table.  If it exists, a pointer to it is
  2526. placed in cursym and the current look-ahead token (LA(1)) is  modified
  2527. accordingly.  Otherwise, a symbol table record is created leaving cur-
  2528. sym pointing to it.  Also of note, we cannot place the zzsymget() call
  2529. into  zzcr_attr()  because  of  the look-ahead.  zzcr_attr() is called
  2530. after the token has been recognized; modifying  LA(1)  in  zzcr_attr()
  2531. would  have  no effect.  Parsing decisions are made based upon current
  2532. look-ahead and, therefore, the lexical action must "compute" the token
  2533. value before the parser receives it.
  2534.  
  2535. 4.1.2.  Attribute destruction
  2536.  
  2537.      The user may elect  to  "destroy"  all  attributes  created  with
  2538.  
  2539.  
  2540.  
  2541.                                                                Page 40
  2542.  
  2543. PCCTS 1.00
  2544.  
  2545.  
  2546. zzcr_attr().   A macro or function called zzd_attr(), is executed once
  2547. for every attribute.  This occurs collectively at  the  end  of  every
  2548. block.   zzd_attr() is passed the address of the attribute to destroy.
  2549. This can be useful when memory is allocated with zzcr_attr() and needs
  2550. to  be  free()'ed.   For  example, sometimes zzcr_attr() needs to make
  2551. copies of some lexical objects temporarily.   Rather  than  explicitly
  2552. inserting  code  into the grammar to free these copies, zzd_attr() can
  2553. be used to do it implicitly.  Notice that this concept is  similar  to
  2554. the constructors and destructors of C++ [Str87].
  2555.  
  2556.      Attributes are often character strings.  Copies  of  the  lexical
  2557. text  buffer  (managed by DLG) are made which later need to be deallo-
  2558. cated.  This can be accomplished with code similar to the following.
  2559.  
  2560.  
  2561.  
  2562.  
  2563. #header <<#define zzd_attr(attr) {free(*(attr));}
  2564.           typedef char *Attrib;>>
  2565.  
  2566. <<
  2567. zzcr_attr(attr, token, text)
  2568. Attrib *attr;
  2569. int token;
  2570. char *text;
  2571. {
  2572.     extern char *malloc();
  2573.  
  2574.     if ( token == StringLiteral )
  2575.     {
  2576.         *attr = malloc( strlen(text)+1 );
  2577.         strcpy(*attr, text);
  2578.     }
  2579. }
  2580. >>
  2581.  
  2582.  
  2583.  
  2584. 4.1.3.  Standard attribute definitions
  2585.  
  2586.      Some typical attribute types are defined  in  the  PCCTS  include
  2587. directory.   These  standard attribute types are contained in the fol-
  2588. lowing include files:
  2589.  
  2590.  
  2591. charbuf.h
  2592.      Attributes are fixed-size  buffers,  each  of  32  characters  in
  2593.      length.   If a string longer than 31 characters (31 + 1 '\0' ter-
  2594.      minator) is matched for a token, it is truncated  to  31  charac-
  2595.      ters.  The user can change this buffer length from the default 32
  2596.      by redefining ZZTEXTSIZE before  the  point  where  charbuf.h  is
  2597.      included.   The  text  for  an  attribute  must  be referenced as
  2598.      $i.text.
  2599.  
  2600.  
  2601.  
  2602.  
  2603.                                                                Page 41
  2604.  
  2605. PCCTS 1.00
  2606.  
  2607.  
  2608. int.hAttributes are int values derived from tokens  using  the  atoi()
  2609.      function.
  2610.  
  2611. charptr.h, charptr.c
  2612.      Attributes are pointers to dynamically-allocated  variable-length
  2613.      strings.   Although generally both more efficient and more flexi-
  2614.      ble than charbuf.h, these attribute  handlers  use  malloc()  and
  2615.      free(),  hence,  they  can  cause  memory fragmentation. The file
  2616.      charptr.c must be #include'd, or linked with, the  C  code  PCCTS
  2617.      generates for any grammar using charptr.h.
  2618.  
  2619.  
  2620. In addition to the standard library of attribute  handlers,  the  user
  2621. may  define  new  attribute  types and handlers - which should also be
  2622. placed in the PCCTS include directory.  The makefile template given in
  2623. section  1.4  knows where the include files live and will inform the C
  2624. compiler.
  2625.  
  2626.      The following example uses the charptr package:
  2627.  
  2628.  
  2629.  
  2630.  
  2631. #header <<#include "charptr.h">>
  2632.  
  2633. <<
  2634. #include "charptr.c"
  2635. main() { ANTLR(a(), stdin); }
  2636. >>
  2637.  
  2638. #token "\n"      <<zzskip();>>
  2639.  
  2640. a   :   "[a-z]+"  <<printf("matched %s\n", $1);>>
  2641.     ;
  2642.  
  2643.  
  2644.  
  2645. 4.1.4.  Attribute references
  2646.  
  2647.      PCCTS accepts five basic attribute referencing notations:
  2648.  
  2649. $i   This format refers to the ith rule  element  within  the  current
  2650.      alternative which can be a rule reference, token or subrule.
  2651.  
  2652. $i.j This format extends the $i notation to allow the user to refer to
  2653.      attributes  at scopes above the current scope. i is the scope and
  2654.      j is the jth rule element within the  alternative  that  encloses
  2655.      the current scope.
  2656.  
  2657. $$   This is a shorthand for the $0 of the enclosing rule and  can  be
  2658.      referred to from an action anywhere within the rule.
  2659.  
  2660. $label
  2661.      $rule is identical to $$ where rule is the name of the  enclosing
  2662.  
  2663.  
  2664.  
  2665.                                                                Page 42
  2666.  
  2667. PCCTS 1.00
  2668.  
  2669.  
  2670.      rule.
  2671.  
  2672.      $parameter refers to one of the user-defined parameters given  in
  2673.      the enclosing rule definition.
  2674.  
  2675.      $return_value refers to one of  the  user-defined  return  values
  2676.      given in the enclosing rule definition.
  2677.  
  2678. $[token, text]
  2679.      This represents an attribute constructor.  Its value is  computed
  2680.      using zzcr_attr just like any other attribute with token and text
  2681.      as parameters.  This is an explicit method of attribute  creation
  2682.      whereas normally attributes are created implicitly - one for each
  2683.      input terminal.  This mechanism can be useful when  creating  AST
  2684.      nodes  which are functions of attributes or for passing values to
  2685.      subrules.  For example, if attributes were integers  and  integer
  2686.      tokens  were  labeled  NUM, $[NUM,"34"] would create an attribute
  2687.      whose value was 34. $[] returns an empty attribute node.
  2688.  
  2689. 4.1.4.1.  $i references
  2690.  
  2691.      As a simple example of $i numbering in rules  with  alternatives,
  2692. consider the following.
  2693.  
  2694.  
  2695.  
  2696.  
  2697. a: B | C ;
  2698.  
  2699.  
  2700.  
  2701. Rule a has 2 alternatives.  $i refers to the ith rule element  in  the
  2702. current  block and within the same alternative.  So, in rule a, both B
  2703. and C are $1.
  2704.  
  2705.      Below, rule a has a subrule as the second  rule  element  and  is
  2706. referenced  as  $2  after the entire subrule has been matched.  Assume
  2707. that charptr.h attributes are in effect.
  2708.  
  2709.  
  2710.  
  2711.  
  2712. a : "ick" ("A" <<$0 = $1;>> | "B" <<$0 = $1;>>) "ugh"
  2713.     <<printf("$1,$2,$3 are %s,%s,%s\n", $1,$2,$3);>>
  2714.   ;
  2715.  
  2716.  
  2717.  
  2718.      In this case, one of the following will be printed  depending  on
  2719. whether "A" or "B" was found
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.                                                                Page 43
  2728.  
  2729. PCCTS 1.00
  2730.  
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736. $1,$2,$3 are ick,A,ugh
  2737. $1,$2,$3 are ick,B,ugh
  2738.  
  2739.  
  2740.  
  2741.      $2 is the attribute of the subrule ("A"|"B") and  is  the  second
  2742. rule  element  of  rule  a  (outermost  level).   However,  within the
  2743. subrule, "A" and "B" are both $1.  The initial value  of  $0  will  be
  2744. undefined  unless it either inherits a value or is assigned a value by
  2745. defining the macro zzdef0.  This value  can,  of  course,  be  altered
  2746. within the subrule by using $0 on the left side of an assignment.
  2747.  
  2748.      $$ always refers to the $0 of the  outermost  scope  -  the  rule
  2749. scope  (i.e  $1.0).   $$ can be referenced from any user action within
  2750. any subrule.
  2751.  
  2752. 4.1.4.2.  $i.j references
  2753.  
  2754.      The EBNF subrules of PCCTS introduce scoping  as  in  programming
  2755. languages.   To  access  attributes  at  scopes above (in an enclosing
  2756. scope) from within a user action, $i.j variables are used where  i  is
  2757. the  scope  and  j follows the normal attribute numbering.  Levels are
  2758. numbered from 1 starting at the rule level.  Each  subrule  increments
  2759. the  level.   Actions at level i cannot access attributes at level i+1
  2760. or below just like in a programming language.  Attributes of the  form
  2761. $i  are  accepted  as a shorthand.  When a level is not indicated, the
  2762. current scope will be assumed.  For example,
  2763.  
  2764.  
  2765.  
  2766.  
  2767. a   :    A B (C (D E) F) G ;
  2768.  
  2769.  
  2770.  
  2771. The following table summarizes levels and attribute numbers:
  2772.  
  2773.  
  2774.  
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.  
  2781.  
  2782.  
  2783.  
  2784.  
  2785.  
  2786.  
  2787.  
  2788.  
  2789.                                                                Page 44
  2790.  
  2791. PCCTS 1.00
  2792.  
  2793.  
  2794.  
  2795.          ____________________________________________________
  2796.          ____________________________________________________|
  2797.          |  A   ||    $1.1     |   $1   |   rule a after A   |
  2798.          |______||_____________|________|____________________|
  2799.          |______||_____________|________|____________________|
  2800.          |  C   ||    $2.1     |   $1   |    (C (D E) F)     |
  2801.          |______||_____________|________|____________________|
  2802.          |______||_____________|________|____________________|
  2803.          |  E   ||    $3.2     |   $2   |       (D E)        |
  2804.          |______||_____________|________|____________________|
  2805.          |______||_____________|________|____________________|
  2806.          |  G   ||    $1.4     |   $4   |   rule a after G   |
  2807.          |______||_____________|________|____________________|
  2808.  
  2809.  
  2810. In this example, actions at level 1 (rule level) cannot access  attri-
  2811. butes  within any of the subrules.  Actions before the subrules cannot
  2812. access these lower attributes because they have not been  created  yet
  2813. (the  terminals  have  not  been  recognized).   Actions following the
  2814. subrules cannot access the lower attributes because they have all been
  2815. collapsed into one attribute--namely, $3.
  2816.  
  2817. 4.1.4.3.  $label references
  2818.  
  2819.      Inheritance (parameters and  return  values)  and  rule-level  $0
  2820. attributes  are  referred to by name. $rule is identical to $$, but is
  2821. more informative.  The following two examples perform the  same  func-
  2822. tion,  but  the  first uses upward-inheritance and and the second uses
  2823. $rule notation.
  2824.  
  2825.  
  2826.  
  2827.  
  2828. #header <<#include "int.h">>
  2829.  
  2830. <<main() { ANTLR(start(), stdin); } >>
  2831.  
  2832. start :     <<int r;>>
  2833.             expr > [r] "\n" <<printf("result %d\n", r);>>
  2834.       ;
  2835.  
  2836. expr > [int result]
  2837.       :    "[0-9]+"        <<$result = $1;>>
  2838.            ( "\+" "[0-9]+" <<$result += $2;>> )*
  2839.       ;
  2840.  
  2841.  
  2842.  
  2843. Note that the next version does not  require  a  parameter  definition
  2844. since all rules implicitly return an attribute ($$, $rule).
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.                                                                Page 45
  2852.  
  2853. PCCTS 1.00
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860. #header <<#include "int.h">>
  2861.  
  2862. <<main() { ANTLR(start(), stdin); } >>
  2863.  
  2864. start :     expr "\n" <<printf("result %d\n", $1);>>
  2865.           ;
  2866.  
  2867. expr  :    "[0-9]+"        <<$expr = $1;>>
  2868.            ( "\+" "[0-9]+" <<$expr += $2;>> )*
  2869.       ;
  2870.  
  2871.  
  2872.  
  2873. Similarly, $parameter refers to one of the user-defined parameters.
  2874.  
  2875. 4.1.5.  $[token, text] attribute constructor
  2876.  
  2877.      This attribute is not automatically  destroyed  via  zzd_attr  if
  2878. zzd_attr  is  defined.  If necessary, the user must explicitly destroy
  2879. these attributes.  For example,
  2880.  
  2881.  
  2882.  
  2883.  
  2884. #header <<#include "charptr.h">>
  2885.  
  2886. <<
  2887. #include "charptr.c"
  2888. main() {ANTLR(a(), stdin);}
  2889. >>
  2890.  
  2891. a   :    <<Attrib b = $[0, "a string"];>>
  2892.          <<printf("b is %s\n", b);
  2893.            zzd_attr(&b); >>
  2894.     ;
  2895.  
  2896.  
  2897.  
  2898. which would yield
  2899.  
  2900.  
  2901.  
  2902.  
  2903. b is a string
  2904.  
  2905.  
  2906.  
  2907. Note that the token number is irrelevant for charptr  type  attributes
  2908. since its zzcr_attr is a function of the text only.
  2909.  
  2910.  
  2911.  
  2912.  
  2913.                                                                Page 46
  2914.  
  2915. PCCTS 1.00
  2916.  
  2917.  
  2918. 4.1.6.  Inheritance
  2919.  
  2920.      Inheritance refers to the ability of a rule to obtain information
  2921. about  the  context  in which it was invoked.  Because ANTLR generates
  2922. top-down parsers, information can be carried down  through  each  rule
  2923. invocation  as  well  as  returned.   This  ability,  dubbed downward-
  2924. inheritance, provides significant power  because  a  rule  can  decide
  2925. which rule invoked it or gain some other context altering information.
  2926. LR parser-generators create parsers of the bottom-up variety and  will
  2927. never  be  able  to  pass information to a subrule because recognition
  2928. begins at the leaves of the parse-tree and works it way upwards to the
  2929. root (start symbol).
  2930.  
  2931. 4.1.6.1.  $0 inheritance
  2932.  
  2933.      $0 is one mechanism by which attributes can be inherited from and
  2934. returned  to  an  invoking  block.  The inheritance mechanism uses the
  2935. attribute stack  to  initialize  the  $0  value  seen  by  a  subrule.
  2936. Subrules  can  only pass one parameter which is implicitly typed as an
  2937. attribute ($0).  The $0 of a subrule is undefined unless set by a user
  2938. action or by passing an attribute to that subrule.  For example,
  2939.  
  2940.  
  2941.  
  2942.  
  2943. decl :    TypeID
  2944.                   Var       <<$2.type = $1;>>
  2945.           ( "," Var <<$2.type = $0;>> )*[$1]
  2946.      ;
  2947.  
  2948.  
  2949.  
  2950. where the [ ] is an InheritAction mentioned above in the grammar for a
  2951. PCCTS  rule.   The  value  inside  is passed to the $0 of the subrule.
  2952. This syntax is also used to pass parameters to rules.  See  below  for
  2953. more  details.  In this case, we are passing the type of a declaration
  2954. (represented by the attribute associated  with  TypeID  -  $1  in  the
  2955. outermost  scope)  to  a  subrule  which  accepts  a list of variables
  2956. separated by commas.  This could alternatively be accomplished via
  2957.  
  2958.  
  2959.  
  2960.  
  2961. decl :    TypeID
  2962.           Var       <<$2.type = $1;>>
  2963.           ( "," Var <<$2.type = $1.1;>> )*
  2964.      ;
  2965.  
  2966.  
  2967.  
  2968. or with a local variable.
  2969.  
  2970.  
  2971.  
  2972.  
  2973.  
  2974.  
  2975.                                                                Page 47
  2976.  
  2977. PCCTS 1.00
  2978.  
  2979.  
  2980.  
  2981.  
  2982.  
  2983.  
  2984. decl :    <<Attrib type;>>
  2985.           TypeID    <<type = $1;>>
  2986.           Var       <<$2.type = type;>>
  2987.           ( "," Var <<$2.type = type;>> )*
  2988.      ;
  2989.  
  2990.  
  2991.  
  2992.      Unlike subrules, rules employ the C  hardware  stack  and  $0  is
  2993. never automatically set by inheritance.  Despite this, the inheritance
  2994. of a value for a rule's $0 can be accomplished by:
  2995.  
  2996.  
  2997.  
  2998.  
  2999. rule[Attrib dummy]: <<$0=$dummy;>> remainder_of_rule ;
  3000.  
  3001.  
  3002.  
  3003. This uses the  more  powerful  rule  communication  mechanism  and  an
  3004. assignment  to  $0  to  simulate  the  inheritance  mechanism used for
  3005. subrules.  Rules have a much more flexible inheritance  scheme  which,
  3006. combined  with  rule-local variables for subrule inheritance, make the
  3007. YACC-like attributes (Attrib's)  useful  primarily  for  communicating
  3008. with the lexical analyzer.
  3009.  
  3010.      If a macro called zzdef0 is #define'd, it is executed upon  entry
  3011. to  any  block (rule or subrule) via zzdef0(&($0)).  This macro can be
  3012. used to ensure that all attributes have a certain property.  For exam-
  3013. ple, if $0 is not set in a rule, then the $i in the invoking rule will
  3014. be undefined (some previous attribute typically).  Setting the $0 ini-
  3015. tially  to  NULL or some other meaningful value can be convenient.  If
  3016. attributes are string pointers, not assigning $0 to NULL  before  rule
  3017. completion  could cause an invoking rule to assume a valid pointer had
  3018. been returned (as $i).
  3019.  
  3020.      Note that use of zzdef0 is incompatible with the  use  of  $0  in
  3021. subrules  to  inherit  values, i.e., zzdef0 will destroy the inherited
  3022. value.
  3023.  
  3024. 4.1.6.2.  Generalized rule communication
  3025.  
  3026.      PCCTS rules may pass parameters and return values just as C func-
  3027. tions  do  (though,  PCCTS  rules  can  return multiple values).  This
  3028. mechanism can be viewed as generalized attribute handling  where  each
  3029. rule defines its downward- and upward-inheritance attribute types.
  3030.  
  3031. 4.1.6.2.1.  Downward-inheritance
  3032.  
  3033.      The syntax for PCCTS parameter passing (downward-inheritance)  is
  3034.  
  3035.  
  3036.  
  3037.                                                                Page 48
  3038.  
  3039. PCCTS 1.00
  3040.  
  3041.  
  3042. identical  to  that of the ANSI C Standard [ANS90] except that the ( )
  3043. is replaced by [ ].  Specifically, parameter declarations  are  comma-
  3044. separated lists of single declarations:
  3045.  
  3046.  
  3047.  
  3048.  
  3049. rule[type  var , ..., type  var ] : ... ;
  3050.          1    1           n    n
  3051.  
  3052.  
  3053. The parameter declarations are broken down into old style  C  declara-
  3054. tions when parsers are generated:
  3055.  
  3056.  
  3057.  
  3058.  
  3059. rule(var , ..., var )
  3060. type  va1 ;        n
  3061.     1..; 1
  3062. type  var ;
  3063. {   n    n
  3064.     /* Stuff to recognize rule */
  3065. }
  3066.  
  3067.  
  3068.  
  3069. which is recognized by both ANSI compliant and old-style C compilers.
  3070.  
  3071.      The parameters mentioned in the parameter declaration list may be
  3072. used  in user actions like any other variable just as in C except that
  3073. they must be preceded by a $.  The $ is consistent with references  to
  3074. the  attributes  associated  with  terminals and rule references.  For
  3075. example,
  3076.  
  3077.  
  3078.  
  3079.  
  3080. a[int i, int j] : <<printf("%d\n", $i+$j);>> ;
  3081.  
  3082.  
  3083.  
  3084. adds the two inherited attributes i and j and  prints  the  result  to
  3085. stdout.  It can be invoked in the following manner:
  3086.  
  3087.  
  3088.  
  3089.  
  3090. rule : a[3,4]
  3091.          ;
  3092.  
  3093.  
  3094.  
  3095.  
  3096.  
  3097.  
  3098.  
  3099.                                                                Page 49
  3100.  
  3101. PCCTS 1.00
  3102.  
  3103.  
  3104. 4.1.6.2.2.  Upward-inheritance
  3105.  
  3106.      Return values are similarly declared via a  comma-separated  list
  3107. of types and names enclosed in [ ] (following the parameter definition
  3108. if any):
  3109.  
  3110.  
  3111.  
  3112.  
  3113. rule[parameters] > [type  var , ..., type  var ] : ... ;
  3114.                         1    1           n    n
  3115.  
  3116.  
  3117. The names given in the return value definition may be used  to  expli-
  3118. citly  set  the  return  values.  These may be treated like $-prefixed
  3119. variables and can referenced as well as set.  The names in the  return
  3120. value definition may not conflict with any parameter or local variable
  3121. defined elsewhere in that rule.
  3122.  
  3123.  
  3124.  
  3125.  
  3126. a[int i, int j] > [int x, int y] : <<$x = $i+$j; $y = 0;>> ;
  3127.  
  3128.  
  3129.  
  3130. Rule a can be invoked in the following manner:
  3131.  
  3132.  
  3133.  
  3134.  
  3135. rule :  <<int i,j;>>
  3136.                 a[3,4] > [i,j]
  3137.          ;
  3138.  
  3139.  
  3140.  
  3141. which passes 3 and 4 to rule a which returns 7 and 0 placing them into
  3142. i and j respectively.
  3143.  
  3144. 4.2.  Abstract-syntax-tree construction and manipulation
  3145.  
  3146.      Many translation problems can be accomplished with actions embed-
  3147. ded  in  a grammar that simply compute an output phrase and send it to
  3148. the output stream.  Unfortunately, most translation problems cannot be
  3149. implemented  in such a straightforward manner.  For this reason, PCCTS
  3150. supports an  abstract-syntax-tree  (AST)  mechanism  that  provides  a
  3151. framework  for  constructing and manipulating intermediate representa-
  3152. tions of the input stream.
  3153.  
  3154.      Without touching the grammar description,  the  user  may  direct
  3155. PCCTS (by using the -gt command-line option) to automatically generate
  3156. an AST of the input stream.  By default, this AST is a  flat  tree  (a
  3157. list) with one node for each input token.  Generally, the organization
  3158.  
  3159.  
  3160.  
  3161.                                                                Page 50
  3162.  
  3163. PCCTS 1.00
  3164.  
  3165.  
  3166. of an AST reflects the language structure used to recognize  an  input
  3167. phrase.   A  flat  AST does not contain information about the language
  3168. structure and, in effect, would only be a  copy  of  the  input.   The
  3169. default  automatic tree construction can be modified by annotating the
  3170. grammar with a few appropriately placed characters and  is  sufficient
  3171. to handle many situations (such as arithmetic expressions) well.
  3172.  
  3173.      Some intermediate-forms cannot be adequately described by  simple
  3174. grammar  annotations (e.g. type-trees for the C programming language).
  3175. A more general tree construction mechanism is  provided  by  PCCTS  to
  3176. allow  explicit intermediate-form tree description and is described in
  3177. section 4.2.4.
  3178.  
  3179.      AST nodes and subtrees, both automatically  and  explicitly  con-
  3180. structed,  are  referenced via #-variables.  The notation and behavior
  3181. of these variables is similar to that of  the  attribute  $-variables.
  3182. They are always implicitly typed as pointers to AST nodes and are gen-
  3183. erally associated with rule and token references; rules yield subtrees
  3184. and tokens yield nodes.
  3185.  
  3186.      PCCTS parsers manage the actual creation of nodes  and  the  con-
  3187. struction of the trees, but the user must describe what information an
  3188. AST node is to carry and how to fill in that information.
  3189.  
  3190.      The command-line option -gt must be used to  access  any  of  the
  3191. features  is  this  section.   Also  note that the PCCTS automatically
  3192. defines #define GENAST so that the user may write code that depends on
  3193. whether or not trees are being constructed.
  3194.  
  3195. 4.2.1.  AST node creation
  3196.  
  3197.      PCCTS provides a default and an explicit node  constructor.   The
  3198. default  constructor  is  applied  for  each  token  in a rule defined
  3199. without the ! modifier (which indicates that the rule  should  disable
  3200. automatic  tree  construction)  and  is  a  function of the associated
  3201. attribute, token and lexical text.  The explicit constructor  is  user
  3202. defined and can take a variable number of arguments.
  3203.  
  3204.      A macro called zzcr_ast() can be defined to give a  default  node
  3205. definition  or  transformation.   Also,  user  actions embedded in the
  3206. grammar can modify AST fields.  AST nodes have the structure
  3207.  
  3208.  
  3209.  
  3210.  
  3211. struct _ast {
  3212.         struct _ast *right, *down;
  3213.         user_defined_fields
  3214. };
  3215.  
  3216.  
  3217.  
  3218. where user_defined_fields is  filled  in  via  the  #define  constant:
  3219. AST_FIELDS.   Only  the  user-defined fields should be modified by the
  3220.  
  3221.  
  3222.  
  3223.                                                                Page 51
  3224.  
  3225. PCCTS 1.00
  3226.  
  3227.  
  3228. user as right and down are handled by the code inserted by  PCCTS  and
  3229. could be subject to change.  zzcr_ast() is of the form
  3230.  
  3231.  
  3232.  
  3233.  
  3234. #define zzcr_ast(ast,attr,tok,text) *ast = F(attr, tok, text);
  3235.  
  3236.  
  3237.  
  3238. with
  3239.  
  3240.  
  3241.  
  3242.  
  3243. AST *ast;
  3244. Attrib *attr;
  3245. int tok;
  3246. char *text;
  3247.  
  3248.  
  3249.  
  3250. For example, a simple, but useful attribute and AST definition is
  3251.  
  3252.  
  3253.  
  3254.  
  3255. #header <<
  3256. typedef int Attrib;
  3257. #define AST_FIELDS int i;
  3258. #define zzcr_attr(attr, token, text) *(attr)=atoi(text)
  3259. #define zzcr_ast(ast, attr, tok, text) (ast)->i = *(attr)
  3260. >>
  3261.  
  3262.  
  3263.  
  3264. which defines both attributes and AST node data to be integers.   This
  3265. default  AST  node construction merely copies the integer found on the
  3266. input stream into the data field i of the new AST node.
  3267.  
  3268.      AST nodes may be explicitly constructed via a user-defined  func-
  3269. tion called zzmk_ast() which is defined as follows:
  3270.  
  3271.  
  3272.  
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.                                                                Page 52
  3286.  
  3287. PCCTS 1.00
  3288.  
  3289.  
  3290.  
  3291.  
  3292.  
  3293. #include <varargs.h>
  3294.  
  3295. /* fill in an AST node (which is passed in) and return a ptr to it */
  3296. AST *zzmk_ast(va_alist)
  3297. va_dcl
  3298. {
  3299.     va_list ap;
  3300.     AST *node;
  3301.  
  3302.     va_start(ap);
  3303.     node = va_arg(ap, AST *);  /* 1st arg is always a new AST node */
  3304.     ...
  3305.     /* fill in node */
  3306.  
  3307.     va_end(ap);
  3308.     return node;
  3309. }
  3310.  
  3311.  
  3312.  
  3313. Note that the K&R-style variable argument method is  not  required  if
  3314. you  are not interested in portability or a constant number of parame-
  3315. ters is passed (if only one node type is used, for example).  A  port-
  3316. able ANSI C version would look like the following:
  3317.  
  3318.  
  3319.  
  3320.  
  3321. #include <stdarg.h>
  3322.  
  3323. /* fill in an AST node (which is passed in) and return a ptr to it */
  3324. AST *zzmk_ast(AST *node, ...)
  3325. {
  3326.     va_list ap;
  3327.  
  3328.     va_start(ap, node);
  3329.     ...
  3330.     /* fill in node */
  3331.  
  3332.     va_end(ap);
  3333.     return node;
  3334. }
  3335.  
  3336.  
  3337.  
  3338. To make an  explicit  node  constructor  that  duplicates  the  simple
  3339. integer  AST  node definition given above, the following would suffice
  3340. (ANSI C version):
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.  
  3347.                                                                Page 53
  3348.  
  3349. PCCTS 1.00
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355. #header <<
  3356. typedef int Attrib;
  3357. #define AST_FIELDS int i;
  3358. #define zzcr_attr(attr, token, text) *(attr)=atoi(text)
  3359. #define zzcr_ast(ast, attr, tok, text) (ast)->i = *(attr)
  3360. #include <stdarg.h>
  3361. >>
  3362.  
  3363. AST *zzmk_ast(AST *node, ...)
  3364. {
  3365.     va_list ap;
  3366.  
  3367.     va_start(ap, node);
  3368.     node->i = va_arg(ap, int);
  3369.     va_end(ap);
  3370.     return node;
  3371. }
  3372.  
  3373.  
  3374.  
  3375. Now, an action may construct tree nodes via #[integer].  For example,
  3376.  
  3377.  
  3378.  
  3379.  
  3380. a > [AST *node]
  3381.         :    <<$node = #[34];>>  /* return a node with 34 in it */
  3382.     ;
  3383.  
  3384.  
  3385.  
  3386.  
  3387. The #[ ] node constructor is detailed in section 4.2.6.
  3388.  
  3389. 4.2.2.  AST node destruction
  3390.  
  3391.      A  routine  called  zzfree_ast(AST *t)  is  used  to   free   any
  3392. abstract-syntax-tree  created by an PCCTS parser.  If defined, a macro
  3393. called zzd_ast is applied to  each  AST  node  before  its  memory  is
  3394. free()'d.   This  can  be  used to free any additional memory that may
  3395. have been allocated by zzcr_ast and attached to the  AST  nodes.   The
  3396. zzd_ast  macro  is passed the address of the node it is to destroy and
  3397. is of the form
  3398.  
  3399.  
  3400.  
  3401.  
  3402. #define zzd_ast( treeNodePtr )  /* perform operation on tree node */
  3403.  
  3404.  
  3405.  
  3406.  
  3407.  
  3408.  
  3409.                                                                Page 54
  3410.  
  3411. PCCTS 1.00
  3412.  
  3413.  
  3414. zzd_ast must be defined  in  or  included  into  the  #header  action.
  3415. zzfree_ast() must be called explicitly by the user.
  3416.  
  3417. 4.2.3.  Automatic AST construction
  3418.  
  3419.      For small or uniform  grammars  (like  C  language  expressions),
  3420. PCCTS  provides  a  concise tree construction mechanism.  Token refer-
  3421. ences are annotated to indicate
  3422.  
  3423. o    which tokens are to be subtree roots in the AST
  3424.  
  3425. o    which tokens are to be excluded from the AST
  3426.  
  3427. Any non-modified (non-root and non-excluded)  token  is  considered  a
  3428. leaf  node.   Rule  names are never included in the automatically gen-
  3429. erated AST's.  The  resulting  tree  is  composed  entirely  of  nodes
  3430. derived  from  grammar  terminals.   Each  rule  yields  one  subtree.
  3431. Subrules do not create subrules;  elements  enclosed  within  subrules
  3432. modify  the  subtree for the current rule.  Subtrees and nodes created
  3433. from terminal  references  are  accessed  from  user  actions  via  #-
  3434. variables which are discussed in section 4.2.6.
  3435.  
  3436. 4.2.3.1.  Grammar annotation
  3437.  
  3438.      PCCTS generates an AST by placing C code into the parser that, at
  3439. parser  run-time,  builds  a tree and makes it available to the user's
  3440. program.  AST's are stored in a child-sibling  list  form  similar  to
  3441. that used by LISP.  This allows each level in the AST to have one root
  3442. and arbitrarily many children:
  3443.  
  3444.  
  3445.  
  3446.  
  3447. (root child  child  ... child )
  3448.            1      2          n
  3449.  
  3450.  
  3451.      Suffixing a token with ^ identifies it as a subtree  root.   Each
  3452. root-token  encountered  increases the depth of the current subtree by
  3453. 1.  All further leaf tokens are considered siblings  to  the  previous
  3454. root  node.   A ! suffix on a terminal reference excludes the terminal
  3455. from the AST (no AST node is created or linked in). Suffixing  a  rule
  3456. reference  with  a  !  indicates that the subtree created by that rule
  3457. reference is not to be linked into the current subtree, but  is  still
  3458. to  be  made  available  via  #i  variables.   Rule references yield a
  3459. pointer to the root of the subtree created by  that  rule  invocation.
  3460. Therefore,  the subtree roots returned by rules become siblings in the
  3461. current rule.  Rules defined with a !  immediately following the  rule
  3462. name  (and before the :) do not automatically construct trees.  A ! in
  3463. the rule definition is like placing a !  after  each  grammar  element
  3464. within  that  rule.  #-variables do not exist for tokens suffixed with
  3465. !.  Hence, tree nodes are not automatically constructed  within  these
  3466. rules  although  references  to  other rules can still create subtrees
  3467. that can be accessed via #-variables.
  3468.  
  3469.  
  3470.  
  3471.                                                                Page 55
  3472.  
  3473. PCCTS 1.00
  3474.  
  3475.  
  3476. To demonstrate the actual construction of AST's, consider the  follow-
  3477. ing grammar fragment.
  3478.  
  3479.  
  3480.  
  3481.  
  3482. x   :   A B^ C! D y
  3483.     ;
  3484.  
  3485. y   :   E^ F
  3486.         ;
  3487.  
  3488.  
  3489.  
  3490. The grammar matches
  3491.  
  3492.  
  3493.  
  3494.  
  3495. A B C D E F
  3496.  
  3497.  
  3498.  
  3499. and considers B to be a subtree root.  Token C is to be ignored.  Rule
  3500. y  matches  E F  and  returns a subtree of depth 2 to rule x where the
  3501. root of rule y's subtree becomes available as #5.  The following  fig-
  3502. ure  sequence  shows  the  state  of the AST after each token has been
  3503. recognized.  The various AST nodes are  labeled  with  the  #-variable
  3504. that  could  be used to access that node.  The LISP-like child-sibling
  3505. notation is given after the input state.
  3506.  
  3507.  
  3508.                            [Figure omitted]
  3509.  
  3510.  
  3511. A o B C D E F,    ( A )
  3512.  
  3513.  
  3514.  
  3515.                            [Figure omitted]
  3516.  
  3517.  
  3518. A B o C D E F,    ( B A )
  3519.  
  3520.  
  3521.  
  3522.                            [Figure omitted]
  3523.  
  3524.  
  3525. A B C o D E F,    ( B A )
  3526.  
  3527.  
  3528.  
  3529.                            [Figure omitted]
  3530.  
  3531.  
  3532.  
  3533.                                                                Page 56
  3534.  
  3535. PCCTS 1.00
  3536.  
  3537.  
  3538. A B C D o E F,    ( B A D )
  3539.  
  3540.  
  3541.  
  3542.                            [Figure omitted]
  3543.  
  3544.  
  3545. A B C D E F o,    ( B A D ( E F ) )
  3546.  
  3547.  
  3548. Because of the ! suffix, terminal C does not appear in the AST.   Ter-
  3549. minal B is a root-token because of the ^ modifier and is therefore the
  3550. root of the subtree created for rule  x.   The  root  of  the  subtree
  3551. created  by  rule y is a sibling of the leaf nodes of rule x.  The way
  3552. in which rules describe a  grammar  effects  AST  construction.   e.g.
  3553. rules  x  and y could be rewritten to recognize the same input, but to
  3554. construct a different tree.
  3555.  
  3556.  
  3557.  
  3558.  
  3559. x   :   A B^ C! D E^ y
  3560.     ;
  3561.  
  3562. y   :   F
  3563.         ;
  3564.  
  3565.  
  3566.  
  3567. In this case the root-token E will become the root of the tree matched
  3568. up to that point (i.e. ( B A D )) yielding
  3569.  
  3570.  
  3571.  
  3572.  
  3573. ( E ( B A D ) )
  3574.  
  3575.  
  3576.  
  3577. The final AST would be
  3578.  
  3579.  
  3580.  
  3581.  
  3582. ( E ( B A D ) F )
  3583.  
  3584.  
  3585.  
  3586. 4.2.3.2.  Operator precedence
  3587.  
  3588.      Operator associativity in the AST's is directly  related  to  the
  3589. precedence implicitly defined among the rules. For example, to specify
  3590. that the exponentiation operator, **, groups right-to-left, a  grammar
  3591. similar to the following would be required.
  3592.  
  3593.  
  3594.  
  3595.                                                                Page 57
  3596.  
  3597. PCCTS 1.00
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604. expr :   exp0 { "\*\*"^ expr }
  3605.      ;
  3606. exp0 :   "[0-9]+"
  3607.      ;
  3608.  
  3609.  
  3610.  
  3611. The input
  3612.  
  3613.  
  3614.  
  3615.  
  3616. 3**4**5
  3617.  
  3618.  
  3619.  
  3620. would yield
  3621.  
  3622.  
  3623.  
  3624.  
  3625. ( \*\* 3 ( \*\* 4 5 ) )
  3626.  
  3627.  
  3628.  
  3629. indicating that the 4**5 would be performed first.
  3630.  
  3631.      For a full explanation of arbitrary  tree  construction  see  the
  3632. section  on explicit AST construction.  However, the following example
  3633. is beneficial in this section.  Give a grammar  fragment  that  recog-
  3634. nizes  a simple assignment, a tree of the form: ( := expr lvalue ) can
  3635. be constructed via:
  3636.  
  3637.  
  3638.  
  3639.  
  3640. assign! : lvalue ":=" expr ";" <<#0 = #(#[$2], #3, #1);>>
  3641.         ;
  3642.  
  3643.  
  3644.  
  3645. The ! after the rule definition tells PCCTS to turn off automatic tree
  3646. construction  for this rule.  #[$2] is an AST node constructed from an
  3647. attribute.
  3648.  
  3649. 4.2.3.3.  Example
  3650.  
  3651.      The following simple grammar illustrates the automatic  construc-
  3652. tion of AST's, the definition/creation of AST nodes, and the use of #i
  3653. variables
  3654.  
  3655.  
  3656.  
  3657.                                                                Page 58
  3658.  
  3659. PCCTS 1.00
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.  
  3666. #header <<
  3667.     typedef int Attrib;
  3668.     #define AST_FIELDS int i, token;
  3669.     #define zzcr_attr(attr, token, text) *(attr)=atoi(text)
  3670.     #define zzcr_ast(ast, attr, tok, text) {(ast)->i = *(attr); (ast)->token=0;}
  3671. >>
  3672.  
  3673.  
  3674.  
  3675.  
  3676.  
  3677.  
  3678.  
  3679. <<
  3680. AST *root = NULL;   /* define a root ptr for AST; must be NULL */
  3681.  
  3682. void show(tree)     /* define function to show a tree node */
  3683. AST *tree;
  3684. {
  3685.     if ( tree->token != 0 ) printf(" %s", zztokens[tree->token]);
  3686.     else printf(" %d", tree->i);
  3687. }
  3688. void before() { printf(" ("); }
  3689. void after() { printf(" )"); }
  3690.  
  3691. main()
  3692. {
  3693.     ANTLR(expr(&root), stdin);       /* get an expr AST by passing &root */
  3694.     zzpre_ast(root, show, before, after);/* print out in LISP notation */
  3695. }
  3696. >>
  3697.  
  3698.  
  3699.  
  3700.  
  3701.  
  3702.  
  3703.  
  3704. expr  :  exp0 ( "\+"^ <<#1->token=LA(1);>> exp0 )* "\n"! ;
  3705. exp0  :  exp1 ( "\*"^ <<#1->token=LA(1);>> exp1 )* ;
  3706. exp1  :  "[0-9]+"
  3707.       ;
  3708.  
  3709.  
  3710.  
  3711. The actions in rules expr and exp0 set the  token  field  (defined  in
  3712. AST_FIELDS)  to  the  current token of look-ahead (LA(1)).  This tells
  3713. the predefined astpreorder() function to print the token value and not
  3714. the  number  value (field i).  Note that we must pass the address of a
  3715. root pointer to expr so that expr can make it  point  to  the  subtree
  3716.  
  3717.  
  3718.  
  3719.                                                                Page 59
  3720.  
  3721. PCCTS 1.00
  3722.  
  3723.  
  3724. constructed  for  that rule.  The newline character is not included in
  3725. the trees because of the ! suffix.  The + and  the  *  characters  are
  3726. considered  operators  in  our language and so they are modified by ^.
  3727. The job performed by the default  AST  node  creation  macro  zzcr_ast
  3728. could  have  just as easily been accomplished by removing zzcr_ast and
  3729. changing rule exp1 to be
  3730.  
  3731.  
  3732.  
  3733.  
  3734. exp1  :  "[0-9]+" <<#1->i = $1; #1->token = 0;>>
  3735.       ;
  3736.  
  3737.  
  3738.  
  3739. which is somewhat more explicit, but would  be  inconvenient  if  many
  3740. such actions were required.
  3741.  
  3742.      If the input to this PCCTS parser example were 3+4,  the  program
  3743. would print out
  3744.  
  3745.  
  3746.  
  3747.  
  3748. ( \+ 3 4 )
  3749.  
  3750.  
  3751.  
  3752. which represents
  3753.  
  3754.  
  3755.                            [Figure omitted]
  3756.  
  3757.  
  3758. or, in child-sibling form
  3759.  
  3760.  
  3761.                            [Figure omitted]
  3762.  
  3763.  
  3764. Note that the AST is significantly different than the parse-tree which
  3765. can be represented by
  3766.  
  3767.  
  3768.                            [Figure omitted]
  3769.  
  3770.  
  3771. An input of 3+4*5 yields
  3772.  
  3773.  
  3774.  
  3775.  
  3776. ( \+ 3 ( \* 4 5 ) )
  3777.  
  3778.  
  3779.  
  3780.  
  3781.                                                                Page 60
  3782.  
  3783. PCCTS 1.00
  3784.  
  3785.  
  3786. which represents
  3787.  
  3788.  
  3789.                            [Figure omitted]
  3790.  
  3791.  
  3792. or, in child-sibling form
  3793.  
  3794.  
  3795.                            [Figure omitted]
  3796.  
  3797.  
  3798. The 4*5 would be performed before the  addition  because  one  of  the
  3799. addition's operands is itself an operation (i.e. a multiply).
  3800.  
  3801. 4.2.4.  Explicit AST construction
  3802.  
  3803.      The automatic tree construction scheme available  with  PCCTS  is
  3804. useful  for  building  AST's whose structure is similar to that of the
  3805. grammar parse trees.  It is  not  suited  to  applications  where  the
  3806. structure  of  the  grammar  bears  no  resemblance  to  the structure
  3807. required in the intermediate-form.  C declarations are a good  example
  3808. of  this  and  a  sample  "C  declaration  to  English"  translator is
  3809. developed in this section.
  3810.  
  3811.      Reasonable tree-construction and tree-rewriting systems, such  as
  3812. Purtilo  and  Callahan's [PuC89] NewYacc, have been developed but most
  3813. rely on bottom-up parser generators like YACC to build a parse-tree in
  3814. memory  which  is  later  traversed  to simulate inherited attributes.
  3815. PCCTS parsers construct AST's while parsing the input.  Rules can pass
  3816. subtrees as arguments to other rules and construct AST's without first
  3817. having to build a parse-tree.  PCCTS supports general AST construction
  3818. via two simple tree description constructs - AST node constructors and
  3819. AST tree definitions.
  3820.  
  3821.      The AST node constructor is similar to the constructor for attri-
  3822. butes ($[token,text]) except that AST node constructors yield pointers
  3823. to AST nodes whereas attribute constructors yield attributes (of  type
  3824. Attrib).   #[args]  creates  an AST node and passes a pointer to it to
  3825. zzmk_ast() with args as arguments.   Constructors  may  be  nested  to
  3826. create AST nodes from attributes; e.g.  #[ $[token,text] ].
  3827.  
  3828.      Trees are defined using a LISP-like notation because of its brev-
  3829. ity.
  3830.  
  3831.  
  3832.  
  3833.  
  3834. #( root, child , child , ..., child  )
  3835.               1       2            n
  3836.  
  3837.  
  3838. where root and child  are pointers to AST nodes which  can  themselves
  3839. be  trees  or  node iconstructors.  The return tree for any rule is #0
  3840.  
  3841.  
  3842.  
  3843.                                                                Page 61
  3844.  
  3845. PCCTS 1.00
  3846.  
  3847.  
  3848. which can appear on both the left- and right-hand side of  an  assign-
  3849. ment  statement.   Automatic construction of trees will proceed unless
  3850. the ! is included in the rule definition to override  the  normal  AST
  3851. mechanism.   The  same  grammar  may  have  some  rules  that  use the
  3852. automatic tree mechanism and other  rules  that  explicitly  construct
  3853. trees.   However,  the methods must not be mixed within the same rule.
  3854. In other words, do not assign a tree to #0 unless you have turned  off
  3855. the  automatic  tree  construction.   When default AST construction is
  3856. turned off, #-variables do not exist for terminals or rule  references
  3857. except  for  references  to  rules that construct trees (explicitly or
  3858. automatically).  Nodes for terminals must be explicitly  created  just
  3859. as the tree structure must be explicitly defined.
  3860.  
  3861. 4.2.4.1.  Simple example
  3862.  
  3863.      We present a trivial example in this section  to  illustrate  the
  3864. AST node and tree constructors.
  3865.  
  3866.  
  3867.  
  3868.  
  3869. #header <<
  3870.     #include "int.h"
  3871.     #define AST_FIELDS int i;
  3872. >>
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.  
  3883.  
  3884.  
  3885.  
  3886.  
  3887.  
  3888.  
  3889.  
  3890.  
  3891.  
  3892.  
  3893.  
  3894.  
  3895.  
  3896.  
  3897.  
  3898.  
  3899.  
  3900.  
  3901.  
  3902.  
  3903.  
  3904.  
  3905.                                                                Page 62
  3906.  
  3907. PCCTS 1.00
  3908.  
  3909.  
  3910.  
  3911.  
  3912.  
  3913.  
  3914. <<
  3915. AST *root = NULL;   /* define a root ptr for AST; must be NULL */
  3916.  
  3917. void show(tree)     /* define function to show a tree node */
  3918. AST *tree;
  3919. {
  3920.     printf(" %d", tree->i);
  3921. }
  3922. void before() { printf(" ("); }
  3923. void after() { printf(" )"); }
  3924.  
  3925. AST *zzmk_ast(node, v)
  3926. AST *node;
  3927. int v;
  3928. {
  3929.     node->i = v;
  3930.     return node;
  3931. }
  3932.  
  3933. main()
  3934. {
  3935.     ANTLR(tree(&root), stdin);
  3936.     zzpre_ast(root, show, before, after);
  3937. }
  3938. >>
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945. tree! :  NUM NUM NUM "\n"
  3946.          <<#0 = #( #[$[NUM,"101"]], #[$1], #[$2], #[$3] );>>
  3947.       ;
  3948.  
  3949. #token "\ "   <<zzskip();>>
  3950. #token NUM "[0-9]+"
  3951.  
  3952.  
  3953.  
  3954. Given the input 3 4 5, rule tree would return
  3955.  
  3956.  
  3957.  
  3958.  
  3959. ( 101 3 4 5 )
  3960.  
  3961.  
  3962.  
  3963. The rule itself matches three integers  followed  by  a  newline.   As
  3964.  
  3965.  
  3966.  
  3967.                                                                Page 63
  3968.  
  3969. PCCTS 1.00
  3970.  
  3971.  
  3972. usual,  the four attributes $1-$4 exist, but #1-#4 do not because rule
  3973. tree was defined with a ! modifier.  To create AST nodes for the  ter-
  3974. minals  we  use the node construct #[$i] which returns a new node con-
  3975. structed through zzmk_ast.  The newline is not to be included  in  the
  3976. tree  so no AST node was constructed for it.  To illustrate the attri-
  3977. bute constructor, a root node was created as a function of  an  attri-
  3978. bute with a value of 101, though #[101] would have been easier.  There
  3979. is no corresponding terminal in the grammar  for  this  AST  node  and
  3980. therefore  one was created.  $[NUM,"101"] creates an attribute through
  3981. zzcr_attr which is passed to zzmk_ast when enclosed in #[].  The  sub-
  3982. tree created in rule tree is explicitly returned by making #0 point to
  3983. the root of the subtree.
  3984.  
  3985. 4.2.4.2.  C declaration to English translator
  3986.  
  3987.      The type declaration syntax of C is somewhat bizarre and  can  be
  3988. troublesome  to  even experienced programmers.  The syntax of declara-
  3989. tion mirrors that of use.  In other words, variables are  defined  the
  3990. way  they would be used in an expression.  We give a loose description
  3991. of how to correctly "parse" a C declaration and then we present a com-
  3992. plete translator to describe, in English, what the declaration means.
  3993.  
  3994.      Kernighan and Ritchie [KeR88] give an  excellent  description  of
  3995. how to understand C declarations and they present a program to convert
  3996. from C to a word description.  To parse a declaration as a  Human,  we
  3997. follow a few simple rules.
  3998.  
  3999. (i)  Start parsing at the variable name.
  4000.  
  4001. (ii) Scan to the right.  For each [expr] or  ()  encountered  say  "n-
  4002.      element array of" or "function returning" respectively where n is
  4003.      the (optional) expression found inside  the  brackets.   Continue
  4004.      scanning until a right-parenthesis or a semicolon.
  4005.  
  4006. (iii)Now, scan left.  For each * say "pointer to" until you see a type
  4007.      name or a left-parenthesis.
  4008.  
  4009. (iv) Move to the next outer nesting level  if  one  exists  and  begin
  4010.      again  at  rule (ii).  If no more declaration symbols exist, look
  4011.      to the left and say  the  type  name  (ignoring  storage  classes
  4012.      here).
  4013.  
  4014. For example, let us parse
  4015.  
  4016.  
  4017.  
  4018.  
  4019. int *(*a[10])();
  4020.  
  4021.  
  4022.  
  4023. By (i), we begin at a.  Looking to the right in (ii), we see  brackets
  4024. and  so  we say "10-element array of."  The right-parenthesis makes us
  4025. jump to rule (iii) and scan left.  We see a * and  say  "pointer  to."
  4026.  
  4027.  
  4028.  
  4029.                                                                Page 64
  4030.  
  4031. PCCTS 1.00
  4032.  
  4033.  
  4034. The left-parenthesis finishes off (iii) and rule (iv) tells us to exit
  4035. this level of parenthesis (nesting) and start again at (ii).  Scanning
  4036. to  the  right  we see () and say "function returning."  The semicolon
  4037. forces us to (iii) where we see a * and say "pointer to."  (iv)  tells
  4038. us  to  say  "integer."  Packing all of the "sayings" together yields:
  4039. "10-element array of pointer to function returning pointer to integer"
  4040. or, in a flat tree representation,
  4041.  
  4042.  
  4043.  
  4044.  
  4045. ( [10] ( * ( () ( * int ) ) ) )."
  4046.  
  4047.  
  4048.  
  4049. Our example parser will construct trees of a  similar  form  but  with
  4050. result in a little better English.
  4051.  
  4052.      To build a type tree  for  C  we  "unroll"  the  nesting  of  the
  4053. declaration so that it can be read left-to-right.  Our trees will have
  4054. the variable name at the root and the type as the leaf.  Each node  in
  4055. the  tree  will  be  a type-qualifier.  The type-qualifiers are one of
  4056. [expr], (), * and are linked together in a parent/child  relationship.
  4057. e.g. ( i ( * int ) ) means that i is a pointer to an integer.
  4058.  
  4059.      The translator uses simple character buffers  as  attributes  and
  4060. AST  node  data.   The  trees  are constructed at parse-time and later
  4061. traversed to print out the description.  A function to find the bottom
  4062. of  a  parent/child  list  is required to augment the normal tree con-
  4063. struction features of PCCTS.
  4064.  
  4065.  
  4066.  
  4067.  
  4068. #header <<
  4069.     #include "charbuf.h"
  4070.     #define AST_FIELDS  Attrib attr;
  4071. >>
  4072.  
  4073. <<
  4074. AST *root = NULL;
  4075.  
  4076. AST *zzmk_ast(node,attr)
  4077. AST *node;
  4078. Attrib attr;
  4079. {
  4080.     node->attr = attr;
  4081.     return node;
  4082. }
  4083.  
  4084. main() { ANTLR(start(&root), stdin); }
  4085.  
  4086.  
  4087.  
  4088.  
  4089.  
  4090.  
  4091.                                                                Page 65
  4092.  
  4093. PCCTS 1.00
  4094.  
  4095.  
  4096.  
  4097.  
  4098.  
  4099.  
  4100. AST *bottom(t)
  4101. AST *t;
  4102. {
  4103.     if ( t==NULL ) return NULL;
  4104.     if ( t->down != NULL ) return bottom(t->down);
  4105.     return t;
  4106. }
  4107.  
  4108. english(tree)
  4109. AST *tree;
  4110. {
  4111.     printf("%s is", tree->attr.text);
  4112.     engl(tree->down, 0);
  4113. }
  4114.  
  4115.  
  4116.  
  4117.  
  4118.  
  4119.  
  4120. engl(tree, plural)
  4121. AST *tree;
  4122. int plural;
  4123. {
  4124.     if ( tree == NULL ) return;
  4125.     if ( strcmp(tree->attr.text, "*") == 0 )
  4126.         printf(plural?" pointers to":" a pointer to");
  4127.     else if ( strcmp(tree->attr.text, "nodim") == 0 ) {
  4128.         printf(plural?" arrays of":" an array of");
  4129.         plural = 1;
  4130.     }
  4131.     else if ( strcmp(tree->attr.text, "int") == 0 )
  4132.         printf(plural?" integers\n":" an integer\n");
  4133.     else if ( strcmp(tree->attr.text, "ret") == 0 )
  4134.         printf(plural?" functions returning": " a function returning");
  4135.     else {
  4136.         if ( plural ) printf(" %s-element arrays of", tree->attr.text);
  4137.         else printf(" a %s-element array of", tree->attr.text);
  4138.         plural = 1;
  4139.     }
  4140.     engl(zzchild(tree), plural);
  4141.     engl(zzsibling(tree), plural);
  4142. }
  4143. >>
  4144.  
  4145.  
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153.                                                                Page 66
  4154.  
  4155. PCCTS 1.00
  4156.  
  4157.  
  4158.  
  4159.  
  4160.  
  4161.  
  4162. #token "[\ \t\n]+"    <<zzskip();>>
  4163.  
  4164. start!  :   ( d <<english(#1); zzfree_ast(#1);>> )*
  4165.         ;
  4166.  
  4167. d!      :   <<AST *word;>>
  4168.             "int" d1[#[$1]] > [word] ";"        <<#0 = #(word, #2);>>
  4169.         ;
  4170.  
  4171. d1![AST *type] > [AST *word]
  4172.         :   "\*" d1[#(#[$1], $type)] > [$word]  <<#0 = #2;>>
  4173.         |   d2[$type] > [$word]                 <<#0 = #1;>>
  4174.         ;
  4175.  
  4176. d2![AST *type] > [AST *word]
  4177.         :   WORD d3[$type]                      <<$word = #[$1]; #0 = #2;>>
  4178.         |   "\(" d1[NULL] > [$word] "\)" d3[$type]
  4179.             <<#( bottom(#2), #4 ); #0 = (#2==NULL)? #4 : #2;>>
  4180.         ;
  4181.  
  4182. d3![AST *type]
  4183.         :   "\[" NUM "\]" d3[type]  <<#0 = #( #[$2], #4 );>>
  4184.         |   "\[" "\]"     d3[type]  <<#0 = #( #[$[WORD,"nodim"]], #3 );>>
  4185.         |   "\(" "\)"               <<#0 = #( #[$[WORD,"ret"]], type );>>
  4186.         |                           <<#0 = type;>>
  4187.         ;
  4188.  
  4189. #token NUM "[0-9]+"
  4190. #token WORD "[a-z]+"
  4191.  
  4192.  
  4193.  
  4194. The rules of this grammar perform the following functions
  4195.  
  4196. startMatch multiple declarations translating each one to  English  and
  4197.      freeing each tree.
  4198.  
  4199. d    Only integers are recognized for simplicity.  Declarations  begin
  4200.      with  "int"  and  are  terminated  by  a  ";".  Rule d1 returns a
  4201.      pointer to the AST  containing  the  symbol  name  found  in  the
  4202.      declaration  (which  has not yet been added to the tree).  Rule d
  4203.      returns the declaration found in rule d1 with the symbol name  as
  4204.      the  new root.  The type node is always the leaf and is passed to
  4205.      rule d1 which builds everything on top of the type node.
  4206.  
  4207. d1   The * is the lowest priority symbol in a declaration and hence we
  4208.      "look"  to  the  right  first.   The * is appended to whatever is
  4209.      found to the right.  This is accomplished by passing  the  *  and
  4210.      the  currently built tree to rule d2.  Since we are scanning from
  4211.      the left, but must translate as if starting from the most  deeply
  4212.  
  4213.  
  4214.  
  4215.                                                                Page 67
  4216.  
  4217. PCCTS 1.00
  4218.  
  4219.  
  4220.      nested  structure,  we must keep adding type-qualifiers on top of
  4221.      the root.  The current tree  is  always  passed  down.   Rule  d1
  4222.      returns a pointer to the AST node containing the variable name.
  4223.  
  4224. d2   Recognize a variable name followed by an array/function  descrip-
  4225.      tor  or recognize a parenthesized declarator.  Rule d2 creates an
  4226.      AST node for the variable name and returns  it.   The  tree  con-
  4227.      structed  by  rule  d3  is  also returned.  We need to attach the
  4228.      array/function descriptor to  the  bottom  of  the  parenthesized
  4229.      declarator which could be arbitrarily large.  For this reason, we
  4230.      use the bottom() function to  find  the  end  of  the  declarator
  4231.      returned by the reference to d1.
  4232.  
  4233. d3   Match an array or function descriptor.  Note that two  tokens  of
  4234.      look-ahead  are  required  to decide between alternatives one and
  4235.      two since both begin with a left-bracket.  Tail-recursion is used
  4236.      to  get  a  sequence  of [] or () descriptors.  Array descriptors
  4237.      like [34] are converted to tree nodes containing just the  number
  4238.      of  elements.   If no size is present, "nodim" is substituted for
  4239.      the number in the AST node.  If nothing is seen by  rule  d3,  it
  4240.      returns  the  type that was passed in since nothing was appended.
  4241.      Function descriptors form type-qualifiers labeled "ret".
  4242.  
  4243. It is interesting to note that the grammar actions  required  to  con-
  4244. struct the type trees were small and mostly assignments.  The explicit
  4245. tree constructors allow complicated trees to be built without a  great
  4246. deal of C code.
  4247.  
  4248.      The translator can be made using the following makefile.
  4249.  
  4250.  
  4251.  
  4252.  
  4253. # Makefile for C -> English translator
  4254. CFLAGS= -I../h
  4255. AFLAGS= -gt -k 2
  4256. GRM=decl
  4257. SRC=scan.c $(GRM).c err.c
  4258. OBJ=scan.o $(GRM).o err.o
  4259.  
  4260. test: $(OBJ) $(SRC)
  4261.     cc -o $(GRM) $(OBJ)
  4262.  
  4263. $(GRM).c parser.dlg : $(GRM).g
  4264.     antlr $(AFLAGS) $(GRM).g
  4265.  
  4266. scan.c : parser.dlg
  4267.     dlg -C2 parser.dlg scan.c
  4268.  
  4269.  
  4270.  
  4271. Our translator knows how and when to make things  plural  so  it  gen-
  4272. erates correct English.  For example,
  4273.  
  4274.  
  4275.  
  4276.  
  4277.                                                                Page 68
  4278.  
  4279. PCCTS 1.00
  4280.  
  4281.  
  4282.  
  4283.  
  4284.  
  4285.  
  4286. int *(*i[5])();
  4287.  
  4288.  
  4289.  
  4290. yields
  4291.  
  4292.  
  4293.  
  4294.  
  4295. i is a 5-element array of pointers to functions returning pointers to integers
  4296.  
  4297.  
  4298.  
  4299. 4.2.5.  Tree manipulation routines
  4300.  
  4301.      PCCTS generates code that calls the following set of tree manipu-
  4302. lation  routines to create AST's.  The user may modify the routines to
  4303. suit their own purposes.  The routines and AST  node  definitions  are
  4304. located  in  ast.c  and  ast.h  respectively  and  reside in the PCCTS
  4305. include directory.  They are automatically included when the ANTLR -gt
  4306. command-line  option  is specified.  Routines prefixed with underscore
  4307. are not normally called by the user.
  4308.  
  4309. void _link(_root, _sibling, _tail)
  4310.      Called to ensure tree manipulation variables for current rule are
  4311.      valid after a rule reference.
  4312.  
  4313. AST *_astnew()
  4314.      Create a new AST node and return it.
  4315.  
  4316. void _child(_root, _sibling, _tail)
  4317.      Add a leaf node to the current AST.  Creates an AST node, applies
  4318.      the  default  node  transformation  (zzcr_ast)  if it exists, and
  4319.      appends the node to the current sibling list.  After  this  func-
  4320.      tion, #i variables are available for user actions.
  4321.  
  4322. void _subroot(_root, _sibling, _tail)
  4323.      Perform the same operations as  _child(),  but  make  the  newly-
  4324.      created  node  the  root for the current sibling list.  If a root
  4325.      node exists, make the newly-created node the root of the  current
  4326.      root.
  4327.  
  4328. void zzpre_ast(tree, apply, before, after)
  4329.      Perform a preorder traversal of tree applying apply to each node.
  4330.      Apply  function  before  before the start of each new subtree and
  4331.      function after after you complete each subtree.
  4332.  
  4333.      A common use of this function is to print out a tree.  For  exam-
  4334.      ple,  if  AST  nodes had a field called token, the tree of tokens
  4335.      could be printed by defining the following
  4336.  
  4337.  
  4338.  
  4339.                                                                Page 69
  4340.  
  4341. PCCTS 1.00
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.      void show(tree)
  4349.      AST *tree;
  4350.      {
  4351.          if ( tree == NULL ) return;
  4352.          printf(" %s", zztokens[tree->token]);
  4353.      }
  4354.  
  4355.      void before() { printf(" ("); }
  4356.      void after()  { printf(" )"); }
  4357.  
  4358.  
  4359.  
  4360.      and then calling zzpre_ast() as
  4361.  
  4362.  
  4363.  
  4364.  
  4365.      zzpre_ast(some_tree, show, before, after);
  4366.  
  4367.  
  4368.  
  4369. AST *zzdup_ast(tree)
  4370.      Return a duplicate of the tree passed in.
  4371.  
  4372. void zzfree_ast(tree)
  4373.      Free the AST pointed to by tree applying  zzd_ast  to  each  node
  4374.      before freeing if it is defined.
  4375.  
  4376. zzrm_ast
  4377.      This macro is used to free  the  subtree  for  the  current  rule
  4378.      (using  zzfree_ast())  and  remove  all  references to it.  PCCTS
  4379.      maintains local pointers to the current sibling list etc... which
  4380.      must  be  NULL'ed  in  order to begin a new subtree.  Translators
  4381.      that perform an operation on a list of items using ()* or ()+ can
  4382.      add an action to free and remove references to the AST associated
  4383.      with the different items upon each iteration of  the  loop.  e.g.
  4384.      (item <<zzrm_ast;>>)+.
  4385.  
  4386. zzchild(tree)
  4387.      Return the first child of the node pointed to by  tree.   Returns
  4388.      NULL if tree is NULL.
  4389.  
  4390. zzsibling(tree)
  4391.      Return the immediate sibling of the  node  pointed  to  by  tree.
  4392.      Returns NULL if tree is NULL.
  4393.  
  4394.  
  4395. The parameters tree, _root, _sibling and _tail are defined as
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.                                                                Page 70
  4402.  
  4403. PCCTS 1.00
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410. AST *tree, **_root, **_sibling, **_tail;
  4411.  
  4412.  
  4413.  
  4414. A useful modification to _astnew() would be to use  custom  allocation
  4415. of  AST  nodes.   Since  they  are all the same size, it could be done
  4416. quickly and efficiently.
  4417.  
  4418. 4.2.6.  AST references
  4419.  
  4420.      References to AST objects come in three basic forms.
  4421.  
  4422. #i   This attribute refers to the tree constructed for  the  ith  rule
  4423.      element   within  the  current  alternative.   #i  variables  are
  4424.      scoped/numbered just like $i variables and their association dis-
  4425.      solves  after  leaving the current attribute scope.  #i is unique
  4426.      until the current block is exited or another iteration of a (  )*
  4427.      or a ( )+ loop has begun.
  4428.  
  4429.      #0 is special and always refers to the root of the subtree  asso-
  4430.      ciated  with  the  rule in which it was referenced.  #0 is scoped
  4431.      like $$, not like $0; there is only one #0 for the  entire  rule.
  4432.      If  #0  is  ever  set  to  NULL,  the  current subtree disappears
  4433.      (without freeing the nodes).  Normally, #0 is only set  when  the
  4434.      automatic  AST  tree  creation  is turned off with a !  after the
  4435.      rule name in a definition.
  4436.  
  4437.      Since subrules do not have their own #0 values.  The #i value  of
  4438.      a  subrule  is  undefined.   However,  for  compatibility with $i
  4439.      numbering, subrules are counted as though they were  assigned  #i
  4440.      values:
  4441.  
  4442.      An example #-variable number is as follows.
  4443.  
  4444.  
  4445.  
  4446.  
  4447.      a   :   B
  4448.              ( C D /* #1 is C, #2 is D */ )*
  4449.              E
  4450.              /* #1 is B, #2 does not exist, #3 is E */
  4451.          ;
  4452.  
  4453.  
  4454.  
  4455.      When the automatic tree construction is turned off  for  a  rule,
  4456.      #-variables  for  terminals  are  undefined  since  nodes are not
  4457.      created for them.  #-variables always exist for  rule  references
  4458.      since  the  referenced  rule  may construct a tree (implicitly or
  4459.      explicitly).
  4460.  
  4461.  
  4462.  
  4463.                                                                Page 71
  4464.  
  4465. PCCTS 1.00
  4466.  
  4467.  
  4468. #[args]
  4469.      This form constructs an AST node and returns a pointer to it  (of
  4470.      type  AST *).   The  arguments and the newly-constructed node are
  4471.      passed to the zzmk_ast() function defined by the user.
  4472.  
  4473. #(root, child , child , ..., child )
  4474.      This for_ repres_nts a tree d_scriptor from a  set  of  AST  node
  4475.      pointers.  It is translated to a function call that links all the
  4476.      child nodes together as siblings, with root as their  parent.   A
  4477.      pointer  to the root is returned.  If the root is NULL, a pointer
  4478.      to the sibling list is returned.  #( NULL ) and #()  both  return
  4479.      NULL.    #( nodeptr )   yields  nodeptr.   All  child'ren  become
  4480.      siblings of each other and any siblings  of  the  child'ren  that
  4481.      existed previously become siblings also.  For example,
  4482.  
  4483.  
  4484.  
  4485.  
  4486.      #( NULL, #( NULL, #[a], #[b]), #[c] )
  4487.  
  4488.  
  4489.  
  4490.      results in a, b and c all being siblings.
  4491.  
  4492. 4.2.7.  Invoking parsers that construct trees
  4493.  
  4494.      PCCTS parsers pass an address of a root pointer  to  other  rules
  4495. while  constructing  AST's.   This  root  pointer  is always the first
  4496. parameter and will point to the subtree built for that rule upon  rule
  4497. completion.   Any  parameters  defined  for a rule are not affected by
  4498. this additional rule argument.  All root pointers must be set to  NULL
  4499. initially.   Normally,  PCCTS  generates  code  to  handle all pointer
  4500. parameter passing and tree manipulations.  However, the starting  rule
  4501. (i.e.  the  one called using the ANTLR macro) may try to reference the
  4502. root pointer it presumes was passed in.  Therefore, the address  of  a
  4503. NULL-initialized root pointer must be manually passed in.  e.g.
  4504.  
  4505.  
  4506.  
  4507.  
  4508. AST *root = NULL;
  4509.  
  4510. main()
  4511. {
  4512.         ANTLR(start(&root), stdin);
  4513. }
  4514.  
  4515. start : stuff ;
  4516.  
  4517.  
  4518.  
  4519. This root parameter will be not be defined in rule start  if  the  -gt
  4520. command-line option is not used.
  4521.  
  4522.  
  4523.  
  4524.  
  4525.                                                                Page 72
  4526.  
  4527. PCCTS 1.00
  4528.  
  4529.  
  4530.      Note that if main() is located in a file  other  than  a  grammar
  4531. file, the user must explicitly include ast.h.
  4532.  
  4533. 4.2.8.  Error recovery and AST's
  4534.  
  4535.      When a syntax error is discovered by an  ANTLR-generated  parser,
  4536. no  further additions will be made to the subtree of the current rule.
  4537. Additions will resume after "successful" error recovery.  The  AST  is
  4538. always  left  in  a  stable state (i.e. a valid child-sibling tree) so
  4539. that user actions may examine  and/or  modify  the  tree.   This  also
  4540. ensures that syntax errors will not result in ill-formed trees.
  4541.  
  4542. 5.  Error detection and repair
  4543.  
  4544.      Reasonable error recovery is a notoriously difficult  task  which
  4545. is  handled  very poorly, or not at all, by most parser-generator sys-
  4546. tems.  In part, this may be due to the fact  that  most  systems  con-
  4547. struct  LR  parsers,  and these are theoretically less able to recover
  4548. from errors than LL parsers [FiL88].  It can also be justified on  the
  4549. basis  that  a  parser can be used to quickly find the first error, so
  4550. that an interactive user can repair the error  and  recompile  without
  4551. having  to read through a multitude of additional error messages which
  4552. might represent the parser's confusion rather than actual errors.
  4553.  
  4554.      In contrast, PCCTS attempts to provide a simple, automatic, error
  4555. reporting  and recovery mechanism.  Currently, ANTLR-generated parsers
  4556. recover from syntax errors by consuming tokens until a  token  in  the
  4557. FOLLOW  set  of X is discovered where X is the rule in which the error
  4558. was discovered.  Errors are reported in terms of  the  set  of  tokens
  4559. which could legally have appeared at that point.
  4560.  
  4561.      A syntax error occurs when a PCCTS parser discovers  a  token  on
  4562. the  input stream that cannot be matched to any currently recognizable
  4563. rule element.  Because PCCTS performs grammar analysis on  the  user's
  4564. grammar  description,  it  is aware of all possible tokens that can be
  4565. recognized at a given instant.  Sets  representing  these  tokens  are
  4566. passed  to  an  error  reporting  function  when  a  syntax  error  is
  4567. discovered.  Optionally, a fail-action can be executed.
  4568.  
  4569.      [Wir76] provides a simple mechanism for  recovering  from  syntax
  4570. errors in LL(1) parsers by consuming tokens until the current token is
  4571. found to be a member  of  a  "stopping  set."  This  stopping  set  is
  4572. comprised of the FOLLOW set for that rule and any user-defined marking
  4573. ("resynch") tokens that are never to be skipped (e.g.  BEGIN).   PCCTS
  4574. currently  employs  a simple variant of the [Wir76] mechanism.  When a
  4575. syntax error occurs in any production of rule X, the parser will  con-
  4576. sume input until the current token is a member of the stopping set for
  4577. X.
  4578.  
  4579.      The syntax error recovery mechanism employed by  PCCTS  does  not
  4580. effect  parser recognition speed unless an error is discovered.  PCCTS
  4581. error recovery is attractive because it is completely  automatic,  but
  4582. it tends to delete groups of tokens which may lead to erroneous resyn-
  4583. chronizations.  This "glutton" scheme could be refined by allowing the
  4584.  
  4585.  
  4586.  
  4587.                                                                Page 73
  4588.  
  4589. PCCTS 1.00
  4590.  
  4591.  
  4592. user  to  specify  a  set  of resynch tokens to augment the FOLLOW set
  4593. [Wir76].  These resynch tokens would be determined by experience.
  4594.  
  4595.      Sophisticated error recovery is possible using k tokens of  look-
  4596. ahead.   Future  versions  of PCCTS might employ this large look-ahead
  4597. for intelligent error  recovery.   Hence,  it  can  be  expected  that
  4598. automatic  error  handling  will  improve  without  requiring users to
  4599. change the input to PCCTS.
  4600.  
  4601. 5.1.  Modifying grammars to recognize common syntax errors
  4602.  
  4603.      The user may modify a given  grammar  to  recognize  common,  but
  4604. erroneous sentences.  For example, if rule expr8 below were part of an
  4605. expression recognizer for a programming language,
  4606.  
  4607.  
  4608.  
  4609.  
  4610. expr8   :    VAR
  4611.         |    INT
  4612.         |    FUNC "\(" elist "\)"
  4613.         ;
  4614.  
  4615.  
  4616.  
  4617. it could be modified to print an error message whenever  an  undefined
  4618. variable was seen.  In other words,
  4619.  
  4620.  
  4621.  
  4622.  
  4623. expr8   :    VAR
  4624.         |    INT
  4625.         |    FUNC "\(" elist "\)"
  4626.         |    WORD <<error("Undefined variable: %s", $1);>>
  4627.         ;
  4628.  
  4629.  
  4630.  
  4631. Without this additional production, the parser would  print  something
  4632. like (assuming test was the undefined variable found):
  4633.  
  4634.  
  4635.  
  4636.  
  4637. syntax error at "test" missing { VAR INT FUNC }
  4638.  
  4639.  
  4640.  
  4641. The extra production would allow a more informative error  message  to
  4642. be printed, such as:
  4643.  
  4644.  
  4645.  
  4646.  
  4647.  
  4648.  
  4649.                                                                Page 74
  4650.  
  4651. PCCTS 1.00
  4652.  
  4653.  
  4654.  
  4655.  
  4656.  
  4657.  
  4658. Undefined variable: "test"
  4659.  
  4660.  
  4661.  
  4662. 5.2.  Default error reporting function
  4663.  
  4664.      The default error reporting function, zzsyn(), is defined as fol-
  4665. lows.
  4666.  
  4667.  
  4668.  
  4669.  
  4670. void
  4671. zzsyn(char *text,     /* text of current token */
  4672.       int tok,        /* current token */
  4673.       char *egroup,   /* label attached to rule with error if present */
  4674.       unsigned *eset, /* etok==0 -> >1 token missing; set is eset */
  4675.       int etok)       /* etok>0 -> 1 token missing; token is etok */
  4676. {
  4677.     fprintf(stderr, "syntax error at \"%s\"", text);
  4678.     fprintf(stderr, " missing ");
  4679.     if ( !etok ) zzedecode(eset);
  4680.     else fprintf(stderr, "%s", zztokens[etok]);
  4681.     if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup);
  4682.     fprintf(stderr, "\n");
  4683. }
  4684.  
  4685.  
  4686.  
  4687.      A list of the regular expression or label  associated  with  each
  4688. token  value  is  stored  in  the  char  *zztokens[]  array  in err.c.
  4689. zzedecode() is a predefined function that decodes the  set  of  tokens
  4690. stored in the bit-set eset.
  4691.  
  4692.      zzsyn() can be modified according to the user's needs.  For exam-
  4693. ple,  it  can  be  modified  to  print  out  the  file and line number
  4694. (zzline).
  4695.  
  4696. 5.3.  Error groups
  4697.  
  4698.      The user may attach a string to a non-terminal that is passed  on
  4699. to  the  error  reporting  macro/function  zzsyn()  by placing it just
  4700. before the : in a rule definition. e.g.
  4701.  
  4702.  
  4703.  
  4704.  
  4705. declarator "declaration or definition" : ... ;
  4706.  
  4707.  
  4708.  
  4709.  
  4710.  
  4711.                                                                Page 75
  4712.  
  4713. PCCTS 1.00
  4714.  
  4715.  
  4716. Although zzsyn() can be redefined  by  the  user,  the  default  error
  4717. reporting  facility appends the specified string to the error message.
  4718. More than one rule may share the same string.  This mechanism can gen-
  4719. erate  decent error messages.  For example, one could specify that all
  4720. rules dealing with expressions (e.g. factor, term, conditional) are to
  4721. be  labeled  as  "expression".   The  default zzsyn() would then yield
  4722. something like:
  4723.  
  4724.  
  4725.  
  4726.  
  4727. syntax error at "NUM" missing { "\+" "\*" } in expression
  4728.  
  4729.  
  4730.  
  4731. as opposed to
  4732.  
  4733.  
  4734.  
  4735.  
  4736. syntax error at "NUM" missing { "\+" "\*" }
  4737.  
  4738.  
  4739.  
  4740. Another example might be that all rules used to define variables, such
  4741. as      rule      declarator      above,     should     be     labeled
  4742. "declaration or definition".
  4743.  
  4744. 5.4.  Error token classes
  4745.  
  4746.      The default syntax error reporting facility generates a  list  of
  4747. tokens  that could be possibility matched when the erroneous token was
  4748. encountered.  Often, this list is large and means little to  the  user
  4749. for  anything  but  small grammars.  For example, an expression recog-
  4750. nizer might generate  the  following  error  message  for  an  invalid
  4751. expression, "a . b":
  4752.  
  4753.  
  4754.  
  4755.  
  4756. syntax error at "." missing { "\+" "\-" "\*" "\/" "\&" "\|" "\<" "\>" "\=" ";" }
  4757.  
  4758.  
  4759.  
  4760. A better error message would be
  4761.  
  4762.  
  4763.  
  4764.  
  4765. syntax error at "." missing { operator ";" }
  4766.  
  4767.  
  4768.  
  4769. This modification can be accomplished by defining the error class:
  4770.  
  4771.  
  4772.  
  4773.                                                                Page 76
  4774.  
  4775. PCCTS 1.00
  4776.  
  4777.  
  4778.  
  4779.  
  4780.  
  4781.  
  4782. #errclass "operator" { "\+" "\-" "\*" "\/" "\&" "\|" "\<" "\>" "\=" }
  4783.  
  4784.  
  4785.  
  4786. 5.4.1.  Error class definitions
  4787.  
  4788.      The general syntax for #errclass is as follows:
  4789.  
  4790.  
  4791.  
  4792.  
  4793. #errclass label { e  e  ...  e  }
  4794.                    1  2       n
  4795.  
  4796.  
  4797. where label is either a quoted string or  a  label  (capitalized  just
  4798. like token labels).  The quoted string must not conflict with any rule
  4799. name or regular expression.  Groups of expressions  will  be  replaced
  4800. with  this  string and it must not appear to be a simple token.  Simi-
  4801. larly, an error class label may not share the same name as  a  labeled
  4802. token.   The error class elements, e , can be a labeled token, a regu-
  4803. lar expression or a non-terminal.  T_kens (labeled or regular  expres-
  4804. sions)  referenced  within  an  error  class must at some point in the
  4805. grammar be referenced in a rule or  explicitly  defined  with  #token.
  4806. The  definition need not appear before the #errclass definition.  If a
  4807. non-terminal is referenced, the FIRST set (set of all tokens that  can
  4808. be  recognized  first  upon  entering a rule) for that rule is instan-
  4809. tiated into the error class.  The -ge command-line option can be  used
  4810. to  have  PCCTS  generate  an error class for each non-terminal of the
  4811. form:
  4812.  
  4813.  
  4814.  
  4815.  
  4816. #errclass Rule { rule }
  4817.  
  4818.  
  4819.  
  4820. which implies that each non-terminal will have an error class composed
  4821. of  the  first set for that rule.  The error class name is the same as
  4822. the non-terminal except that the first character is converted to upper
  4823. case.
  4824.  
  4825.      Error class names may also be used as error class  elements  (e )
  4826. since  error class names are treated somewhat like tokens.  This capa-
  4827. bility allows error class hierarchies.  For example,
  4828.  
  4829.  
  4830.  
  4831.  
  4832.  
  4833.  
  4834.  
  4835.                                                                Page 77
  4836.  
  4837. PCCTS 1.00
  4838.  
  4839.  
  4840.  
  4841.  
  4842.  
  4843.  
  4844. #errclass Fruit { CHERRY APPLE }
  4845. #errclass Meat { COW PIG }
  4846. #errclass "stuff you can eat" { Fruit Meat }
  4847.  
  4848. yum :  (CHERRY | APPLE) PIE
  4849.     |  (COW | PIG) FARM
  4850.     |  THE (CHERRY | APPLE) TREE
  4851.     ;
  4852.  
  4853.  
  4854.  
  4855. Different error messages will result depending upon where in rule a  a
  4856. syntax error is detected.  If the input were
  4857.  
  4858.  
  4859.  
  4860.  
  4861. THE PIG TREE
  4862.  
  4863.  
  4864.  
  4865. the following error message would result:
  4866.  
  4867.  
  4868.  
  4869.  
  4870. syntax error at "PIG" missing { Fruit }
  4871.  
  4872.  
  4873.  
  4874. However, if the input were
  4875.  
  4876.  
  4877.  
  4878.  
  4879. FARM COW
  4880.  
  4881.  
  4882.  
  4883. the decent error message
  4884.  
  4885.  
  4886.  
  4887.  
  4888. syntax error at "FARM" missing { "stuff you can eat" THE }
  4889.  
  4890.  
  4891.  
  4892. would result.  Note that without  the  error  class  definitions,  the
  4893. error message would have been:
  4894.  
  4895.  
  4896.  
  4897.                                                                Page 78
  4898.  
  4899. PCCTS 1.00
  4900.  
  4901.  
  4902.  
  4903.  
  4904.  
  4905.  
  4906. syntax error at "FARM" missing { CHERRY APPLE COW PIG THE }
  4907.  
  4908.  
  4909.  
  4910. which conveys the same information, but at a much lower level.
  4911.  
  4912. 5.4.2.  Error class utilization
  4913.  
  4914.      PCCTS attempts to construct sets of tokens for error  reporting--
  4915. error  sets.  The sets are created wherever a parsing decision will be
  4916. made in the generated parser.  At every point in the  parsing  process
  4917. there  exists  a  set  of currently recognizable/acceptable terminals.
  4918. This set can be decoded  and  printed  out  when  a  syntax  error  is
  4919. detected  -  when  the  current  token  is not currently recognizable.
  4920. PCCTS attempts to replace subsets of all error sets with error classes
  4921. defined  by  the  user.   For example, rule a below contains a subrule
  4922. with more than one alternative which implies that a  parsing  decision
  4923. will be required at run-time to determine which alternative to choose.
  4924.  
  4925.  
  4926.  
  4927.  
  4928. a   :  (Happy | Sad | Funny | Carefree) Person ;
  4929.  
  4930.  
  4931.  
  4932. If, upon entering rule a, the current token is not  one  of  the  four
  4933. terminals found in the alternatives, a syntax error will have occurred
  4934. and the following message  would  be  generated  (if  "huh"  were  the
  4935. current token):
  4936.  
  4937.  
  4938.  
  4939.  
  4940. syntax error at "huh" missing { Happy Sad Funny Carefree }
  4941.  
  4942.  
  4943.  
  4944. Let us define an error class called Adjective that groups  those  same
  4945. four tokens together.
  4946.  
  4947.  
  4948.  
  4949.  
  4950. #errclass Adjective { Happy Sad Funny Carefree }
  4951.  
  4952.  
  4953.  
  4954. Now, the error message would be:
  4955.  
  4956.  
  4957.  
  4958.  
  4959.                                                                Page 79
  4960.  
  4961. PCCTS 1.00
  4962.  
  4963.  
  4964.  
  4965.  
  4966.  
  4967.  
  4968. syntax error at "huh" missing { Adjective }
  4969.  
  4970.  
  4971.  
  4972.      PCCTS repeatedly trys to replace subsets of the error  set  until
  4973. no more substitutions can be made.  At each replacement iteration, the
  4974. largest error class that is completely contained within the error  set
  4975. is  substituted  for  that group of tokens.  One replacement iteration
  4976. may perform some substitution that makes another, previously inviable,
  4977. substitution  possible.  This allows the hierarchy mechanism described
  4978. above in the error class description section.  The sequence of substi-
  4979. tutions for the yum example would be:
  4980.  
  4981.  
  4982.  
  4983.  
  4984. [i]     { CHERRY APPLE COW PIG THE }
  4985. [ii]    { Fruit COW PIG THE }
  4986. [iii]   { Fruit Meat THE }
  4987. [iv]    { "stuff you can eat" THE }
  4988.  
  4989.  
  4990.  
  4991.      The error class mechanism leads to smaller error sets and can  be
  4992. used to provide more informative error messages.
  4993.  
  4994. 6.  Things you should know about
  4995.  
  4996.      This section is a collection of important  things  that  did  not
  4997. properly belong in any other section.
  4998.  
  4999. 6.1.  Available program symbols
  5000.  
  5001.      This section describes all symbols visible to the user  that  may
  5002. be of interest.
  5003.  
  5004. 6.1.1.  Macros, functions, #define's
  5005.  
  5006.  
  5007.  
  5008.  
  5009.  
  5010.  
  5011.  
  5012.  
  5013.  
  5014.  
  5015.  
  5016.  
  5017.  
  5018.  
  5019.  
  5020.  
  5021.                                                                Page 80
  5022.  
  5023. PCCTS 1.00
  5024.  
  5025.  
  5026.  
  5027.  
  5028.  
  5029.  
  5030. ZZCOL                 /* define so that DLG tracks column # of tokens */
  5031. ZZLEXBUFSIZE          /* if not set, default size of lexical bufs */
  5032. ZZA_STACKSIZE         /* if not set, default size of attrib stack */
  5033. ZZAST_STACKSIZE       /* if not set, default size of AST stack */
  5034. zzTRACE(rule)         /* macro called at start of rule when -gd set */
  5035. LL_K                  /* == max # tokens of look-ahead used in parser */
  5036. ANTLR(start,stream)   /* ANTLR startup macro; get input from stream */
  5037. ANTLRf(start,funcPtr) /* ANTLR startup macro; get input from func */
  5038. zzcr_attr()           /* create attribute from token, text on input */
  5039. zzd_attr()            /* call zzd_attr(&($i)) for each attrib created */
  5040. zzcr_ast()            /* how to create an AST node from attribute */
  5041. zzmk_ast()            /* how to create an AST node (user-defined) */
  5042. zzd_ast()             /* how to destroy an AST node */
  5043. LA(i)                 /* ith token of look-ahead */
  5044. LATEXT(i)             /* text for ith token of look-ahead */
  5045. zzlextext             /* buffer holding text of current token */
  5046. zzsyn()               /* error reporting macro */
  5047. zzpre_ast(tree, func1, func2, func3) /* see section 4.2.5 */
  5048. zzfree_ast(tree)      /* see section 4.2.5 */
  5049. zzdup_ast(tree)       /* see section 4.2.5 */
  5050. zzedecode(unsigned *error_set); /* decode a bit-set */
  5051. zzskip()              /* Tell DLG to skip this token */
  5052. zzmore()              /* Tell DLG to try for more chars */
  5053. zzmode(mode)          /* switch DLG to another lex mode */
  5054. zzadvance()           /* Get next char allow only valid chars */
  5055. zzrdstream(s)         /* Reset lex_line, use stream s for input */
  5056. zzrdfunc(f)           /* Reset lex_line, call function f to read input */
  5057. zzreplchar(c)         /* replace current lex buffer with c */
  5058. zzreplstr(s)          /* replace current lex buffer with s */
  5059.  
  5060.  
  5061.  
  5062. 6.1.2.  Global variables
  5063.  
  5064.  
  5065.  
  5066.  
  5067. char    *zztokens[],  /* zztokens[t] is rexpr or label for token t */
  5068.         *zzbegexpr,   /* start of text for currently recognized expr */
  5069.         *zzendexpr;   /* end of text for currently recognized expr */
  5070. int     zzline,       /* set by user to current line # */
  5071.         zzbegcol,     /* column # of 1st char in token */
  5072.         zzendcol,     /* column # of last char in token */
  5073.         zzchar;       /* current character of look-ahead */
  5074. void    (*zzerr)();   /* ptr to func to exec upon lexical error */
  5075.  
  5076.  
  5077.  
  5078. One of the most common actions found among  PCCTS  descriptions  is  a
  5079. statement similar to
  5080.  
  5081.  
  5082.  
  5083.                                                                Page 81
  5084.  
  5085. PCCTS 1.00
  5086.  
  5087.  
  5088.  
  5089.  
  5090.  
  5091.  
  5092. #token "\n"    << zzline++; >>    /* Move to next line */
  5093.  
  5094.  
  5095.  
  5096. 6.2.  ANSI versus K&R
  5097.  
  5098.      K&R,  actually  Kernighan  and  Ritchie,   "The   C   Programming
  5099. Language," Prentice-Hall, 1978, was effectively the standard for the C
  5100. language until the ANSI X3-J11 committee put  forth  a  definition  of
  5101. ANSI  C  [ANS90].  Unfortunately, ANSI C is not compatible with K&R C,
  5102. yet both dialects are in common use.  For this reason, PCCTS  supports
  5103. generation of either ANSI C or K&R C.
  5104.  
  5105.      By default, PCCTS generates K&R C code with parameterless  extern
  5106. declarations  automatically  placed in tokens.h for each parsing func-
  5107. tion that has a return value.  If the -ga command-line option is  used
  5108. (on  both  ANTLR  and DLG), PCCTS generates ANSI C compatible code and
  5109. function prototype declarations; all  parsing  functions  with  return
  5110. values  or parameter definitions have appropriate prototypes placed in
  5111. tokens.h.
  5112.  
  5113.      According to the ANSI  C  standard,  a  compliant  compiler  must
  5114. define  the macro name __STDC__, which would not be defined by a K&R C
  5115. compiler.  Hence, code can be written to work correctly with both ANSI
  5116. C  and  K&R  C  by  using #ifdef to test if __STDC__ has been defined.
  5117. Although the output of PCCTS would  have  been  excessively  large  if
  5118. #ifdef had been used to make the code be acceptable to both ANSI C and
  5119. K&R C compilers, #include files and other support code  may  test  for
  5120. the macro __STDC__.
  5121.  
  5122. 6.3.  Bugs
  5123.  
  5124.      Occasionally, PCCTS will find a grammar that  it  cannot  analyze
  5125. and you will receive an error similar to the following.
  5126.  
  5127.  
  5128.  
  5129.  
  5130. file.c, line 43: out of memory while analyzing alts 2 and 5 of (..)+
  5131.  
  5132.  
  5133.  
  5134. This is due to LL(k) grammar analysis requiring exponential  space  in
  5135. some  cases.   Normally,  this  problem only will occur with k > 2 for
  5136. large, ambiguous, grammars.  A technique which avoids  the  worst-case
  5137. exponential  space  requirement  is  being  considered  for  a  future
  5138. release.
  5139.  
  5140.      Although not technically  a  "bug,"  the  differences  between  B
  5141. release  PCCTS  and  version  1.00  will  cause  numerous errors to be
  5142.  
  5143.  
  5144.  
  5145.                                                                Page 82
  5146.  
  5147. PCCTS 1.00
  5148.  
  5149.  
  5150. reported if old grammars are submitted to the  new  system.   Most  of
  5151. these  incompatibilities  require only minor changes; see section 7.1.
  5152. This was expected - why do you think we called it B?
  5153.  
  5154.      The code generated using the -ga option has not been  tested  for
  5155. compliance with the ANSI C standard.
  5156.  
  5157.      The source code for ANTLR itself is not ANSI compliant,  although
  5158. it is fairly close.
  5159.  
  5160.      Error messages reporting ambiguities involving nullable  subrules
  5161. (i.e.,  {}  or  ()*)  sometime  blame  the ambiguity on an alternative
  5162. rather than the nullable construct.
  5163.  
  5164.      The names of PCCTS variables and/or functions are not necessarily
  5165. consistent,  mnemonic  or  convenient.   PCCTS symbols are, therefore,
  5166. subject to change.
  5167.  
  5168.      ANTLR will not compile on any system that does not have _iobuf as
  5169. the  standard  FILE * structure name.  This is because struct _iobuf *
  5170. is used in a header file  instead  of  FILE *.   The  header  file  is
  5171. automatically  generated  via  proto--the  C  example distributed with
  5172. PCCTS.  You can circumvent this problem by changing the declaration of
  5173. struct _iobuf * in proto.h to FILE *.
  5174.  
  5175.      ANTLR normally checks to see that you do not reference an  attri-
  5176. bute  (parameter, return value, normal attribute) that is not defined.
  5177. However, if you use a $name where name  is  a  substring  of  a  valid
  5178. parameter or return value, it thinks that it is ok.
  5179.  
  5180.      Invoking an ANTLR parser  multiple  times  or  invoking  multiple
  5181. parsers does not work very well; tokens tend to be lost.
  5182.  
  5183. 7.  History
  5184.  
  5185.      PCCTS Version 1.00 was written  using  B  release  PCCTS -  1.0B.
  5186. 1.0B  was,  in  turn,  written in alpha release PCCTS, 1.0A, which was
  5187. written in YUCC (a graduate class project gone wild).  YUCC was  writ-
  5188. ten  in  PG;  both  of  which  were simple BNF-style recursive descent
  5189. parser generators.  PG was written in RD [JuD84].
  5190.  
  5191. 7.1.  Differences from B release PCCTS
  5192.  
  5193.      PCCTS Version 1.00 is  significantly  different  from  B  release
  5194. PCCTS.  However, Version 1.00 is mostly a superset - most old grammars
  5195. require only minor changes for version 1.00.  This section  delineates
  5196. all of the changes and a few possible migration paths.
  5197.  
  5198. o    #attrib is now called #header to reflect the more general use  of
  5199.      the construct in version 1.00.
  5200.  
  5201. o    The ANTLR initiation macro now requires that  the  starting  rule
  5202.      have  ()  appended  just  as you would call the function by hand.
  5203.      For example, ANTLR(start(), stdin).
  5204.  
  5205.  
  5206.  
  5207.                                                                Page 83
  5208.  
  5209. PCCTS 1.00
  5210.  
  5211.  
  5212. o    A number of internal functions and variables have been renamed so
  5213.      that  conflicts with user-defined names are less likely.  All the
  5214.      new names begin with the prefix zz.  For example:
  5215.  
  5216.      o    aCreate() is now zzcr_attr().
  5217.  
  5218.      o    cur_char is now called zzchar, but the user should not  need
  5219.           to reference it.
  5220.  
  5221.      o    LexSkip and LexMore are now zzskip and zzmore.
  5222.  
  5223. o    Token is now called LA(1) (first token of look-ahead).  LA(i)  is
  5224.      the ith token.
  5225.  
  5226. o    LexText is now LATEXT(1) (text for first  token  of  look-ahead).
  5227.      LATEXT(i) is the text for the ith token.
  5228.  
  5229. o    ANTLRi no longer exists.
  5230.  
  5231. o    Rules no longer  automatically  define  an  attribute  parameter.
  5232.      Also,  parameters  of the form {...} (i.e. rule[{...}]) cannot be
  5233.      used.  Basically, parameter passing to a rule is exactly like  in
  5234.      a  programming  language.  All parameters must be defined and can
  5235.      be any valid type.  Also, return values may be defined for  rules
  5236.      rather  than  using old-style upward attributes.  Rules may simu-
  5237.      late the old-style $0 inheritance via
  5238.  
  5239.  
  5240.  
  5241.  
  5242.      rule[Attrib inh] : <<$0 = inh;>> ... ;
  5243.  
  5244.  
  5245.  
  5246. o    A new file called mode.h is created by DLG and is  included  into
  5247.      your  ANTLR parser.  This implies that DLG must be run before you
  5248.      can compile the C files created by ANTLR.
  5249.  
  5250. o    New command-line  options  have  appeared,  old  ones  have  been
  5251.      changed and/or disappeared.  To be precise,
  5252.  
  5253.  
  5254.      -T   is now -gd.
  5255.  
  5256.      -z   is gone.
  5257.  
  5258.      -n   is now -gx.
  5259.  
  5260.      -l   is now -fl.
  5261.  
  5262.      -c   is now -gc.
  5263.  
  5264.      -I   is gone.
  5265.  
  5266.  
  5267.  
  5268.  
  5269.                                                                Page 84
  5270.  
  5271. PCCTS 1.00
  5272.  
  5273.  
  5274.      -s   is gone.
  5275.  
  5276.      -fi  is gone.
  5277.  
  5278.      -fo  is gone.
  5279.  
  5280.      -R   is now -cr.
  5281.  
  5282.      -e   is gone.
  5283.  
  5284.      -a   is gone.
  5285.  
  5286.      -w   is now one of -e1, -e2, -e3.
  5287.  
  5288.      -d   is gone.
  5289.  
  5290.      -E   is gone since the user can redefine zzsyn().
  5291.  
  5292. o    zzreplchar() and zzreplstr() should be used instead of  modifying
  5293.      the lexical buffer manually.
  5294.  
  5295. o    A pointer to a function called zzerr is set to a function to call
  5296.      upon lexical error (invalid token etc...).
  5297.  
  5298. 7.2.  Future directions
  5299.  
  5300.      Neither we nor Purdue University guarantee that  PCCTS  works  or
  5301. accept  liability  if it does not do what you want it to.  However, we
  5302. do try to maintain and improve the system.  So, we value user feedback
  5303. that might help us improve PCCTS.
  5304.  
  5305.      Within Purdue University's School of Electrical  Engineering,  we
  5306. are  constantly updating PCCTS.  The 1.00 release does not include all
  5307. the latest goodies - it contains only those features whose implementa-
  5308. tion  we  believe  to  be useful, correct, and reasonably stable.  The
  5309. following is a partial  list  of  improvements  currently  being  con-
  5310. sidered:
  5311.  
  5312. Parser construction
  5313.      Currently, ANTLR parsers use a sequence of if statements to  find
  5314.      the  correct  alternative  to match.  This is inefficient if only
  5315.      one token of look-ahead is required to uniquely  determine  which
  5316.      alternative  to  choose.   Depending  on the C compiler, a switch
  5317.      statement would generate much faster code.
  5318.  
  5319.      Attribute and AST variables are maintained on software stacks  in
  5320.      1.00.  Grammar analysis could easily create a collection of local
  5321.      hardware-stack-based variables to use in place  of  the  software
  5322.      stack.   This would eliminate the need to specify an attribute or
  5323.      AST stack size and produce faster code.
  5324.  
  5325. Inline rules
  5326.      For the most part, subrules are like macro-expansions  of  rules.
  5327.      Rather  than referencing a rule, the user simply instantiates the
  5328.  
  5329.  
  5330.  
  5331.                                                                Page 85
  5332.  
  5333. PCCTS 1.00
  5334.  
  5335.  
  5336.      rule in place of  the  rule  reference.   Grammatically  the  two
  5337.      methods  are  the  same,  but  they differ in two important ways.
  5338.      First, subrules cannot employ the sophisticated parameter passing
  5339.      mechanism  available  to rules.  Second, subrules are much faster
  5340.      than rule references since subrules avoid the function call over-
  5341.      head.   A  future  version of PCCTS might introduce inline rules.
  5342.      Inline rules would be defined as before (with the addition of the
  5343.      inline  keyword) but would be instantiated into rules that refer-
  5344.      ence them.  This would cut down on grammar clutter by breaking up
  5345.      long rules while maintaining the speed advantage of subrules.
  5346.  
  5347. Abstract-syntax-trees
  5348.      Through experience with PCCTS AST's, a new group of tree  manipu-
  5349.      lation  routines  should  appear.   Some  of them could relate to
  5350.      code-generation.
  5351.  
  5352. Example grammars
  5353.      More and more grammars are being built with PCCTS.  Some of  them
  5354.      might be made available through future PCCTS releases and through
  5355.      users' network postings.
  5356.  
  5357. Recognition
  5358.      Currently, PCCTS parsers cannot recognize as  large  a  class  of
  5359.      languages  as  bottom-up parsers.  Research is underway to create
  5360.      hybrid parsers that would retain top-down's  programmer-interface
  5361.      features while gaining bottom-up's recognition strength.
  5362.  
  5363. Code generation
  5364.      Research continues at Purdue toward  a  code-generator  generator
  5365.      for parallel machines (PIG).
  5366.  
  5367.      A simple uni-processor code-generator that has  been  in  use  at
  5368.      Purdue may be made available in the next release of PCCTS.
  5369.  
  5370. $tokenPCCTS only  recognizes  $i,  $i.j,  $rule  variables  presently.
  5371.      Future  versions might allow $token variables which will refer to
  5372.      attributes for tokens by the name of the token not  the  position
  5373.      number.
  5374.  
  5375. 7.3.  Acknowledgements
  5376.  
  5377.      Thanks is due to the users of B release PCCTS for their excellent
  5378. suggestions.  In particular, Mark Nichols (PhD candidate in Electrical
  5379. Engineering at Purdue) discovered many of the initial quirks and bugs.
  5380. We acknowledge Dana Hoggatt (Micro Data Base Systems Inc) for his idea
  5381. of error grouping (strings attached to non-terminals) and his signifi-
  5382. cant  software  testing  efforts.   Thanks  is  due  Professor Matthew
  5383. O'Keefe and Peter Dahl (both at University  of  Minnesota)  for  their
  5384. review  of  the  user's  manual  and  their bug-finding escapades into
  5385. PCCTS.
  5386.  
  5387.  
  5388.  
  5389.  
  5390.  
  5391.  
  5392.  
  5393.                                                                Page 86
  5394.  
  5395. PCCTS 1.00
  5396.  
  5397.  
  5398. 8.  References
  5399.  
  5400. [ANS90]
  5401.      American National Standard for Information Systems,  "Programming
  5402.      Language C," Document X3J11/90-013, February 1990.
  5403.  
  5404. [AhU79]
  5405.      A.V. Aho, J.D. Ullman, Principles of  Compiler  Design,  Addison-
  5406.      Wesley Publishing Company, Reading, Massachusetts, 1979.
  5407.  
  5408. [DoP90]
  5409.      H. Dobler and K. Pirklbauer, "Coco-2 A  New  Compiler  Compiler,"
  5410.      ACM SIGPLAN Notices, Vol. 25, No. 5, May 1990.
  5411.  
  5412. [Joh78]
  5413.      Stephen C. Johnson, "Yacc: Yet Another  Compiler-Compiler,"  Bell
  5414.      Laboratories, Murray Hill, NJ, 1978.
  5415.  
  5416. [JuD84]
  5417.      R. Juels, H. Dietz, S. Arbeeny, J. Patane,  E.  Tepe,  "Automatic
  5418.      Translation  Systems,"  Study Report, Center For Digital Systems,
  5419.      Department of Electrical Engineering and  Computer  Science,  The
  5420.      Polytechnic Institute of New York, New York, 1984.
  5421.  
  5422. [KeR88]
  5423.      Brian W. Kernighan and Dennis  M.  Ritchie,  "The  C  programming
  5424.      Language,"  Prentice  Hall  Inc.,  Englewood  Cliffs, New Jersey,
  5425.      1988.
  5426.  
  5427. [Les75]
  5428.      M. E. Lesk, "LEX--a Lexical Analyzer  Generator,"  CSTR  39  Bell
  5429.      Laboratories, Murray Hill, NJ, 1975.
  5430.  
  5431. [LeP81]
  5432.      Harry R. Lewis, Christos H. Papadimitriou, Elements of the Theory
  5433.      of  Computation,  Prentice Hall, Inc., Englewood Cliffs, New Jer-
  5434.      sey, 1981.
  5435.  
  5436. [Nau63]
  5437.      P. Naur (ed.), "Revised report on the algorithmic language  ALGOL
  5438.      60," Communications of the ACM 6:1, 1-17.
  5439.  
  5440. [PaD90]
  5441.      Terence  Parr,  Henry  Dietz,  Will  Cohen,   "Purdue   Compiler-
  5442.      Construction  Tool  Set," Technical Report TR-EE 90-14, School Of
  5443.      Electrical Engineering, Purdue University,  West  Lafayette,  IN,
  5444.      February 1990.
  5445.  
  5446. [Par90]
  5447.      Terence Parr, "The Analysis of Extended BNF Grammars and the Con-
  5448.      struction of LL(1) Parsers," Technical Report TR-EE 90-30, School
  5449.      Of Electrical Engineering, Purdue University, West Lafayette, IN,
  5450.      May 1990.
  5451.  
  5452.  
  5453.  
  5454.  
  5455.                                                                Page 87
  5456.  
  5457. PCCTS 1.00
  5458.  
  5459.  
  5460. [PuC89]
  5461.      James J. Purtilo and John R. Callahan, "Parse-Tree  Annotations",
  5462.      Communications of the ACM, Vol. 32, No. 12, December 1989.
  5463.  
  5464. [Str87]
  5465.      Bjarne Stroustrup, "The C++ Programming Language," Addison-Wesley
  5466.      Publishing Company, Reading, Massachusetts, 1987.
  5467.  
  5468. [Wir76]
  5469.      Niklaus Wirth, Algorithms + Data Structures = Programs,  Prentice
  5470.      Hall, Inc., Englewood Cliffs, New Jersey, 1976.
  5471.  
  5472. Notes:[LeP81] credits P. Naur [Nau63] with Backus-Naur Form (BNF)  and
  5473.      is  a reasonable text on language theory.  [AhU79] gave more com-
  5474.      plete references to Johnson's YACC and Lesk's LEX - i.e. the CSTR
  5475.      numbers from Bell Laboratories.
  5476.  
  5477.  
  5478.  
  5479.  
  5480.  
  5481.  
  5482.  
  5483.  
  5484.  
  5485.  
  5486.  
  5487.  
  5488.  
  5489.  
  5490.  
  5491.  
  5492.  
  5493.  
  5494.  
  5495.  
  5496.  
  5497.  
  5498.  
  5499.  
  5500.  
  5501.  
  5502.  
  5503.  
  5504.  
  5505.  
  5506.  
  5507.  
  5508.  
  5509.  
  5510.  
  5511.  
  5512.  
  5513.  
  5514.  
  5515.  
  5516.  
  5517.  
  5518.  
  5519. PCCTS 1.00
  5520.  
  5521.  
  5522.  
  5523.  
  5524.  
  5525.                           Table of Contents
  5526.  
  5527.  
  5528.  
  5529.  
  5530. 1. Introduction .................................................    1
  5531.  
  5532.          1.1. PCCTS programming interface .......................    2
  5533.  
  5534.          1.2. PCCTS information flow ............................    3
  5535.  
  5536.          1.3. PCCTS file(s) format ..............................    3
  5537.  
  5538.          1.4. Makefile template .................................    5
  5539.  
  5540.          1.5. PCCTS component command-line options ..............    6
  5541.  
  5542.          1.6. Introductory example ..............................   10
  5543.  
  5544. 2. Lexical analysis and token definition ........................   13
  5545.  
  5546.          2.1. Token Labeling and token actions ..................   13
  5547.  
  5548.          2.2. Lexical actions via #lexaction ....................   16
  5549.  
  5550.          2.3. Multiple lexical classes ..........................   16
  5551.  
  5552.                   2.3.1. Multiple grammars, multiple lexical
  5553. analyzers .......................................................   17
  5554.  
  5555.                   2.3.2. Single grammar, multiple lexical
  5556. analyzers .......................................................   18
  5557.  
  5558.          2.4. Handling end of input .............................   18
  5559.  
  5560.          2.5. Token order and lexical ambiguities ...............   19
  5561.  
  5562.          2.6. Quoted tokens .....................................   19
  5563.  
  5564.          2.7. Interactive lexical analyzers .....................   21
  5565.  
  5566.          2.8. DLG lexical input .................................   21
  5567.  
  5568.          2.9. Tracking pattern position .........................   22
  5569.  
  5570. 3. Syntactic analysis ...........................................   22
  5571.  
  5572.          3.1. PCCTS rule definitions ............................   23
  5573.  
  5574.                   3.1.1. Subrules ...............................   24
  5575.  
  5576.  
  5577.  
  5578.  
  5579.  
  5580.  
  5581. PCCTS 1.00
  5582.  
  5583.  
  5584.                   3.1.2. Rule communication .....................   25
  5585.  
  5586.                   3.1.3. Miscellaneous notes ....................   27
  5587.  
  5588.                   3.1.4. LL(k) parsing ..........................   28
  5589.  
  5590.          3.2. Grammar ambiguities ...............................   28
  5591.  
  5592.          3.3. Look-ahead size ...................................   30
  5593.  
  5594.          3.4. ANTLR parser construction .........................   30
  5595.  
  5596.                   3.4.1. Efficiency .............................   31
  5597.  
  5598.                   3.4.2. Debugging parsers ......................   32
  5599.  
  5600.          3.5. PCCTS parser template .............................   32
  5601.  
  5602.          3.6. Grammatical actions ...............................   34
  5603.  
  5604.                   3.6.1. Init Actions ...........................   34
  5605.  
  5606.                   3.6.2. Fail actions ...........................   35
  5607.  
  5608.                   3.6.3. Actions appearing outside of rules .....   36
  5609.  
  5610. 4. Attribute handling ...........................................   37
  5611.  
  5612.          4.1. General attribute handling ........................   37
  5613.  
  5614.                   4.1.1. Attribute creation .....................   38
  5615.  
  5616.                   4.1.2. Attribute destruction ..................   40
  5617.  
  5618.                   4.1.3. Standard attribute definitions .........   41
  5619.  
  5620.                   4.1.4. Attribute references ...................   42
  5621.  
  5622.                            4.1.4.1. $i references ...............   43
  5623.  
  5624.                            4.1.4.2. $i.j references .............   44
  5625.  
  5626.                            4.1.4.3. $label references ...........   45
  5627.  
  5628.                   4.1.5. $[token, text] attribute constructor
  5629.  
  5630.                   4.1.6. Inheritance ............................   47
  5631.  
  5632.                            4.1.6.1. $0 inheritance ..............   47
  5633.  
  5634.                            4.1.6.2. Generalized rule communi-
  5635. cation ..........................................................   48
  5636.  
  5637.                                     4.1.6.2.1. Downward-
  5638.  
  5639.  
  5640.  
  5641.  
  5642.  
  5643. PCCTS 1.00
  5644.  
  5645.  
  5646. inheritance .....................................................   48
  5647.  
  5648.                                     4.1.6.2.2. Upward-
  5649. inheritance .....................................................   50
  5650.  
  5651.          4.2. Abstract-syntax-tree construction and manipula-
  5652. tion ............................................................   50
  5653.  
  5654.                   4.2.1. AST node creation ......................   51
  5655.  
  5656.                   4.2.2. AST node destruction ...................   54
  5657.  
  5658.                   4.2.3. Automatic AST construction .............   55
  5659.  
  5660.                            4.2.3.1. Grammar annotation ..........   55
  5661.  
  5662.                            4.2.3.2. Operator precedence .........   57
  5663.  
  5664.                            4.2.3.3. Example .....................   58
  5665.  
  5666.                   4.2.4. Explicit AST construction ..............   61
  5667.  
  5668.                            4.2.4.1. Simple example ..............   62
  5669.  
  5670.                            4.2.4.2. C declaration to English
  5671. translator ......................................................   64
  5672.  
  5673.                   4.2.5. Tree manipulation routines .............   69
  5674.  
  5675.                   4.2.6. AST references .........................   71
  5676.  
  5677.                   4.2.7. Invoking parsers that construct trees
  5678.  
  5679.                   4.2.8. Error recovery and AST's ...............   73
  5680.  
  5681. 5. Error detection and repair ...................................   73
  5682.  
  5683.          5.1. Modifying grammars to recognize common syntax
  5684. errors ..........................................................   74
  5685.  
  5686.          5.2. Default error reporting function ..................   75
  5687.  
  5688.          5.3. Error groups ......................................   75
  5689.  
  5690.          5.4. Error token classes ...............................   76
  5691.  
  5692.                   5.4.1. Error class definitions ................   77
  5693.  
  5694.                   5.4.2. Error class utilization ................   79
  5695.  
  5696. 6. Things you should know about .................................   80
  5697.  
  5698.          6.1. Available program symbols .........................   80
  5699.  
  5700.  
  5701.  
  5702.  
  5703.  
  5704.  
  5705. PCCTS 1.00
  5706.  
  5707.  
  5708.                   6.1.1. Macros, functions, #define's ...........   80
  5709.  
  5710.                   6.1.2. Global variables .......................   81
  5711.  
  5712.          6.2. ANSI versus K&R ...................................   82
  5713.  
  5714.          6.3. Bugs ..............................................   82
  5715.  
  5716. 7. History ......................................................   83
  5717.  
  5718.          7.1. Differences from B release PCCTS ..................   83
  5719.  
  5720.          7.2. Future directions .................................   85
  5721.  
  5722.          7.3. Acknowledgements ..................................   86
  5723.  
  5724. 8. References ...................................................   87
  5725.  
  5726.  
  5727.  
  5728.  
  5729.  
  5730.  
  5731.  
  5732.  
  5733.  
  5734.  
  5735.  
  5736.  
  5737.  
  5738.  
  5739.  
  5740.  
  5741.  
  5742.  
  5743.  
  5744.  
  5745.  
  5746.  
  5747.  
  5748.  
  5749.  
  5750.  
  5751.  
  5752.  
  5753.  
  5754.  
  5755.  
  5756.  
  5757.  
  5758.  
  5759.  
  5760.  
  5761.  
  5762.  
  5763.  
  5764.  
  5765.  
  5766.  
  5767.