]> pd.if.org Git - pccts/commitdiff
auto commit for import
authorTerence Parr <>
Fri, 6 Oct 1995 00:39:58 +0000 (19:39 -0500)
committerNathan Wagner <nw@hydaspes.if.org>
Sun, 26 Feb 2017 02:16:52 +0000 (20:16 -0600)
antlr/generic.h [new file with mode: 0755]
antlr/globals.c [new file with mode: 0755]
antlr/hash.c [new file with mode: 0755]
antlr/lex.c [new file with mode: 0755]
antlr/main.c [new file with mode: 0755]
antlr/misc.c [new file with mode: 0755]
antlr/pred.c [new file with mode: 0755]

diff --git a/antlr/generic.h b/antlr/generic.h
new file mode 100755 (executable)
index 0000000..68fd4d2
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * generic.h -- generic include stuff for new PCCTS ANTLR.
+ *
+ * $Id: generic.h,v 1.2 95/06/15 18:06:55 parrt Exp $
+ * $Revision: 1.2 $
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#define StrSame                        0
+
+#define DefaultParserName      "zzparser"
+
+#define ZZLEXBUFSIZE 4000
+
+/* Tree/FIRST/FOLLOW defines -- valid only after all grammar has been read */
+#define ALT                    TokenNum+1
+#define SET                    TokenNum+2
+#define TREE_REF       TokenNum+3
+
+                                       /* E r r o r  M a c r o s */
+
+#define fatal(err)     fatalFL(err, __FILE__, __LINE__)
+#define fatal_internal(err)    fatal_intern(err, __FILE__, __LINE__)
+
+
+#define eMsg1(s,a)     eMsg3(s,a,NULL,NULL)
+#define eMsg2(s,a,b)   eMsg3(s,a,b,NULL)
+
+                               /* S a n i t y  C h e c k i n g */
+
+#ifndef require
+#define require(expr, err) {if ( !(expr) ) fatal_internal(err);}
+#endif
+
+                                       /* L i s t  N o d e s */
+
+typedef struct _ListNode {
+                       void *elem;                     /* pointer to any kind of element */
+                       struct _ListNode *next;
+               } ListNode;
+
+/* Define a Cycle node which is used to track lists of cycles for later
+ * reconciliation by ResolveFoCycles().
+ */
+typedef struct _c {
+                       int croot;                      /* cycle root */
+                       set cyclicDep;          /* cyclic dependents */
+                       unsigned deg;           /* degree of FOLLOW set of croot */
+               } Cycle;
+
+typedef struct _e {
+                       int tok;                        /* error class name == TokenStr[tok] */
+                       ListNode *elist;        /* linked list of elements in error set */
+                       set eset;
+                       int setdeg;                     /* how big is the set */
+                       int lexclass;           /* which lex class is it in? */
+               } ECnode;
+
+typedef struct _TCnode {
+                       int tok;                        /* token class name */
+                       ListNode *tlist;        /* linked list of elements in token set */
+                       set tset;
+                       int lexclass;           /* which lex class is it in? */
+                       unsigned char dumped; /* this def has been been dumped */
+                       unsigned setnum;        /* which set number is this guy? (if dumped) */
+               } TCnode;
+
+typedef struct _ft {
+                       char *token;            /* id of token type to remap */
+                       int tnum;                       /* move token type to which token position */
+               } ForcedToken;
+
+#define newListNode    (ListNode *) calloc(1, sizeof(ListNode));
+#define newCycle       (Cycle *) calloc(1, sizeof(Cycle));
+#define newECnode      (ECnode *) calloc(1, sizeof(ECnode));
+#define newTCnode      (TCnode *) calloc(1, sizeof(TCnode));
+
+
+                               /* H a s h  T a b l e  E n t r i e s */
+
+typedef struct _t {                            /* Token name or expression */
+                       char *str;
+                       struct _t *next;
+                       int token;                      /* token number */
+                       unsigned char classname;        /* is it a err/tok class name or token */
+                       TCnode *tclass;         /* ptr to token class */
+                       char *action;
+               } TermEntry;
+
+typedef struct _r {                            /* Rule name and ptr to start of rule */
+                       char *str;
+                       struct _t *next;
+                       int rulenum;            /* RulePtr[rulenum]== ptr to RuleBlk junction */
+                       unsigned char noAST;/* gen AST construction code? (def==gen code) */
+                       char *egroup;           /* which error group (err reporting stuff) */
+                       ListNode *el_labels;/* list of element labels ref in all of rule */
+            unsigned char has_rule_exception;
+               } RuleEntry;
+
+typedef struct _f {                            /* cache Fi/Fo set */
+                       char *str;                      /* key == (rulename, computation, k) */
+                       struct _f *next;
+                       set fset;                       /* First/Follow of rule */
+                       set rk;                         /* set of k's remaining to be done after ruleref */
+                       int incomplete;         /* only w/FOLLOW sets.  Use only if complete */
+               } CacheEntry;
+
+typedef struct _LabelEntry {   /* element labels */
+                       char *str;
+                       struct _f *next;
+                       Node *elem;                     /* which element does it point to? */
+                       ExceptionGroup *ex_group;
+                                                               /* Is there an exception attached to label? */
+               } LabelEntry;
+
+typedef struct _SignalEntry {
+                       char *str;
+                       struct _f *next;
+                       int signum;                     /* unique signal number */
+               } SignalEntry;
+
+#define newTermEntry(s)                (TermEntry *) newEntry(s, sizeof(TermEntry))
+#define newRuleEntry(s)                (RuleEntry *) newEntry(s, sizeof(RuleEntry))
+#define newCacheEntry(s)       (CacheEntry *) newEntry(s, sizeof(CacheEntry))
+#define newLabelEntry(s)       (LabelEntry *) newEntry(s, sizeof(LabelEntry))
+#define newSignalEntry(s)      (SignalEntry *) newEntry(s, sizeof(SignalEntry))
+
+
+typedef struct _UserAction {
+                       char *action;
+                       int file, line;
+               } UserAction;
+
+
+                                       /* L e x i c a l  C l a s s */
+
+/* to switch lex classes, switch ExprStr and Texpr (hash table) */
+typedef struct _lc {
+                       char *classnum, **exprs;
+                       Entry **htable;
+               } LClass;
+
+typedef struct _exprOrder {
+                       char *expr;
+                       int lclass;
+               } Expr;
+
+
+typedef Graph Attrib;
+
+                                               /* M a x i m u m s */
+
+#ifndef HashTableSize
+#define HashTableSize  253
+#endif
+#ifndef StrTableSize
+#define StrTableSize   15000   /* all tokens, nonterminals, rexprs stored here */
+#endif
+#define MaxLexClasses  50              /* how many automatons */
+/* TokenStart and EofToken are ignored if #tokdefs meta-op is used */
+#define TokenStart             2               /* MUST be in 1 + EofToken */
+#define EofToken               1               /* Always predefined to be 1 */
+#define MaxNumFiles            20
+#define MaxFileName            300             /* largest file name size */
+#define MaxRuleName            100             /* largest rule name size */
+#define TSChunk                        100             /* how much to expand TokenStr/ExprStr each time */
+#define TIChunk                        TSChunk /* expand TokenInd by same as TokenStr to mirror them */
+#define FoStackSize            100             /* deepest FOLLOW recursion possible */
+
+#define NumPredefinedSignals 3
+
+           /* S t a n d a r d  S i g n a l s */
+
+#define sigNoSignal                            0
+#define sigMismatchedToken             1
+#define sigNoViableAlt                 2
+#define sigNoSemViableAlt              3
+
+
+
+/* AST token types */
+#define ASTexclude             0
+#define ASTchild               1
+#define ASTroot                        2
+#define ASTinclude             3               /* include subtree made by rule ref */
+
+
+#define PredictionVariable                             "zzpr_expr"
+#define PredictionLexClassSuffix               "_zzpred"
+
+#define WildCardString                                 "WildCard"
+
+#ifndef ANTLRm
+#define ANTLRm(st, f, _m)      zzbufsize = ZZLEXBUFSIZE;\
+                                               zzmode(_m);                                     \
+                                               zzenterANTLR(f);                        \
+                                               st; ++zzasp;                            \
+                                               zzleaveANTLR(f);
+#endif                                         
+
+#include "proto.h"
+#include "config.h"
+#include <string.h>
diff --git a/antlr/globals.c b/antlr/globals.c
new file mode 100755 (executable)
index 0000000..8795fd9
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * globals.c   --      File containing all variables/tables visible to all files.
+ *
+ * $Id: globals.c,v 1.5 95/10/05 11:57:02 parrt Exp $
+ * $Revision: 1.5 $
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+#include <stdio.h>
+#ifdef __cplusplus
+#ifndef __STDC__
+#define __STDC__
+#endif
+#endif
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+char Version[] = "1.33" ;      /* PCCTS version number */
+char VersionDef[] = "133";  /* same (except int equiv for preproc symbol) */
+char LexStartSymbol[] = "START";/* Name of starting lexical class/automaton */
+
+char *RemapFileName = "remap.h";
+char *DlgFileName = "parser.dlg";
+char *DefFileName = "tokens.h";
+char *ErrFileName = "err.c";
+char *ModeFileName = "mode.h";
+
+char *ParserName = DefaultParserName;
+
+/* list of PCCTS supplied support symbols; these are renamed when more than
+ * one ANTLR-generated parsers are linked together to avoid name conflicts.
+ * Can't use '##' ANSIC preprocessor concat operator with K&R and:
+ *             #define zzskip  zzparser ## skip
+ * will not work for ANSI/C++ as 'zzparserskip' is created w/o zzparser
+ * being substituted--ack!!!
+ */
+char *StandardSymbols[] = {
+/* ANTLR stuff */
+       "zzStackOvfMsg",
+       "zzasp",
+       "zzaStack",
+       "inf_tokens",
+       "inf_text",
+       "inf_text_buffer",
+       "inf_text_buffer_ptr",
+       "inf_text_buffer_size",
+       "inf_labase",
+       "inf_last",
+       "inf_lap",
+       "zztokenLA",
+       "zztextLA",
+       "zzlap",
+       "zzlabase",
+       "zztoktext",
+       "zztoken",
+       "zzdirty",
+       "zzguessing",
+       "zzguess_start",
+       "zzresynch",
+       "zzinf_tokens",
+       "zzinf_text",
+       "zzinf_text_buffer",
+       "zzinf_labase",
+       "zzinf_last",
+       "zzfill_inf_look",
+       "zzFAIL",
+       "zzsave_antlr_state",
+       "zzrestore_antlr_state",
+       "zzsyn",
+       "zzset_el",
+       "zzset_deg",
+       "zzedecode",
+       "_zzsetmatch",
+       "_zzmatch",
+       "_inf_zzgettok",
+    "zzconsumeUntil", 
+    "zzconsumeUntilToken",
+    "_zzmatch_wsig",
+    "_zzsetmatch_wsig",
+    "_zzmatch_wdfltsig",
+    "_zzsetmatch_wdfltsig",
+       "zzdflthandlers",
+/* DLG stuff */
+       "zzreal_line",
+       "zzcharfull",
+       "zzerr",
+       "zzlextext",
+       "zzbegexpr",
+       "zzendexpr",
+       "zzbufsize",
+       "zzbegcol",
+       "zzendcol",
+       "zzline",
+       "zzchar",
+       "zzbufovf",
+       "zzrdstream",
+       "zzrdfunc",
+       "zzrdstr",
+       "zzclose_stream",
+       "zzsave_dlg_state",
+       "zzrestore_dlg_state",
+       "zzmode",
+       "zzskip",
+       "zzmore",
+       "zzreplchar",
+       "zzreplstr",
+       "zzgettok",
+       "zzadvance",
+       "zzerrstd",
+       "zzerr_in",
+       "zzconstr_attr",
+       "zzempty_attr",
+       "zzerraction",
+       "zztokens",                     /* list of token regular expressions */
+       "dfa",
+       "accepts",
+       "actions",
+       NULL            /* must be present */
+};
+
+/* list of PCCTS supplied support functions; these are renamed when more than
+ * one ANTLR-generated parsers are linked together to avoid name conflicts.
+ */
+char *ASTSymbols[] = {
+       "AST",
+       "zzast_sp",
+       "zzastStack",
+       "zzlink",
+       "zzastnew",
+       "zzsubchild",
+       "zzsubroot",
+       "zzpre_ast",
+       "zzfree_ast",
+       "zztmake",
+       "zzdup_ast",
+       "zztfree",
+       "zzdouble_link",
+       NULL            /* must be present */
+};
+
+/* Current ambiguity examination information */
+int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile;
+char *CurAmbigbtype;
+
+
+                                               /* M e t h o d  T a b l e s */
+/*
+ * The following tables are used to fill syntax diagram nodes with the correct
+ * function pointers for computing FIRST sets and printing themselves.
+ */
+
+/* fpTraverse[node type] == pointer to function that calculates trees
+ * representing the FIRST sets for that node (maintains spatial info).
+ * We use 'struct _tree' not 'tree' due to a g++ 2.4.3 bug.
+ */
+#ifdef __cplusplus
+struct _tree *(*fpTraverse[NumNodeTypes+1])(... /* Node *, int, set * */) = {
+       NULL,
+       (struct _tree *(*)(...)) tJunc,
+       (struct _tree *(*)(...)) tRuleRef,
+       (struct _tree *(*)(...)) tToken,
+       (struct _tree *(*)(...)) tAction
+};
+#else
+Tree *(*fpTraverse[NumNodeTypes+1])() = {
+       NULL,
+       tJunc,
+       tRuleRef,
+       tToken,
+       tAction
+};
+#endif
+
+/* fpReach[node type] == pointer to function that calculates FIRST set for
+ * that node. (r stands for reach).  We use 'struct _set' not 'set'
+ * due to a g++ 2.4.3 bug.
+ */
+#ifdef __cplusplus
+struct _set (*fpReach[NumNodeTypes+1])(... /* Node *, int, set * */) = {
+       NULL,
+       (struct _set (*)(...)) rJunc,
+       (struct _set (*)(...)) rRuleRef,
+       (struct _set (*)(...)) rToken,
+       (struct _set (*)(...)) rAction
+};
+#else
+set (*fpReach[NumNodeTypes+1])() = {
+       NULL,
+       rJunc,
+       rRuleRef,
+       rToken,
+       rAction
+};
+#endif
+
+/* fpPrint[node type] == pointer to function that knows how to print that node. */
+#ifdef __cplusplus
+void (*fpPrint[NumNodeTypes+1])(... /* Node * */) = {
+       NULL,
+       (void (*)(...)) pJunc,
+       (void (*)(...)) pRuleRef,
+       (void (*)(...)) pToken,
+       (void (*)(...)) pAction
+};
+#else
+void (*fpPrint[NumNodeTypes+1])() = {
+       NULL,
+       pJunc,
+       pRuleRef,
+       pToken,
+       pAction
+};
+#endif
+
+char *decodeJType[] = {
+       "invalid",
+       "aSubBlk",
+       "aOptBlk",
+       "aLoopBlk",
+       "EndBlk",
+       "RuleBlk",
+       "Generic",
+       "EndRule",
+       "aPlusBlk",
+       "aLoopBegin"
+};
+
+
+                                                       /* H a s h  T a b l e s */
+
+Entry  **Tname,                        /* Table of all token names (maps name to tok num)*/
+               **Texpr,                        /* Table of all token expressions
+                                                          (maps expr to tok num) */
+               **Rname,                        /* Table of all Rules (has ptr to start of rule) */
+               **Fcache,                       /* Cache of First/Follow Computations */
+               **Tcache;                       /* Tree cache; First/Follow for permute trees */
+Entry  **Elabel;                       /* Table of all element label names */
+Entry  **Sname;                        /* Signal names */
+
+
+                                                       /* V a r i a b l e s */
+
+int            EpToken=0;                      /* Imaginary Epsilon token number */
+int            WildCardToken=0;
+int            CurFile= -1;            /* Index into FileStr table */
+char   *CurRule=NULL;          /* Pointer to current rule name */
+RuleEntry *CurRuleNode=NULL;/* Pointer to current rule node in syntax tree */
+char   *CurRetDef=NULL;        /* Pointer to current return type definition */
+char   *CurParmDef=NULL;       /* Pointer to current parameter definition */
+Junction *CurRuleBlk=NULL;     /* Pointer to current block node for enclosing block */
+ListNode *CurExGroups=NULL;    /* Current list of exception groups for rule/alts */
+ListNode *CurElementLabels=NULL;
+int            CurBlockID=0;           /* Unique int for each block */
+int            CurAltNum=0;
+Junction *CurAltStart = NULL;  /* Junction node that starts the alt */
+int            NumRules=0;                     /* Rules are from 1 to n */
+FILE   *output=NULL;           /* current parser output file */
+FILE   *input=NULL;            /* current grammar input file */
+char   *FileStr[MaxNumFiles];/* Ptr to array of file names on command-line */
+int            NumFiles=0;                     /* current grammar file number */
+#ifdef __cplusplus
+void   (**fpTrans)(...),       /* array of ptrs to funcs that translate nodes */
+               (**fpJTrans)(...);      /*  ... that translate junctions */
+#else
+void   (**fpTrans)(),          /* array of ptrs to funcs that translate nodes */
+               (**fpJTrans)();         /*  ... that translate junctions */
+#endif
+int            **FoStack;                      /* Array of LL_k ptrs to stacks of rule numbers */
+int            **FoTOS;                        /* FOLLOW stack top-of-stack pointers */
+Junction *SynDiag = NULL;      /* Pointer to start of syntax diagram */
+int            BlkLevel=1;                     /* Current block level.  Set by antlr.g, used by
+                                                        * scanner to translate $i.j attributes */
+set            reserved_positions;     /* set of token positions reserved by '#token T=i' cmds */
+set            all_tokens;                     /* set of all token types */
+set            imag_tokens;            /* set of all imaginary token types (EpToken, errclasses...) */
+set            tokclasses;                     /* set of all token class token types */
+ListNode *ForcedTokens = 0;    /* list of token_id/token_num pairs to remap */
+ListNode *MetaTokenNodes=NULL; /* list of meta token refs such as token classes etc... */
+int            *TokenInd=NULL;         /* an indirection level between token num and position
+                                                        * of that token def in TokenStr and ExprStr */
+int            LastTokenCounted=0;     /* ==TokenNum if no token renumbering (same as old TokenNum) */
+int            TokenNum=TokenStart;
+char   **TokenStr=NULL;        /* map token # to token name */
+char   **ExprStr=NULL;         /* map token # to expr */
+Junction **RulePtr=NULL;       /* map rule # to RuleBlk node of rule */
+ListNode *ExprOrder=NULL;      /* list of exprs as they are found in grammar */
+ListNode *BeforeActions=NULL;/* list of grammar actions before rules */
+ListNode *AfterActions=NULL;/* list of grammar actions after rules */
+ListNode *LexActions=NULL;     /* list of lexical actions */
+ListNode **Cycles=NULL;                /* list of cycles (for each k) found when
+                                                          doing FOLLOWs */
+ListNode *eclasses=NULL;       /* list of error classes */
+ListNode *tclasses=NULL;       /* list of token classes */
+LClass  lclass[MaxLexClasses]; /* array of lex class definitions */
+int             CurrentLexClass;       /* index into lclass */
+int             NumLexClasses=0;       /* in range 1..MaxLexClasses (init 0) */
+
+char   *HdrAction=NULL;        /* action defined with #header */
+FILE   *ErrFile;                       /* sets and error recovery stuff */
+FILE   *DefFile=NULL;          /* list of tokens, return value structs, setwd defs */
+int            CannotContinue=FALSE;
+int            OutputLL_k = 1;         /* LL_k for parsing must be power of 2 */
+int            action_file;            /* used to track start of action */
+int            action_line;
+int            FoundGuessBlk=0;        /* there is a (...)? block somewhere in grammar */
+int            FoundException=0;       /* there is an exception somewhere in grammar */
+int            pLevel=0;                       /* print Level */
+int            pAlt1,pAlt2;            /* print "==>" in front of these alts */
+
+/* C++ output stuff */
+FILE   *Parser_h,                      /* where subclass of ANTLRParser goes */
+               *Parser_c;                      /* where code for subclass of ANTLRParser goes */
+char   Parser_h_Name[MaxFileName+1] = "";
+char   Parser_c_Name[MaxFileName+1] = "";
+
+/* list of actions inside the #class {...} defs */
+ListNode *class_before_actions=NULL;
+ListNode *class_after_actions=NULL;
+
+char   CurrentClassName[MaxRuleName]="";
+int            no_classes_found=1;
+char   *UserTokenDefsFile;
+int            UserDefdTokens=0;       /* found #tokdefs? */
+char   *OutputDirectory=TopDirectory;
+ExceptionGroup *DefaultExGroup = NULL;
+int            NumSignals = NumPredefinedSignals;
+int            ContextGuardTRAV=0;
+
+
+                                       /* C m d - L i n e  O p t i o n s */
+
+int            LL_k=1;                         /* how many tokens of full lookahead */
+int            CLL_k= -1;                      /* how many tokens of compressed lookahead */
+int            PrintOut = FALSE;       /* print out the grammar */
+int            PrintAnnotate = FALSE;/* annotate printout with FIRST sets */
+int            CodeGen=TRUE;           /* Generate output code? */
+int            LexGen=TRUE;            /* Generate lexical files? (tokens.h, parser.dlg) */
+int            GenAST=FALSE;           /* Generate AST's? */
+int            GenANSI=FALSE;          /* Generate ANSI code where necessary */
+int            GenExprSets=TRUE;       /* use sets not (LA(1)==tok) expression lists */
+int            GenCR=FALSE;            /* Generate cross reference? */
+int            GenLineInfo=FALSE;      /* Generate # line "file" stuff? */
+int            TraceGen=FALSE;         /* Generate code to trace rule invocation */
+int            elevel=1;                       /* error level for ambiguity messages */
+int            GenEClasseForRules=0;/* don't generate eclass for each rule */
+int            TreeResourceLimit= -1;/* don't limit tree resource */
+int            DemandLookahead = 0;/* demand/delayed lookahead or not */
+char   *RulePrefix = "";       /* prefix each generated rule with this */
+char   *stdpccts = "stdpccts.h";/* where to generate std pccts include file */
+int            GenStdPccts = 0;        /* don't gen stdpccts.h? */
+int            ParseWithPredicates = 1;
+int            WarningLevel = 1;
+int            HoistPredicateContext = 0;
+int            GenCC = 0;                      /* Generate C++ output */
+
+/* DontCopyTokens and Pragma_DupLabeledTokens were a bad idea.  I've just
+   turned them off rather than backpatching the code.  Who knows?  We
+   may need them in the future.
+ */
+int            DontCopyTokens = 1;     /* in C++, don't copy ANTLRToken passed to ANTLR */
diff --git a/antlr/hash.c b/antlr/hash.c
new file mode 100755 (executable)
index 0000000..6e8a278
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * hash.c
+ *
+ * $Id: hash.c,v 1.3 95/10/05 11:57:07 parrt Exp $
+ * $Revision: 1.3 $
+ *
+ * Manage hash tables.
+ *
+ * The following functions are visible:
+ *
+ *             char    *mystrdup(char *);              Make space and copy string
+ *             Entry   **newHashTable();               Create and return initialized hash table
+ *             Entry   *hash_add(Entry **, char *, Entry *)
+ *             Entry   *hash_get(Entry **, char *)
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#include <stdio.h>
+#include "config.h"
+#ifdef __cplusplus
+#ifndef __STDC__
+#define __STDC__
+#endif
+#endif
+#include "hash.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#ifdef VAXC
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#endif
+#include <string.h>
+
+#define StrSame                0
+
+#define fatal(err)                                                                                                                     \
+                       {fprintf(stderr, "%s(%d):", __FILE__, __LINE__);                                \
+                       fprintf(stderr, " %s\n", err); exit(PCCTS_EXIT_FAILURE);}
+#define require(expr, err) {if ( !(expr) ) fatal(err);}
+
+static unsigned size = HashTableSize;
+static char *strings = NULL;
+static char *strp;
+static unsigned strsize = StrTableSize;
+
+/* create the hash table and string table for terminals (string table only once) */
+Entry **
+#ifdef __STDC__
+newHashTable( void )
+#else
+newHashTable( )
+#endif
+{
+       Entry **table;
+       
+       table = (Entry **) calloc(size, sizeof(Entry *));
+       require( table != NULL, "cannot allocate hash table");
+       if ( strings == NULL )
+       {
+               strings = (char *) calloc(strsize, sizeof(char));
+               require( strings != NULL, "cannot allocate string table");
+               strp = strings;
+       }
+       return table;
+}
+
+void
+#ifdef __STDC__
+killHashTable( Entry **table )
+#else
+killHashTable( table )
+Entry **table;
+#endif
+{
+       /* for now, just free table, forget entries */
+       free( table );
+}
+
+/* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */
+Entry *
+#ifdef __STDC__
+hash_add( Entry **table, char *key, Entry *rec )
+#else
+hash_add( table, key, rec )
+Entry **table;
+char *key;
+Entry *rec;
+#endif
+{
+       unsigned h=0;
+       char *p=key;
+       extern Entry *Globals;
+       require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition");
+       
+       Hash(p,h,size);
+       rec->next = table[h];                   /* Add to singly-linked list */
+       table[h] = rec;
+       return rec;
+}
+
+/* Return ptr to 1st entry found in table under key (return NULL if none found) */
+Entry *
+#ifdef __STDC__
+hash_get( Entry **table, char *key )
+#else
+hash_get( table, key )
+Entry **table;
+char *key;
+#endif
+{
+       unsigned h=0;
+       char *p=key;
+       Entry *q;
+/*     require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/
+       if ( !(table!=NULL && key!=NULL) ) *((char *) 34) = 3;
+       
+       Hash(p,h,size);
+       for (q = table[h]; q != NULL; q = q->next)
+       {
+               if ( strcmp(key, q->str) == StrSame ) return( q );
+       }
+       return( NULL );
+}
+
+#ifdef DEBUG_HASH
+void
+#ifdef __STDC__
+hashStat( Entry **table )
+#else
+hashStat( table )
+Entry **table;
+#endif
+{
+       static unsigned short count[20];
+       int i,n=0,low=0, hi=0;
+       Entry **p;
+       float avg=0.0;
+       
+       for (i=0; i<20; i++) count[i] = 0;
+       for (p=table; p<&(table[size]); p++)
+       {
+               Entry *q = *p;
+               int len;
+               
+               if ( q != NULL && low==0 ) low = p-table;
+               len = 0;
+               if ( q != NULL ) fprintf(stderr, "[%d]", p-table);
+               while ( q != NULL )
+               {
+                       len++;
+                       n++;
+                       fprintf(stderr, " %s", q->str);
+                       q = q->next;
+                       if ( q == NULL ) fprintf(stderr, "\n");
+               }
+               count[len]++;
+               if ( *p != NULL ) hi = p-table;
+       }
+
+       fprintf(stderr, "Storing %d recs used %d hash positions out of %d\n",
+                                       n, size-count[0], size);
+       fprintf(stderr, "%f %% utilization\n",
+                                       ((float)(size-count[0]))/((float)size));
+       for (i=0; i<20; i++)
+       {
+               if ( count[i] != 0 )
+               {
+                       avg += (((float)(i*count[i]))/((float)n)) * i;
+                       fprintf(stderr, "Bucket len %d == %d (%f %% of recs)\n",
+                                                       i, count[i], ((float)(i*count[i]))/((float)n));
+               }
+       }
+       fprintf(stderr, "Avg bucket length %f\n", avg);
+       fprintf(stderr, "Range of hash function: %d..%d\n", low, hi);
+}
+#endif
+
+/* Add a string to the string table and return a pointer to it.
+ * Bump the pointer into the string table to next avail position.
+ */
+char *
+#ifdef __STDC__
+mystrdup( char *s )
+#else
+mystrdup( s )
+char *s;
+#endif
+{
+       char *start=strp;
+       require(s!=NULL, "mystrdup: NULL string");
+
+       while ( *s != '\0' )
+       {
+               require( strp <= &(strings[strsize-2]),
+                                "string table overflow\nIncrease StrTableSize in hash.h and recompile hash.c\n");
+               *strp++ = *s++;
+       }
+       *strp++ = '\0';
+
+       return( start );
+}
diff --git a/antlr/lex.c b/antlr/lex.c
new file mode 100755 (executable)
index 0000000..78ed821
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ * lex.c       --      Generate all of the lexical type files: parser.dlg tokens.h
+ *
+ * $Id: lex.c,v 1.4 95/09/26 12:58:36 parrt Exp $
+ * $Revision: 1.4 $
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+#include <stdio.h>
+#include <ctype.h>
+#ifdef __cplusplus
+#ifndef __STDC__
+#define __STDC__
+#endif
+#endif
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+#define DLGErrorString "invalid token"
+
+/* Generate a complete lexical description of the lexemes found in the grammar */
+void
+#ifdef __STDC__
+genLexDescr( void )
+#else
+genLexDescr( )
+#endif
+{
+       ListNode *p;
+       FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");
+       require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );
+       special_fopen_actions(OutMetaName(DlgFileName));
+
+       fprintf(dlgFile, "<<\n");
+       fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName);
+       fprintf(dlgFile, " *\n");
+       fprintf(dlgFile, " * Generated from:");
+       {int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}
+       fprintf(dlgFile, "\n");
+       fprintf(dlgFile, " *\n");
+       fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
+       fprintf(dlgFile, " * Purdue University Electrical Engineering\n");
+       fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");
+       fprintf(dlgFile, " * ANTLR Version %s\n", Version);
+       fprintf(dlgFile, " */\n\n");
+       if ( GenCC )
+       {
+               if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
+               else fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
+               fprintf(dlgFile, "#include \"%s\"\n", ATOKEN_H);
+               if ( GenAST ) fprintf(dlgFile, "#include \"%s\"\n", ASTBASE_H);
+               if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
+       }
+       else
+       {
+               fprintf(dlgFile, "#include <stdio.h>\n");
+               fprintf(dlgFile, "#define ANTLR_VERSION %s\n", VersionDef);
+               if ( strcmp(ParserName, DefaultParserName)!=0 )
+                       fprintf(dlgFile, "#define %s %s\n", DefaultParserName, ParserName);
+               if ( strcmp(ParserName, DefaultParserName)!=0 )
+                       fprintf(dlgFile, "#include \"%s\"\n", RemapFileName);
+               if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
+               if ( FoundGuessBlk )
+               {
+                       fprintf(dlgFile, "#define ZZCAN_GUESS\n");
+                       fprintf(dlgFile, "#include <setjmp.h>\n");
+               }
+               if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);
+               if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");
+               fprintf(dlgFile, "#include \"antlr.h\"\n");
+               if ( GenAST ) {
+                       fprintf(dlgFile, "#include \"ast.h\"\n");
+               }
+               if ( UserDefdTokens )
+                       fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
+               /* still need this one as it has the func prototypes */
+               fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
+               fprintf(dlgFile, "#include \"dlgdef.h\"\n");
+               fprintf(dlgFile, "LOOKAHEAD\n");
+               fprintf(dlgFile, "void zzerraction()\n");
+               fprintf(dlgFile, "{\n");
+               fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);
+               fprintf(dlgFile, "\tzzadvance();\n");
+               fprintf(dlgFile, "\tzzskip();\n");
+               fprintf(dlgFile, "}\n");
+       }
+       fprintf(dlgFile, ">>\n\n");
+
+       /* dump all actions */
+    if (LexActions != NULL)
+    {
+        for (p = LexActions->next; p!=NULL; p=p->next)
+               {
+                       fprintf(dlgFile, "<<\n");
+                       dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
+                       fprintf(dlgFile, ">>\n");
+               }
+       }
+       /* dump all regular expression rules/actions (skip sentinel node) */
+       if ( ExprOrder == NULL ) {
+               warnNoFL("no regular expressions found in grammar");
+       }
+       else dumpLexClasses(dlgFile);
+       fprintf(dlgFile, "%%%%\n");
+       fclose( dlgFile );
+}
+
+/* For each lexical class, scan ExprOrder looking for expressions
+ * in that lexical class.  Print out only those that match.
+ * Each element of the ExprOrder list has both an expr and an lclass
+ * field.
+ */
+void
+#ifdef __STDC__
+dumpLexClasses( FILE *dlgFile )
+#else
+dumpLexClasses( dlgFile )
+FILE *dlgFile;
+#endif
+{
+       int i;
+       TermEntry *t;
+       ListNode *p;
+       Expr *q;
+
+       for (i=0; i<NumLexClasses; i++)
+       {
+               fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);
+               for (p=ExprOrder->next; p!=NULL; p=p->next)
+               {
+                       q = (Expr *) p->elem;
+                       if ( q->lclass != i ) continue;
+                       lexmode(i);
+                       t = (TermEntry *) hash_get(Texpr, q->expr);
+                       require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
+                       if ( t->token == EpToken ) continue;
+                       fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));
+                       /* replace " killed by StripQuotes() */
+                       q->expr[ strlen(q->expr) ] = '"';
+                       if ( !GenCC ) {
+                               if ( TokenString(t->token) != NULL )
+                                       fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));
+                               else
+                                       fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);
+                       }
+                       if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
+                       if ( GenCC ) {
+                               if ( TokenString(t->token) != NULL )
+                                       fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));
+                               else
+                                       fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token);
+                       }
+                       fprintf(dlgFile, "\t>>\n\n");
+               }
+       }
+}
+
+/* Strip the leading path (if any) from a filename */
+char *
+#ifdef __STDC__
+StripPath( char *fileName )
+#else
+StripPath( fileName )
+char *fileName;
+#endif
+{
+       char *p;
+       static char dirSym[2] = DirectorySymbol;
+
+       if(NULL != (p = strrchr(fileName, dirSym[0])))
+               p++;
+       else
+               p = fileName;
+
+       return(p);
+}
+
+/* Generate a list of #defines && list of struct definitions for
+ * aggregate retv's */
+void
+#ifdef __STDC__
+genDefFile( void )
+#else
+genDefFile( )
+#endif
+{
+       int i;
+
+       /* If C++ mode and #tokdef used, then don't need anything in here since
+        * C++ puts all definitions in the class file name.
+        */
+       if ( GenCC && UserTokenDefsFile ) return;
+
+       DefFile = fopen(OutMetaName(DefFileName), "w");
+       require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
+       special_fopen_actions(OutMetaName(DefFileName));
+
+       fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName)));
+       fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName)));
+
+       fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);
+       fprintf(DefFile, " *\n");
+       fprintf(DefFile, " * Generated from:");
+       for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
+       fprintf(DefFile, "\n");
+       fprintf(DefFile, " *\n");
+       fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
+       fprintf(DefFile, " * Purdue University Electrical Engineering\n");
+       fprintf(DefFile, " * ANTLR Version %s\n", Version);
+       fprintf(DefFile, " */\n");
+
+       if ( !GenCC && LexGen ) {
+               fprintf(DefFile,"#define zzEOF_TOKEN %d\n",
+                               TokenInd!=NULL?TokenInd[EofToken]:EofToken);
+       }
+
+       if ( !UserDefdTokens )
+       {
+               int first=1;
+
+               if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {\n");
+               for (i=1; i<TokenNum; i++)
+               {
+                       /* Don't do EpToken or expr w/o labels */
+                       if ( TokenString(i)!=NULL && i != EpToken )
+                       {
+                               TermEntry *p;
+                               
+                               if ( WarningLevel>1 )
+                               {
+                                       int j;
+                                       /* look in all lexclasses for the reg expr */
+                                       for (j=0; j<NumLexClasses; j++)
+                                       {
+                                               lexmode(j);
+                                               if ( ExprString(i)!=NULL ) break;
+                                       }
+                                       if ( j>=NumLexClasses )
+                                       {
+                                               warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
+                                       }
+                               }
+                               require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
+                                               "token not in sym tab when it should be");
+                               if ( !p->classname )
+                               {
+                                       if ( GenCC ) {
+                                               if ( !first ) fprintf(DefFile, ",\n");
+                                               first = 0;
+                                               fprintf(DefFile, "\t%s=%d", TokenString(i), i);
+                                       }
+                                       else
+                                               fprintf(DefFile, "#define %s %d\n", TokenString(i), i);
+                               }
+                       }
+               }
+               if ( GenCC ) fprintf(DefFile, "};\n");
+       }
+
+       if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
+
+       fprintf(DefFile, "\n#endif\n");
+}
+
+void
+#ifdef __STDC__
+GenRemapFile( void )
+#else
+GenRemapFile( )
+#endif
+{
+       if ( strcmp(ParserName, DefaultParserName)!=0 )
+       {
+               FILE *f;
+               int i;
+
+               f = fopen(OutMetaName(RemapFileName), "w");
+               require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
+               special_fopen_actions(OutMetaName(RemapFileName));
+
+               fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);
+               fprintf(f, " *\n");
+               fprintf(f, " * Generated from:");
+               for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
+               fprintf(f, "\n");
+               fprintf(f, " *\n");
+               fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
+               fprintf(f, " * Purdue University Electrical Engineering\n");
+               fprintf(f, " * ANTLR Version %s\n", Version);
+               fprintf(f, " */\n");
+
+               GenRuleFuncRedefs(f, SynDiag);
+               GenPredefinedSymbolRedefs(f);
+               if ( GenAST ) GenASTSymbolRedefs(f);
+               GenSetRedefs(f);
+
+               fclose(f);
+       }
+}
+
+/* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
+void
+#ifdef __STDC__
+GenRuleFuncRedefs( FILE *f, Junction *p )
+#else
+GenRuleFuncRedefs( f, p )
+FILE *f;
+Junction *p;
+#endif
+{
+       fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");
+       while ( p!=NULL )
+       {
+               fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);
+               p = (Junction *)p->p2;
+       }
+}
+
+/* Generate a bunch of #defines that rename all standard symbols to be
+ * "ParserName_symbol".  The list of standard symbols to change is in
+ * globals.c.
+ */
+void
+#ifdef __STDC__
+GenPredefinedSymbolRedefs( FILE *f )
+#else
+GenPredefinedSymbolRedefs( f )
+FILE *f;
+#endif
+{
+       char **p;
+
+       fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");
+       for (p = &StandardSymbols[0]; *p!=NULL; p++)
+       {
+               fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
+       }
+}
+
+/* Generate a bunch of #defines that rename all AST symbols to be
+ * "ParserName_symbol".  The list of AST symbols to change is in
+ * globals.c.
+ */
+void
+#ifdef __STDC__
+GenASTSymbolRedefs( FILE *f )
+#else
+GenASTSymbolRedefs( f )
+FILE *f;
+#endif
+{
+       char **p;
+
+       fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");
+       for (p = &ASTSymbols[0]; *p!=NULL; p++)
+       {
+               fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
+       }
+}
+
+/* redefine all sets generated by ANTLR; WARNING:  'zzerr', 'setwd' must match
+ * use in bits.c (DumpSetWd() etc...)
+ */
+void
+#ifdef __STDC__
+GenSetRedefs( FILE *f )
+#else
+GenSetRedefs( f )
+FILE *f;
+#endif
+{
+       int i;
+
+       for (i=1; i<=wordnum; i++)
+       {
+               fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);
+       }
+       for (i=1; i<=esetnum; i++)
+       {
+               fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);
+       }
+}
+
+/* Find all return types/parameters that require structs and def
+ * all rules with ret types.
+ */
+void
+#ifdef __STDC__
+GenRulePrototypes( FILE *f, Junction *p )
+#else
+GenRulePrototypes( f, p )
+FILE *f;
+Junction *p;
+#endif
+{
+       int i;
+
+       i = 1;
+       while ( p!=NULL )
+       {
+               if ( p->ret != NULL )
+               {
+                       if ( HasComma(p->ret) )
+                       {
+                               DumpRetValStruct(f, p->ret, i);
+                       }
+                       fprintf(f, "\n#ifdef __STDC__\n");
+                       if ( HasComma(p->ret) )
+                       {
+                               fprintf(f, "extern struct _rv%d", i);
+                       }
+                       else
+                       {
+                               fprintf(f, "extern ");
+                               DumpType(p->ret, f);
+                       }
+                       fprintf(f, " %s%s(", RulePrefix, p->rname);
+                       DumpANSIFunctionArgDef(f,p);
+                       fprintf(f, ";\n");
+#ifdef OLD
+                       if ( p->pdecl != NULL || GenAST )
+                       {
+                               if ( GenAST ) {
+                                       fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
+                               }
+                               if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+                       }
+                       else fprintf(f, "void");
+                       fprintf(f, ");\n");
+#endif
+                       fprintf(f, "#else\n");
+                       if ( HasComma(p->ret) )
+                       {
+                               fprintf(f, "extern struct _rv%d", i);
+                       }
+                       else
+                       {
+                               fprintf(f, "extern ");
+                               DumpType(p->ret, f);
+                       }
+                       fprintf(f, " %s%s();\n", RulePrefix, p->rname);
+                       fprintf(f, "#endif\n");
+               }
+               else
+               {
+                       fprintf(f, "\n#ifdef __STDC__\n");
+                       fprintf(f, "void %s%s(", RulePrefix, p->rname);
+                       DumpANSIFunctionArgDef(f,p);
+                       fprintf(f, ";\n");
+#ifdef OLD
+                       if ( p->pdecl != NULL || GenAST )
+                       {
+                               if ( GenAST ) {
+                                       fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
+                               }
+                               if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+                       }
+                       else fprintf(f, "void");
+                       fprintf(f, ");\n");
+#endif
+                       fprintf(f, "#else\n");
+                       fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);
+                       fprintf(f, "#endif\n");
+               }
+               i++;
+               p = (Junction *)p->p2;
+       }
+}
+
+/* Define all rules in the class.h file; generate any required
+ * struct definitions first, however.
+ */
+void
+#ifdef __STDC__
+GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
+#else
+GenRuleMemberDeclarationsForCC( f, q )
+FILE *f;
+Junction *q;
+#endif
+{
+       Junction *p = q;
+       int i;
+
+       fprintf(f, "private:\n");
+
+       /* Dump dflt handler declaration */
+       fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");
+
+       fprintf(f, "public:\n");
+
+       /* Dump return value structs */
+       i = 1;
+       while ( p!=NULL )
+       {
+               if ( p->ret != NULL )
+               {
+                       if ( HasComma(p->ret) )
+                       {
+                               DumpRetValStruct(f, p->ret, i);
+                       }
+               }
+               i++;
+               p = (Junction *)p->p2;
+       }
+
+       /* Dump member func defs && CONSTRUCTOR */
+       fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);
+/*
+       fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n",
+                          CurrentClassName);
+*/
+
+       i = 1;
+       p = q;
+       while ( p!=NULL )
+       {
+               if ( p->ret != NULL )
+               {
+                       if ( HasComma(p->ret) )
+                       {
+                               fprintf(f, "\tstruct _rv%d", i);
+                       }
+                       else
+                       {
+                               fprintf(f, "\t");
+                               DumpType(p->ret, f);
+                       }
+                       fprintf(f, " %s(", p->rname);
+                       DumpANSIFunctionArgDef(f,p);
+                       fprintf(f, ";\n");
+#ifdef OLD
+                       if ( p->pdecl != NULL || GenAST )
+                       {
+                               if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
+                               if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+                       }
+                       fprintf(f, ");\n");
+#endif
+               }
+               else
+               {
+                       fprintf(f, "\tvoid %s(", p->rname);
+                       DumpANSIFunctionArgDef(f,p);
+                       fprintf(f, ";\n");
+#ifdef OLD
+                       if ( p->pdecl != NULL || GenAST )
+                       {
+                               if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
+                               if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+                       }
+                       fprintf(f, ");\n");
+#endif
+               }
+               i++;
+               p = (Junction *)p->p2;
+       }
+}
+
+/* Given a list of ANSI-style parameter declarations, print out a
+ * comma-separated list of the symbols (w/o types).
+ * Basically, we look for a comma, then work backwards until start of
+ * the symbol name.  Then print it out until 1st non-alnum char.  Now,
+ * move on to next parameter.
+ */
+void
+#ifdef __STDC__
+DumpListOfParmNames( char *pdecl, FILE *output )
+#else
+DumpListOfParmNames( pdecl, output )
+char *pdecl;
+FILE *output;
+#endif
+{
+       int firstTime = 1, done = 0;
+       require(output!=NULL, "DumpListOfParmNames: NULL parm");
+
+       if ( pdecl == NULL ) return;
+       while ( !done )
+       {
+               if ( !firstTime ) putc(',', output);
+               done = DumpNextNameInDef(&pdecl, output);
+               firstTime = 0;
+       }
+}
+
+/* given a list of parameters or return values, dump the next
+ * name to output.  Return 1 if last one just printed, 0 if more to go.
+ */
+int
+#ifdef __STDC__
+DumpNextNameInDef( char **q, FILE *output )
+#else
+DumpNextNameInDef( q, output )
+char **q;
+FILE *output;
+#endif
+{
+       char *p = *q;           /* where did we leave off? */
+       int done=0;
+
+       while ( *p!='\0' && *p!=',' ) p++;              /* find end of decl */
+       if ( *p == '\0' ) done = 1;
+       while ( !isalnum(*p) && *p!='_' ) --p;  /* scan back until valid var character */
+       while ( isalnum(*p) || *p=='_' ) --p;   /* scan back until beginning of variable */
+       p++;                                            /* move to start of variable */
+       while ( isalnum(*p) || *p=='_'  ) {putc(*p, output); p++;}
+       while ( *p!='\0' && *p!=',' ) p++;              /* find end of decl */
+       p++;                            /* move past this parameter */
+
+       *q = p;                         /* record where we left off */
+       return done;
+}
+
+/* Given a list of ANSI-style parameter declarations, dump K&R-style
+ * declarations, one per line for each parameter.  Basically, convert
+ * comma to semi-colon, newline.
+ */
+void
+#ifdef __STDC__
+DumpOldStyleParms( char *pdecl, FILE *output )
+#else
+DumpOldStyleParms( pdecl, output )
+char *pdecl;
+FILE *output;
+#endif
+{
+       require(output!=NULL, "DumpOldStyleParms: NULL parm");
+
+       if ( pdecl == NULL ) return;
+       while ( *pdecl != '\0' )
+       {
+               if ( *pdecl == ',' )
+               {
+                       pdecl++;
+                       putc(';', output); putc('\n', output);
+                       while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
+               }
+               else {putc(*pdecl, output); pdecl++;}
+       }
+       putc(';', output);
+       putc('\n', output);
+}
+
+/* Take in a type definition (type + symbol) and print out type only */
+void
+#ifdef __STDC__
+DumpType( char *s, FILE *f )
+#else
+DumpType( s, f )
+char *s;
+FILE *f;
+#endif
+{
+       char *p, *end;
+       require(s!=NULL, "DumpType: invalid type string");
+
+       p = &s[strlen(s)-1];            /* start at end of string and work back */
+       /* scan back until valid variable character */
+       while ( !isalnum(*p) && *p!='_' ) --p;
+       /* scan back until beginning of variable */
+       while ( isalnum(*p) || *p=='_' ) --p;
+       if ( p<=s )
+       {
+               warnNoFL(eMsg1("invalid parameter/return value: '%s'",s));
+               return;
+       }
+       end = p;                                        /* here is where we stop printing alnum */
+       p = s;
+       while ( p!=end ) {putc(*p, f); p++;} /* dump until just before variable */
+       while ( *p!='\0' )                                       /* dump rest w/o variable */
+       {
+               if ( !isalnum(*p) && *p!='_' ) putc(*p, f);
+               p++;
+       }
+}
+
+/* check to see if string e is a word in string s */
+int
+#ifdef __STDC__
+strmember( char *s, char *e )
+#else
+strmember( s, e )
+char *s;
+char *e;
+#endif
+{
+    register char *p;
+    require(s!=NULL&&e!=NULL, "strmember: NULL string");
+    
+    if ( *e=='\0' ) return 1;   /* empty string is always member */
+    do {
+       while ( *s!='\0' && !isalnum(*s) && *s!='_' )
+       ++s;
+       p = e;
+       while ( *p!='\0' && *p==*s ) {p++; s++;}
+       if ( *p=='\0' ) {
+           if ( *s=='\0' ) return 1;
+           if ( !isalnum (*s) && *s != '_' ) return 1;
+       }
+       while ( isalnum(*s) || *s == '_' )
+       ++s;
+    } while ( *s!='\0' );
+    return 0;
+}
+
+int
+#ifdef __STDC__
+HasComma( char *s )
+#else
+HasComma( s )
+char *s;
+#endif
+{
+       while (*s!='\0')
+               if ( *s++ == ',' ) return 1;
+       return 0;
+}
+
+void
+#ifdef __STDC__
+DumpRetValStruct( FILE *f, char *ret, int i )
+#else
+DumpRetValStruct( f, ret, i )
+FILE *f;
+char *ret;
+int i;
+#endif
+{
+       fprintf(f, "\nstruct _rv%d {\n", i);
+       while ( *ret != '\0' )
+       {
+                while ( *ret==' ' || *ret=='\t' ) ret++; /* ignore white */
+                putc('\t', f);
+                while ( *ret!=',' && *ret!='\0' ) {putc(*ret,f); ret++;}
+                if ( *ret == ',' ) {putc(';', f); putc('\n', f); ret++;}
+       }
+       fprintf(f, ";\n};\n");
+}
+
+/* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
+char *
+#ifdef __STDC__
+StripQuotes( char *s )
+#else
+StripQuotes( s )
+char *s;
+#endif
+{
+       if ( *s == '"' )
+       {
+               s[ strlen(s)-1 ] = '\0';    /* remove last quote */
+               return( s+1 );                          /* return address past initial quote */
+       }
+       return( s );
+}
+
diff --git a/antlr/main.c b/antlr/main.c
new file mode 100755 (executable)
index 0000000..1d0284a
--- /dev/null
@@ -0,0 +1,1220 @@
+/*
+ * main.c -- main program for PCCTS ANTLR.
+ *
+ * $Id: main.c,v 1.7 95/10/05 11:57:08 parrt Exp $
+ * $Revision: 1.7 $
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#include <stdio.h>
+#ifdef __cplusplus
+#ifndef __STDC__
+#define __STDC__
+#endif
+#endif
+#include "stdpccts.h"
+
+#define MAX_INT_STACK 50
+static int istack[MAX_INT_STACK];              /* Int stack */
+static int isp = MAX_INT_STACK;
+
+static int DontAcceptFiles = 0;                        /* if stdin, don't read files */
+static int DontAcceptStdin = 0;                        /* if files seen first, don't accept stdin */
+
+
+               /* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */
+
+typedef struct _Opt {
+                       char *option;
+                       int  arg;
+#ifdef __cplusplus
+                       void (*process)(...);
+#else
+                       void (*process)();
+#endif
+                       char *descr;
+               } Opt;
+
+#ifdef __STDC__
+extern void ProcessArgs(int, char **, Opt *);
+#else
+extern void ProcessArgs();
+#endif
+
+static void
+#ifdef __STDC__
+pStdin( void )
+#else
+pStdin( )
+#endif
+{
+       if ( DontAcceptStdin )
+       {
+               warnNoFL("'-' (stdin) ignored as files were specified first");
+               return;
+       }
+
+       require(NumFiles<MaxNumFiles,"exceeded max # of input files");
+       FileStr[NumFiles++] = "stdin";
+       DontAcceptFiles = 1;
+}
+
+static void
+#ifdef __STDC__
+pFile( char *s )
+#else
+pFile( s )
+char *s;
+#endif
+{
+       if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
+       if ( DontAcceptFiles )
+       {
+               warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
+               return;
+       }
+
+       require(NumFiles<MaxNumFiles,"exceeded max # of input files");
+       FileStr[NumFiles++] = s;
+       DontAcceptStdin = 1;
+}
+
+static void
+#ifdef __STDC__
+pLLK( char *s, char *t )
+#else
+pLLK( s, t )
+char *s;
+char *t;
+#endif
+{
+       LL_k = atoi(t);
+       if ( LL_k <= 0 ) {
+               warnNoFL("must have at least one token of lookahead (setting to 1)");
+               LL_k = 1;
+       }
+}
+
+static void
+#ifdef __STDC__
+pCk( char *s, char *t )
+#else
+pCk( s, t )
+char *s;
+char *t;
+#endif
+{
+       CLL_k = atoi(t);
+       if ( CLL_k <= 0 ) {
+               warnNoFL("must have at least one token of look-ahead (setting to 1)");
+               CLL_k = 1;
+       }
+}
+
+#ifdef __STDC__
+void chkGTFlag()
+#else
+void chkGTFlag(void)
+#endif
+{
+       if ( !GenAST )
+               warn("#-variable or other AST item referenced w/o -gt option");
+}
+
+#ifdef __STDC__
+static void pCGen(void)        { CodeGen = FALSE; LexGen = FALSE; }
+static void pLGen(void)        { LexGen = FALSE; }
+static void pTGen(void)        { TraceGen = TRUE; }
+static void pSGen(void)        { GenExprSets = FALSE; }
+static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); }
+static void pPrtA(void)        { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
+static void pAst(void) { GenAST = TRUE; }
+static void pANSI(void)        { GenANSI = TRUE; }
+static void pCr(void)  { GenCR = TRUE; }
+/*static void pCt(void)        { warnNoFL("-ct option is now the default"); }*/
+static void pLI(void)  { GenLineInfo = TRUE; }
+static void pFr(char *s, char *t) {RemapFileName = t;}
+static void pFe(char *s, char *t) {ErrFileName = t;}
+static void pFl(char *s, char *t) {DlgFileName = t;}
+static void pFm(char *s, char *t) {ModeFileName = t;}
+static void pFt(char *s, char *t) {DefFileName = t;}
+static void pE1(void)  { elevel = 1; }
+static void pE2(void)  { elevel = 2; }
+static void pE3(void)  { elevel = 3; }
+static void pEGen(void)        { GenEClasseForRules = 1; }
+static void pDL(void)
+       {
+           DemandLookahead = 1;
+           if ( GenCC ) {
+                       warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
+                       DemandLookahead = 0;
+           }
+       }
+
+static void pGHdr(void)        { GenStdPccts = 1; }
+static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
+static void pW1(void) { WarningLevel = 1; }
+static void pW2(void) { WarningLevel = 2; }
+static void pCC(void) { GenCC = TRUE; }
+#else
+static void pCGen()    { CodeGen = FALSE; LexGen = FALSE; }
+static void pLGen()    { LexGen = FALSE; }
+static void pTGen()    { TraceGen = TRUE; }
+static void pSGen()    { GenExprSets = FALSE; }
+static void pPrt()             { PrintOut = TRUE; pCGen(); pLGen(); }
+static void pPrtA()    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
+static void pAst()             { GenAST = TRUE; }
+static void pANSI()    { GenANSI = TRUE; }
+static void pCr()              { GenCR = TRUE; }
+/*static void pCt()            { warnNoFL("-ct option is now the default"); }*/
+static void pLI()              { GenLineInfo = TRUE; }
+static void pFr(s,t) char *s, *t; {RemapFileName = t;}
+static void pFe(s,t) char *s, *t; {ErrFileName = t;}
+static void pFl(s,t) char *s, *t; {DlgFileName = t;}
+static void pFm(s,t) char *s, *t; {ModeFileName = t;}
+static void pFt(s,t) char *s, *t; {DefFileName = t;}
+static void pE1()              { elevel = 1; }
+static void pE2()              { elevel = 2; }
+static void pE3()              { elevel = 3; }
+static void pEGen()    { GenEClasseForRules = 1; }
+static void pDL()
+       {
+           DemandLookahead = 1;
+           if ( GenCC ) {
+               warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
+               DemandLookahead = 0;
+           }
+       }
+static void pGHdr()    { GenStdPccts = 1; }
+static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
+static void pW1() { WarningLevel = 1; }
+static void pW2() { WarningLevel = 2; }
+static void pCC() { GenCC = TRUE; }
+#endif
+
+static void
+#ifdef __STDC__
+pPre( char *s, char *t )
+#else
+pPre( s, t )
+char *s;
+char *t;
+#endif
+{
+       RulePrefix = t;
+}
+
+static void
+#ifdef __STDC__
+pOut( char *s, char *t )
+#else
+pOut( s, t )
+char *s;
+char *t;
+#endif
+{
+       OutputDirectory = t;
+}
+
+static void
+#ifdef __STDC__
+pPred( void )
+#else
+pPred( )
+#endif
+{
+       warnNoFL("-pr is no longer used (predicates employed if present); see -prc");
+/*
+       if ( DemandLookahead )
+               warnNoFL("-gk conflicts with -pr; -gk turned off");
+       DemandLookahead = 0;
+       HoistPredicateContext = 0;
+*/
+}
+
+static void
+#ifdef __STDC__
+pPredCtx( char *s, char *t )
+#else
+pPredCtx(s,t)
+char *s;
+char *t;
+#endif
+{
+       if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
+       else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
+       else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
+       else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
+       if ( DemandLookahead )
+       {
+               warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
+               DemandLookahead = 0;
+       }
+}
+
+static void
+#ifdef __STDC__
+pTRes( char *s, char *t )
+#else
+pTRes( s, t )
+char *s;
+char *t;
+#endif
+{
+       TreeResourceLimit = atoi(t);
+       if ( TreeResourceLimit <= 0 )
+       {
+               warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
+               TreeResourceLimit = -1; /* set to no limit */
+       }
+}
+
+Opt options[] = {
+#ifdef __cplusplus
+    { "-CC", 0, (void (*)(...)) pCC,   "Generate C++ output (default=FALSE)"},
+    { "-ck", 1, (void (*)(...)) pCk,   "Set compressed lookahead depth; fast approximate lookahead"},
+    { "-cr", 0, (void (*)(...)) pCr,   "Generate cross reference (default=FALSE)"},
+    { "-e1", 0, (void (*)(...)) pE1,   "Ambiguities/errors shown in low detail (default)"},
+    { "-e2", 0, (void (*)(...)) pE2,   "Ambiguities/errors shown in more detail"},
+    { "-e3", 0, (void (*)(...)) pE3,   "Ambiguities/errors shown in excruciating detail"},
+    { "-fe", 1, (void (*)(...)) pFe,   "Rename err.c"},
+    { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"},
+    { "-fl", 1, (void (*)(...)) pFl,   "Rename lexical output--parser.dlg"},
+    { "-fm", 1, (void (*)(...)) pFm,   "Rename mode.h"},
+    { "-fr", 1, (void (*)(...)) pFr,   "Rename remap.h"},
+    { "-ft", 1, (void (*)(...)) pFt,   "Rename tokens.h"},
+    { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"},
+    { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"},
+    { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"},
+    { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
+       { "-gh", 0, (void (*)(...)) pGHdr,      "Generate stdpccts.h for non-ANTLR-generated-files to include"},
+       { "-gk", 0, (void (*)(...)) pDL,        "Generate parsers that delay lookahead fetches 'til needed"},
+       { "-gl", 0, (void (*)(...)) pLI,        "Generate line info about grammar actions in C parser"},
+       { "-gp", 1, (void (*)(...)) pPre,       "Prefix all generated rule functions with a string"},
+    { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
+    { "-gt", 0, (void (*)(...)) pAst,  "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
+    { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
+    { "-k",  1, (void (*)(...)) pLLK,  "Set full LL(k) lookahead depth (default==1)"},
+    { "-o",  1, (void (*)(...)) pOut,  OutputDirectoryOption},
+    { "-p",  0, (void (*)(...)) pPrt,  "Print out the grammar w/o actions (default=no)"},
+    { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
+    { "-pr",0, (void (*)(...)) pPred,  "no longer used; predicates employed if present"},
+    { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
+       { "-rl", 1, (void (*)(...)) pTRes,      "Limit max # of tree nodes used by grammar analysis"},
+       { "-w1", 0, (void (*)(...)) pW1,        "Set the warning level to 1 (default)"},
+       { "-w2", 0, (void (*)(...)) pW2,        "Ambiguities yield warnings even if predicates or (...)? block"},
+       { "-",   0, (void (*)(...)) pStdin,     "Read grammar from stdin" },
+       { "*",   0, (void (*)(...)) pFile,      "" },   /* anything else is a file */
+#else
+    { "-CC", 0, pCC,   "Generate C++ output (default=FALSE)"},
+    { "-cr", 0, pCr,   "Generate cross reference (default=FALSE)"},
+    { "-ck", 1, pCk,   "Set compressed lookahead depth; fast approximate lookahead"},
+    { "-e1", 0, pE1,   "Ambiguities/errors shown in low detail (default)"},
+    { "-e2", 0, pE2,   "Ambiguities/errors shown in more detail"},
+    { "-e3", 0, pE3,   "Ambiguities/errors shown in excrutiating detail"},
+    { "-fe", 1, pFe,   "Rename err.c"},
+    { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"},
+    { "-fl", 1, pFl,   "Rename lexical output--parser.dlg"},
+    { "-fm", 1, pFm,   "Rename mode.h"},
+    { "-fr", 1, pFr,   "Rename remap.h"},
+    { "-ft", 1, pFt,   "Rename tokens.h"},
+    { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"},
+    { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"},
+    { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"},
+    { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
+       { "-gh", 0, pGHdr,      "Generate stdpccts.h for non-ANTLR-generated-files to include"},
+       { "-gk", 0, pDL,        "Generate parsers that delay lookahead fetches 'til needed"},
+       { "-gl", 0, pLI,        "Generate line info about grammar actions in C parser"},
+       { "-gp", 1, pPre,       "Prefix all generated rule functions with a string"},
+    { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
+    { "-gt", 0, pAst,  "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
+    { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
+    { "-k",  1, pLLK,  "Set full LL(k) lookahead depth (default==1)"},
+    { "-o",  1, pOut,  OutputDirectoryOption},
+    { "-p",  0, pPrt,  "Print out the grammar w/o actions (default=no)"},
+    { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
+    { "-pr",0, pPred,  "no longer used; predicates employed if present"},
+    { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
+       { "-rl", 1, pTRes,      "Limit max # of tree nodes used by grammar analysis"},
+       { "-w1", 0, pW1,        "Set the warning level to 1 (default)"},
+       { "-w2", 0, pW2,        "Ambiguities yield warnings even if predicates or (...)? block"},
+       { "-",   0, pStdin,     "Read grammar from stdin" },
+       { "*",   0, pFile,      "" },   /* anything else is a file */
+#endif
+       { NULL,  0, NULL }
+};
+
+void readDescr();
+void cleanUp();
+
+#ifdef __STDC__
+static void buildRulePtr( void );
+static void help( void );
+static void init( void );
+static void CompleteTokenSetRefs( void );
+static void ensure_no_C_file_collisions(char *);
+#else
+static void buildRulePtr( );
+static void help( );
+static void init( );
+static void CompleteTokenSetRefs( );
+static void ensure_no_C_file_collisions();
+#endif
+
+                                                               /* M a i n */
+
+int
+#ifdef __STDC__
+main( int argc, char *argv[] )
+#else
+main( argc, argv )
+int argc;
+char *argv[];
+#endif
+{
+       int i;
+       static char EPSTR[] = "[Ep]";
+
+/*     malloc_debug(8);*/
+    special_inits();
+
+       fprintf(stderr, "Antlr parser generator   Version %s   1989-1995\n", Version);
+       if ( argc == 1 ) { help(); zzDIE; }
+       ProcessArgs(argc-1, &(argv[1]), options);
+
+       /* Fix lookahead depth */
+       /* Compressed lookahead must always be larger than or equal to full lookahead */
+       if ( CLL_k < LL_k  && CLL_k>0 )
+       {
+               warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
+               CLL_k = LL_k;
+       }
+       if ( CLL_k == -1 ) CLL_k = LL_k;
+       OutputLL_k = CLL_k;
+       if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
+               int n;
+               for(n=1; n<CLL_k; n<<=1) {;}
+               OutputLL_k = n;
+       }
+
+       fpTrans = &(C_Trans[0]);                /* Translate to C Language */
+       fpJTrans = &(C_JTrans[0]);
+       init();
+       lexclass(LexStartSymbol);
+
+       readDescr();
+       LastTokenCounted = TokenNum;
+       RemapForcedTokens();
+       if ( CannotContinue ) {cleanUp(); zzDIE;}
+       if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
+       if ( WarningLevel>1 && HdrAction == NULL )
+          warnNoFL("no #header action was found");
+
+       EpToken = addTname(EPSTR);              /* add imaginary token epsilon */
+       set_orel(EpToken, &imag_tokens);
+
+       /* this won't work for hand-built scanners since EofToken is not
+        * known.  Forces EOF to be token type 1.
+        */
+       set_orel(EofToken, &imag_tokens);
+
+       set_size(NumWords(TokenNum-1));
+
+       /* compute the set of all known token types 
+        * It represents the set of tokens from 1 to last_token_num + the
+        * reserved positions above that (if any).  Don't include the set of
+        * imaginary tokens such as the token/error classes or EOF.
+        */
+       {
+               set a;
+               a = set_dup(reserved_positions);
+               for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
+               all_tokens = set_dif(a, imag_tokens);
+               set_free(a);
+       }
+
+       ComputeTokSets();                               /* Compute #tokclass sets */
+       CompleteTokenSetRefs();                 /* Change complex nodes in syn diag */
+
+       if ( CodeGen ) genDefFile();    /* create tokens.h */
+       if ( LexGen ) genLexDescr();    /* create parser.dlg */
+
+       if ( GenStdPccts )
+       {
+               FILE *f = fopen(OutMetaName(stdpccts), "w");
+               if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
+               else
+               {
+                       special_fopen_actions(OutMetaName(stdpccts));
+                       genStdPCCTSIncludeFile(f);
+                       fclose(f);
+               }
+       }
+
+       buildRulePtr();                                 /* create mapping from rule # to RuleBlk junction */
+       ComputeErrorSets();
+       FoLink( (Node *)SynDiag );              /* add follow links to end of all rules */
+       
+       if ( GenCR ) GenCrossRef( SynDiag );
+
+       if ( CodeGen )
+       {
+               if ( SynDiag == NULL )
+               {
+                       warnNoFL("no grammar description recognized");
+                       cleanUp();
+                       zzDIE;
+               }
+               else if ( !GenCC ) {
+                       ErrFile = fopen(OutMetaName(ErrFileName), "w");
+                       require(ErrFile != NULL, "main: can't open err file");
+                       special_fopen_actions(OutMetaName(ErrFileName));
+                       NewSetWd();
+                       GenErrHdr();
+                       TRANS(SynDiag);                 /* Translate to the target language */
+                       DumpSetWd();
+                       DumpRemainingTokSets();
+                       fclose( ErrFile );
+               }
+               else {
+                       strcpy(Parser_h_Name, CurrentClassName);
+                       strcat(Parser_h_Name, ".h");
+                       strcpy(Parser_c_Name, CurrentClassName);
+                       strcat(Parser_c_Name, CPP_FILE_SUFFIX);
+                       ensure_no_C_file_collisions(Parser_c_Name);
+                       Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
+                       require(Parser_h != NULL, "main: can't open class Parserx.h file");
+                       special_fopen_actions(OutMetaName(Parser_h_Name));
+                       Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
+                       require(Parser_c != NULL, "main: can't open class Parserx.c file");
+                       special_fopen_actions(OutMetaName(Parser_c_Name));
+                       GenParser_h_Hdr();
+                       if ( class_before_actions != NULL )
+                       {
+                               ListNode *p;
+                               for (p = class_before_actions->next; p!=NULL; p=p->next)
+                               {
+                                       UserAction *ua = (UserAction *)p->elem;
+                                       dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
+                               }
+                       }
+                       GenParser_c_Hdr();
+                       NewSetWd();
+                       TRANS(SynDiag);                 /* Translate to the target language */
+                       DumpSetWd();
+                       GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
+                       if ( class_after_actions != NULL )
+                       {
+                               ListNode *p;
+                               for (p = class_after_actions->next; p!=NULL; p=p->next)
+                               {
+                                       UserAction *ua = (UserAction *)p->elem;
+                                       dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
+                               }
+                       }
+                       DumpRemainingTokSets();
+                       fprintf(Parser_h, "};\n");
+                       fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName);
+                       fclose( Parser_h );
+                       fclose( Parser_c );
+               }
+       }
+
+       if ( PrintOut )
+       {
+               if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
+               else PRINT(SynDiag);
+       }
+
+       GenRemapFile();                                 /* create remap.h */
+
+       cleanUp();
+       exit(PCCTS_EXIT_SUCCESS);
+}
+
+static void
+#ifdef __STDC__
+init( void )
+#else
+init( )
+#endif
+{
+       SignalEntry *q;
+
+       Tname = newHashTable();
+       Rname = newHashTable();
+       Fcache = newHashTable();
+       Tcache = newHashTable();
+       Sname = newHashTable();
+       /* Add default signal names */
+       q = (SignalEntry *)hash_add(Sname,
+                                                         "NoViableAlt",
+                                                         (Entry *)newSignalEntry("NoViableAlt"));
+       require(q!=NULL, "cannot alloc signal entry");
+       q->signum = sigNoViableAlt;
+       q = (SignalEntry *)hash_add(Sname,
+                                                         "MismatchedToken",
+                                                         (Entry *)newSignalEntry("MismatchedToken"));
+       require(q!=NULL, "cannot alloc signal entry");
+       q->signum = sigMismatchedToken;
+       q = (SignalEntry *)hash_add(Sname,
+                                                         "NoSemViableAlt",
+                                                         (Entry *)newSignalEntry("NoSemViableAlt"));
+       require(q!=NULL, "cannot alloc signal entry");
+       q->signum = sigNoSemViableAlt;
+       
+       reserved_positions = empty;
+       all_tokens = empty;
+       imag_tokens = empty;
+       tokclasses = empty;
+       TokenStr = (char **) calloc(TSChunk, sizeof(char *));
+       require(TokenStr!=NULL, "main: cannot allocate TokenStr");
+       FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
+       require(FoStack!=NULL, "main: cannot allocate FoStack");
+       FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
+       require(FoTOS!=NULL, "main: cannot allocate FoTOS");
+       Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
+       require(Cycles!=NULL, "main: cannot allocate Cycles List");
+}
+
+static void
+#ifdef __STDC__
+help( void )
+#else
+help( )
+#endif
+{
+       Opt *p = options;
+       fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
+       while ( *(p->option) != '*' )
+       {
+               fprintf(stderr, "\t%-4s %s   %s\n",
+                                               p->option,
+                                               (p->arg)?"___":"   ",
+                                               p->descr);
+               p++;
+       }
+}
+
+/* The RulePtr array is filled in here.  RulePtr exists primarily
+ * so that sets of rules can be maintained for the FOLLOW caching
+ * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n
+ * to a pointer to its RuleBlk junction where n is the number of rules.
+ */
+static void
+#ifdef __STDC__
+buildRulePtr( void )
+#else
+buildRulePtr( )
+#endif
+{
+       int r=1;
+       Junction *p  = SynDiag;
+       RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
+       require(RulePtr!=NULL, "cannot allocate RulePtr array");
+       
+       while ( p!=NULL )
+       {
+               require(r<=NumRules, "too many rules???");
+               RulePtr[r++] = p;
+               p = (Junction *)p->p2;
+       }
+}
+
+void
+#ifdef __STDC__
+dlgerror(const char *s)
+#else
+dlgerror(s)
+char *s;
+#endif
+{
+       fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+       fprintf(stderr, " lexical error: %s (text was '%s')\n",
+                                       ((s == NULL) ? "Lexical error" : s), zzlextext);
+}
+
+void
+#ifdef __STDC__
+readDescr( void )
+#else
+readDescr( )
+#endif
+{
+       zzerr = dlgerror;
+       input = NextFile();
+       if ( input==NULL ) fatal("No grammar description found (exiting...)");
+       ANTLR(grammar(), input);
+}
+
+FILE *
+#ifdef __STDC__
+NextFile( void )
+#else
+NextFile( )
+#endif
+{
+       FILE *f;
+
+       for (;;)
+       {
+               CurFile++;
+               if ( CurFile >= NumFiles ) return(NULL);
+               if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
+               f = fopen(FileStr[CurFile], "r");
+               if ( f == NULL )
+               {
+                       warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
+               }
+               else
+               {
+                       return(f);
+               }
+       }
+}
+
+/*
+ * Return a string corresponding to the output file name associated
+ * with the input file name passed in.
+ *
+ * Observe the following rules:
+ *
+ *             f.e             --> f".c"
+ *             f               --> f".c"
+ *             f.              --> f".c"
+ *             f.e.g   --> f.e".c"
+ *
+ * Where f,e,g are arbitrarily long sequences of characters in a file
+ * name.
+ *
+ * In other words, if a ".x" appears on the end of a file name, make it
+ * ".c".  If no ".x" appears, append ".c" to the end of the file name.
+ *
+ * C++ mode using .cpp not .c.
+ *
+ * Use malloc() for new string.
+ */
+char *
+#ifdef __STDC__
+outname( char *fs )
+#else
+outname( fs )
+char *fs;
+#endif
+{
+       static char buf[MaxFileName+1];
+       char *p;
+       require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
+
+       p = buf;
+       strcpy(buf, fs);
+       while ( *p != '\0' )  {p++;}                    /* Stop on '\0' */
+       while ( *p != '.' && p != buf ) {--p;}  /* Find '.' */
+       if ( p != buf ) *p = '\0';                              /* Found '.' */
+       require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");
+       if ( GenCC ) strcat(buf, CPP_FILE_SUFFIX);
+       else strcat(buf, ".c");
+       return( buf );
+}
+
+void
+#ifdef __STDC__
+fatalFL( char *err_, char *f, int l )
+#else
+fatalFL( err_, f, l )
+char *err_;
+char *f;
+int l;
+#endif
+{
+       fprintf(stderr, ErrHdr, f, l);
+       fprintf(stderr, " %s\n", err_);
+       cleanUp();
+       exit(PCCTS_EXIT_FAILURE);
+}
+
+void
+#ifdef __STDC__
+fatal_intern( char *err_, char *f, int l )
+#else
+fatal_intern( err_, f, l )
+char *err_;
+char *f;
+int l;
+#endif
+{
+       fprintf(stderr, ErrHdr, f, l);
+       fprintf(stderr, " #$%%*&@# internal error: %s\n", err_);
+       fprintf(stderr, ErrHdr, f, l);
+       fprintf(stderr, " [complain to nearest government official\n");
+       fprintf(stderr, ErrHdr, f, l);
+       fprintf(stderr, "  or send hate-mail to parrt@parr-research.com;\n");
+       fprintf(stderr, ErrHdr, f, l);
+       fprintf(stderr, "  please pray to the ``bug'' gods that there is a trival fix.]\n");
+       cleanUp();
+       exit(PCCTS_EXIT_FAILURE);
+}
+
+void
+#ifdef __STDC__
+cleanUp( void )
+#else
+cleanUp( )
+#endif
+{
+       if ( DefFile != NULL) fclose( DefFile );
+}
+
+/* sprintf up to 3 strings */
+char *
+#ifdef __STDC__
+eMsg3( char *s, char *a1, char *a2, char *a3 )
+#else
+eMsg3( s, a1, a2, a3 )
+char *s;
+char *a1;
+char *a2;
+char *a3;
+#endif
+{
+       static char buf[250];                   /* DANGEROUS as hell !!!!!! */
+       
+       sprintf(buf, s, a1, a2, a3);
+       return( buf );
+}
+
+/* sprintf a decimal */
+char *
+#ifdef __STDC__
+eMsgd( char *s, int d )
+#else
+eMsgd( s, d )
+char *s;
+int d;
+#endif
+{
+       static char buf[250];                   /* DANGEROUS as hell !!!!!! */
+       
+       sprintf(buf, s, d);
+       return( buf );
+}
+
+void
+#ifdef __STDC__
+s_fprT( FILE *f, set e )
+#else
+s_fprT( f, e )
+FILE *f;
+set e;
+#endif
+{
+       register unsigned *p;
+       unsigned *q;
+
+       if ( set_nil(e) ) return;
+       if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
+       fprintf(f, "{");
+       while ( *p != nil )
+       {
+               fprintf(f, " %s", TerminalString(*p));
+               p++;
+       }
+       fprintf(f, " }");
+       free((char *)q);
+}
+
+/* Return the token name or regular expression for a token number. */
+char *
+#ifdef __STDC__
+TerminalString( int token )
+#else
+TerminalString( token )
+int token;
+#endif
+{
+       int j;
+
+       /* look in all lexclasses for the token */
+       if ( TokenString(token) != NULL ) return TokenString(token);
+       for (j=0; j<NumLexClasses; j++)
+       {
+               lexmode(j);
+               if ( ExprString(token) != NULL ) return ExprString(token);
+       }
+       require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
+       return "invalid";
+}
+
+                    /* S i m p l e  I n t  S t a c k */
+
+void
+#ifdef __STDC__
+pushint( int i )
+#else
+pushint( i )
+int i;
+#endif
+{
+       require(isp>0, "pushint: stack overflow");
+       istack[--isp] = i;
+}
+
+int
+#ifdef __STDC__
+popint( void )
+#else
+popint( )
+#endif
+{
+       require(isp<MAX_INT_STACK, "popint: stack underflow");
+       return istack[isp++];
+}
+
+int
+#ifdef __STDC__
+istacksize( void )
+#else
+istacksize( )
+#endif
+{
+       return MAX_INT_STACK-isp;
+}
+
+void
+#ifdef __STDC__
+istackreset( void )
+#else
+istackreset( )
+#endif
+{
+       isp = MAX_INT_STACK;
+}
+
+int
+#ifdef __STDC__
+istackempty( void )
+#else
+istackempty( )
+#endif
+{
+       return isp==MAX_INT_STACK;
+}
+
+int
+#ifdef __STDC__
+topint( void )
+#else
+topint( )
+#endif
+{
+       require(isp<MAX_INT_STACK, "topint: stack underflow");
+       return istack[isp];
+}
+
+void
+#ifdef __STDC__
+ProcessArgs( int argc, char **argv, Opt *options )
+#else
+ProcessArgs( argc, argv, options )
+int argc;
+char **argv;
+Opt *options;
+#endif
+{
+       Opt *p;
+       require(argv!=NULL, "ProcessArgs: command line NULL");
+
+       while ( argc-- > 0 )
+       {
+               p = options;
+               while ( p->option != NULL )
+               {
+                       if ( strcmp(p->option, "*") == 0 ||
+                                strcmp(p->option, *argv) == 0 )
+                       {
+                               if ( p->arg )
+                               {
+                                       (*p->process)( *argv, *(argv+1) );
+                                       argv++;
+                                       argc--;
+                               }
+                               else
+                                       (*p->process)( *argv );
+                               break;
+                       }
+                       p++;
+               }
+               argv++;
+       }
+}
+
+/* Go back into the syntax diagram and compute all meta tokens; i.e.
+ * turn all '.', ranges, token class refs etc... into actual token sets
+ */
+static void
+CompleteTokenSetRefs()
+{
+       ListNode *p;
+
+       if ( MetaTokenNodes==NULL ) return;
+       for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
+       {
+               set a,b;
+
+               TokNode *q = (TokNode *)p->elem;
+               if ( q->wild_card )
+               {
+                       q->tset = all_tokens;
+               }
+               else if ( q->tclass!=NULL )
+               {
+                       if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
+                       else q->tset = q->tclass->tset;
+               }
+               else if ( q->upper_range!=0 )
+               {
+                       /* we have a range on our hands: make a set from q->token .. q->upper_range */
+                       int i;
+                       a = empty;
+                       for (i=q->token; i<=(int)q->upper_range; i++) { set_orel(i, &a); }
+                       q->tset = a;
+               }
+               /* at this point, it can only be a complemented single token */
+               else if ( q->complement )
+               {
+                       a = set_of(q->token);
+                       b = set_dif(all_tokens, a);
+                       set_free(a);
+                       q->tset=b;
+               }
+               else fatal("invalid meta token");
+       }
+}
+
+char *
+#ifdef __STDC__
+OutMetaName(char *n)
+#else
+OutMetaName(n)
+char *n;
+#endif
+{
+       static char buf[MaxFileName+1];
+
+       if ( strcmp(OutputDirectory,TopDirectory)==0 ) return n;
+       strcpy(buf, OutputDirectory);
+       if ( strcmp(&buf[strlen(buf) - 1], DirectorySymbol ) )
+               strcat(buf, DirectorySymbol);
+       strcat(buf, n);
+       return buf;
+}
+
+static void
+#ifdef __STDC__
+ensure_no_C_file_collisions(char *class_c_file)
+#else
+ensure_no_C_file_collisions(class_c_file)
+char *class_c_file;
+#endif
+{
+       int i;
+
+       for (i=0; i<NumFiles; i++)
+       {
+#ifdef PC
+               /* assume that file names are case insensitive */
+               if ( stricmp(outname(FileStr[i]), class_c_file)==0 )
+#else
+               if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
+#endif
+               {
+                       fatal(eMsg1("class def output file conflicts with parser output file: %s",
+                                               outname(FileStr[i])));
+               }
+       }
+}
+
+void
+#ifdef __STDC__
+warnNoFL(char *err)
+#else
+warnNoFL(err)
+char *err;
+#endif
+{
+       fprintf(stderr, "warning: %s\n", err);
+}
+
+void
+#ifdef __STDC__
+warnFL(char *err,char *f,int l)
+#else
+warnFL(err,f,l)
+char *f;
+int l;
+char *err;
+#endif
+{
+       fprintf(stderr, ErrHdr, f, l);                                          
+       fprintf(stderr, " warning: %s\n", err);
+}
+
+void
+#ifdef __STDC__
+warn(char *err)                                                                                                
+#else
+warn(err)                                                                                              
+char *err;
+#endif
+{
+       /* back up the file number if we hit an error at the end of the last file */
+       if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+       fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+       fprintf(stderr, " warning: %s\n", err);
+}
+
+void
+#ifdef __STDC__
+warnNoCR( char *err )
+#else
+warnNoCR( err )                                                                                        
+char *err;
+#endif
+{
+       /* back up the file number if we hit an error at the end of the last file */
+       if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+       fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+       fprintf(stderr, " warning: %s", err);
+}
+
+void
+#ifdef __STDC__
+errNoFL(char *err)
+#else
+errNoFL(err)
+char *err;
+#endif
+{
+       fprintf(stderr, "error: %s\n", err);
+}
+
+void
+#ifdef __STDC__
+errFL(char *err,char *f,int l)
+#else
+errFL(err,f,l)
+char *err;
+char *f;
+int l;
+#endif
+{
+       fprintf(stderr, ErrHdr, f, l);                                          
+       fprintf(stderr, " error: %s\n", err);
+}
+
+void
+#ifdef __STDC__
+err(char *err)                                                                                         
+#else
+err(err)                                                                                               
+char *err;
+#endif
+{
+       /* back up the file number if we hit an error at the end of the last file */
+       if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+       fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+       fprintf(stderr, " error: %s\n", err);
+}
+
+void
+#ifdef __STDC__
+errNoCR( char *err )                                                                                   
+#else
+errNoCR( err )                                                                                 
+char *err;
+#endif
+{
+       /* back up the file number if we hit an error at the end of the last file */
+       if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+       fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+       fprintf(stderr, " error: %s", err);
+}
+
+UserAction *
+#ifdef __STDC__
+newUserAction(char *s)
+#else
+newUserAction(s)
+char *s;
+#endif
+{
+       UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
+       require(ua!=NULL, "cannot allocate UserAction");
+
+       ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+       strcpy(ua->action, s);
+       return ua;
+}
+
+/* Added by TJP September 1994 */
+/* Take in file.h and return file_h; names w/o '.'s are left alone */
+char *
+#ifdef __USE_PROTOS
+gate_symbol(char *name)
+#else
+gate_symbol(name)
+char *name;
+#endif
+{
+       static char buf[100];
+       char *p;
+       sprintf(buf, "%s", name);
+
+       for (p=buf; *p!='\0'; p++)
+       {
+               if ( *p=='.' ) *p = '_';
+       }
+       return buf;
+}
+
+char *
+#ifdef __USE_PROTOS
+makeAltID(int blockid, int altnum)
+#else
+makeAltID(blockid, altnum)
+int blockid;
+int altnum;
+#endif
+{
+       static char buf[100];
+       char *p;
+       sprintf(buf, "_blk%d_alt%d", blockid, altnum);
+       p = (char *)malloc(strlen(buf)+1);
+       strcpy(p, buf);
+       return p;
+}
diff --git a/antlr/misc.c b/antlr/misc.c
new file mode 100755 (executable)
index 0000000..7dda4ec
--- /dev/null
@@ -0,0 +1,1325 @@
+/*
+ * misc.c
+ *
+ * Manage tokens, regular expressions.
+ * Print methods for debugging
+ * Compute follow lists onto tail ends of rules.
+ *
+ * The following functions are visible:
+ *
+ *             int             addTname(char *);               Add token name
+ *             int             addTexpr(char *);               Add token expression
+ *             int             Tnum(char *);                   Get number of expr/token
+ *             void    Tklink(char *, char *); Link a name with an expression
+ *             int             hasAction(expr);                Does expr already have action assigned?
+ *             void    setHasAction(expr);             Indicate that expr now has an action
+ *             Entry   *newEntry(char *,int);  Create new table entry with certain size
+ *             void    list_add(ListNode **list, char *e)
+ *             void    list_apply(ListNode *list, void (*f)())
+ *             void    lexclass(char *m);              switch to new/old lexical class
+ *             void    lexmode(int i);                 switch to old lexical class i
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+#include <stdio.h>
+#ifdef __cplusplus
+#ifndef __STDC__
+#define __STDC__
+#endif
+#endif
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+
+static int tsize=TSChunk;              /* size of token str arrays */
+
+static void
+#ifdef __STDC__
+RemapForcedTokensInSyntaxDiagram(Node *);
+#else
+RemapForcedTokensInSyntaxDiagram();
+#endif
+
+                               /* T o k e n  M a n i p u l a t i o n */
+
+/*
+ * add token 't' to the TokenStr/Expr array.  Make more room if necessary.
+ * 't' is either an expression or a token name.
+ *
+ * There is only one TokenStr array, but multiple ExprStr's.  Therefore,
+ * for each lex class (element of lclass) we must extend the ExprStr array.
+ * ExprStr's and TokenStr are always all the same size.
+ *
+ * Also, there is a Texpr hash table for each automaton.
+ */
+static void
+#ifdef __STDC__
+Ttrack( char *t )
+#else
+Ttrack( t )
+char *t;
+#endif
+{
+       if ( TokenNum >= tsize )        /* terminal table overflow? */
+       {
+               char **p;
+               int i, more, j;
+
+               more = TSChunk * (1 + ((TokenNum-tsize) / TSChunk));
+               tsize += more;
+               TokenStr = (char **) realloc((char *)TokenStr, tsize*sizeof(char *));
+               require(TokenStr != NULL, "Ttrack: can't extend TokenStr");
+               for (i=0; i<NumLexClasses; i++)
+               {
+                       lclass[i].exprs = (char **)
+                                                         realloc((char *)lclass[i].exprs, tsize*sizeof(char *));
+                       require(lclass[i].exprs != NULL, "Ttrack: can't extend ExprStr");
+                       for (p= &lclass[i].exprs[tsize-more],j=1; j<=more; j++) *p++ = NULL;
+               }
+               for (p= &TokenStr[tsize-more],i=1; i<=more; i++) *p++ = NULL;
+               lexmode( CurrentLexClass ); /* reset ExprStr in case table moved */
+       }
+       /* note: we use the actual ExprStr/TokenStr array
+        * here as TokenInd doesn't exist yet
+        */
+       if ( *t == '"' ) ExprStr[TokenNum] = t;
+       else TokenStr[TokenNum] = t;
+}
+
+static Expr *
+#ifdef __STDC__
+newExpr( char *e )
+#else
+newExpr( e )
+char *e;
+#endif
+{
+       Expr *p = (Expr *) calloc(1, sizeof(Expr));
+       require(p!=NULL, "newExpr: cannot alloc Expr node");
+
+       p->expr = e;
+       p->lclass = CurrentLexClass;
+       return p;
+}
+
+/* switch to lexical class/mode m.  This amounts to creating a new
+ * lex mode if one does not already exist and making ExprStr point
+ * to the correct char string array.  We must also switch Texpr tables.
+ *
+ * BTW, we need multiple ExprStr arrays because more than one automaton
+ * may have the same label for a token, but with different expressions.
+ * We need to track an expr for each automaton.  If we disallowed this
+ * feature, only one ExprStr would be required.
+ */
+void
+#ifdef __STDC__
+lexclass( char *m )
+#else
+lexclass( m )
+char *m;
+#endif
+{
+       int i;
+       TermEntry *p;
+       static char EOFSTR[] = "\"@\"";
+
+       if ( hash_get(Tname, m) != NULL )
+       {
+               warn(eMsg1("lexclass name conflicts with token/errclass label '%s'",m));
+       }
+       /* does m already exist? */
+       i = LexClassIndex(m);
+       if ( i != -1 ) {lexmode(i); return;}
+       /* must make new one */
+       NumLexClasses++;
+       CurrentLexClass = NumLexClasses-1;
+       require(NumLexClasses<=MaxLexClasses, "number of allowable lexclasses exceeded\nIncrease MaxLexClasses in generic.h and recompile all C files");
+       lclass[CurrentLexClass].classnum = m;
+       lclass[CurrentLexClass].exprs = (char **) calloc(tsize, sizeof(char *));
+       require(lclass[CurrentLexClass].exprs!=NULL,
+                       "lexclass: cannot allocate ExprStr");
+       lclass[CurrentLexClass].htable = newHashTable();
+       ExprStr = lclass[CurrentLexClass].exprs;
+       Texpr = lclass[CurrentLexClass].htable;
+       /* define EOF for each automaton */
+       p = newTermEntry( EOFSTR );
+       p->token = EofToken;    /* couldn't have remapped tokens yet, use EofToken */
+       hash_add(Texpr, EOFSTR, (Entry *)p);
+       list_add(&ExprOrder, (void *)newExpr(EOFSTR));
+       /* note: we use the actual ExprStr array
+        * here as TokenInd doesn't exist yet
+        */
+       ExprStr[EofToken] = EOFSTR;
+}
+
+void
+#ifdef __STDC__
+lexmode( int i )
+#else
+lexmode( i )
+int i;
+#endif
+{
+       require(i<NumLexClasses, "lexmode: invalid mode");
+       ExprStr = lclass[i].exprs;
+       Texpr = lclass[i].htable;
+       CurrentLexClass = i;
+}
+
+/* return index into lclass array of lexical class. return -1 if nonexistent */
+int
+#ifdef __STDC__
+LexClassIndex( char *cl )
+#else
+LexClassIndex( cl )
+char *cl;
+#endif
+{
+       int i;
+
+       for (i=0; i<NumLexClasses; i++)
+       {
+               if ( strcmp(lclass[i].classnum, cl) == 0 ) return i;
+       }
+       return -1;
+}
+
+int
+#ifdef __STDC__
+hasAction( char *expr )
+#else
+hasAction( expr )
+char *expr;
+#endif
+{
+       TermEntry *p;
+       require(expr!=NULL, "hasAction: invalid expr");
+
+       p = (TermEntry *) hash_get(Texpr, expr);
+       require(p!=NULL, eMsg1("hasAction: expr '%s' doesn't exist",expr));
+       return (p->action!=NULL);
+}
+
+void
+#ifdef __STDC__
+setHasAction( char *expr, char *action )
+#else
+setHasAction( expr, action )
+char *expr;
+char *action;
+#endif
+{
+       TermEntry *p;
+       require(expr!=NULL, "setHasAction: invalid expr");
+
+       p = (TermEntry *) hash_get(Texpr, expr);
+       require(p!=NULL, eMsg1("setHasAction: expr '%s' doesn't exist",expr));
+       p->action = action;
+}
+
+ForcedToken *
+#ifdef __STDC__
+newForcedToken(char *token, int tnum)
+#else
+newForcedToken(token, tnum)
+char *token;
+int tnum;
+#endif
+{
+       ForcedToken *ft = (ForcedToken *) calloc(1, sizeof(ForcedToken));
+       require(ft!=NULL, "out of memory");
+       ft->token = token;
+       ft->tnum = tnum;
+       return ft;
+}
+
+/*
+ * Make a token indirection array that remaps token numbers and then walk
+ * the appropriate symbol tables and SynDiag to change token numbers
+ */
+void
+#ifdef __STDC__
+RemapForcedTokens(void)
+#else
+RemapForcedTokens()
+#endif
+{
+       ListNode *p;
+       ForcedToken *q;
+       unsigned int max_token_number=0;
+       int i;
+
+       if ( ForcedTokens == NULL ) return;
+
+       /* find max token num */
+       for (p = ForcedTokens->next; p!=NULL; p=p->next)
+       {
+               q = (ForcedToken *) p->elem;
+               if ( q->tnum > max_token_number ) max_token_number = q->tnum;
+       }
+       fprintf(stderr, "max token number is %d\n", max_token_number);
+
+       /* make token indirection array */
+       TokenInd = (int *) calloc(max_token_number+1, sizeof(int));
+       LastTokenCounted = TokenNum;
+       TokenNum = max_token_number+1;
+       require(TokenInd!=NULL, "RemapForcedTokens: cannot allocate TokenInd");
+
+       /* fill token indirection array and change token id htable ; swap token indices */
+       for (i=1; i<TokenNum; i++) TokenInd[i] = i;
+       for (p = ForcedTokens->next; p!=NULL; p=p->next)
+       {
+               TermEntry *te;
+               int old_pos, t;
+
+               q = (ForcedToken *) p->elem;
+               fprintf(stderr, "%s forced to %d\n", q->token, q->tnum);
+               te = (TermEntry *) hash_get(Tname, q->token);
+               require(te!=NULL, "RemapForcedTokens: token not in hash table");
+               old_pos = te->token;
+               fprintf(stderr, "Before: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);
+               fprintf(stderr, "Before: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);
+               q = (ForcedToken *) p->elem;
+               t = TokenInd[old_pos];
+               TokenInd[old_pos] = q->tnum;
+               TokenInd[q->tnum] = t;
+               te->token = q->tnum;            /* update token type id symbol table */
+               fprintf(stderr, "After: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);
+               fprintf(stderr, "After: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);
+
+               /* Change the token number in the sym tab entry for the exprs
+                * at the old position of the token id and the target position
+                */
+               /* update expr at target (if any) of forced token id */
+               if ( q->tnum < TokenNum )       /* is it a valid position? */
+               {
+                       for (i=0; i<NumLexClasses; i++)
+                       {
+                               if ( lclass[i].exprs[q->tnum]!=NULL )
+                               {
+                                       /* update the symbol table for this expr */
+                                       TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[q->tnum]);
+                                       require(e!=NULL, "RemapForcedTokens: expr not in hash table");
+                                       e->token = old_pos;
+                                       fprintf(stderr, "found expr '%s' at target %d in lclass[%d]; changed to %d\n",
+                                                       lclass[i].exprs[q->tnum], q->tnum, i, old_pos);
+                               }
+                       }
+               }
+               /* update expr at old position (if any) of forced token id */
+               for (i=0; i<NumLexClasses; i++)
+               {
+                       if ( lclass[i].exprs[old_pos]!=NULL )
+                       {
+                               /* update the symbol table for this expr */
+                               TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[old_pos]);
+                               require(e!=NULL, "RemapForcedTokens: expr not in hash table");
+                               e->token = q->tnum;
+                               fprintf(stderr, "found expr '%s' for id %s in lclass[%d]; changed to %d\n",
+                                               lclass[i].exprs[old_pos], q->token, i, q->tnum);
+                       }
+               }
+       }
+
+       /* Update SynDiag */
+       RemapForcedTokensInSyntaxDiagram((Node *)SynDiag);
+}
+
+static void
+#ifdef __STDC__
+RemapForcedTokensInSyntaxDiagram(Node *p)
+#else
+RemapForcedTokensInSyntaxDiagram(p)
+Node *p;
+#endif
+{
+       Junction *j = (Junction *) p;
+       RuleRefNode *r = (RuleRefNode *) p;
+       TokNode *t = (TokNode *)p;
+
+       if ( p==NULL ) return;
+       require(p->ntype>=1 && p->ntype<=NumNodeTypes,  "Remap...: invalid diagram node");
+       switch ( p->ntype )
+       {
+               case nJunction :
+                       if ( j->visited ) return;
+                       if ( j->jtype == EndRule ) return;
+                       j->visited = TRUE;
+                       RemapForcedTokensInSyntaxDiagram( j->p1 );
+                       RemapForcedTokensInSyntaxDiagram( j->p2 );
+                       j->visited = FALSE;
+                       return;
+               case nRuleRef :
+                       RemapForcedTokensInSyntaxDiagram( r->next );
+                       return;
+               case nToken :
+                       if ( t->remapped ) return;      /* we've been here before */
+                       t->remapped = 1;
+                       fprintf(stderr, "remapping %d to %d\n", t->token, TokenInd[t->token]);
+                       t->token = TokenInd[t->token];
+                       RemapForcedTokensInSyntaxDiagram( t->next );
+                       return;
+               case nAction :
+                       RemapForcedTokensInSyntaxDiagram( ((ActionNode *)p)->next );
+                       return;
+               default :
+                       fatal_internal("invalid node type");
+       }
+}
+
+/*
+ * Add a token name.  Return the token number associated with it.  If it already
+ * exists, then return the token number assigned to it.
+ *
+ * Track the order in which tokens are found so that the DLG output maintains
+ * that order.  It also lets us map token numbers to strings.
+ */
+int
+#ifdef __STDC__
+addTname( char *token )
+#else
+addTname( token )
+char *token;
+#endif
+{
+       TermEntry *p;
+       require(token!=NULL, "addTname: invalid token name");
+
+       if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;
+       p = newTermEntry( token );
+       Ttrack( p->str );
+       p->token = TokenNum++;
+       hash_add(Tname, token, (Entry *)p);
+       return p->token;
+}
+
+/* This is the same as addTname except we force the TokenNum to be tnum.
+ * We don't have to use the Forced token stuff as no tokens will have
+ * been defined with #tokens when this is called.  This is only called
+ * when a #tokdefs meta-op is used.
+ */
+int
+#ifdef __STDC__
+addForcedTname( char *token, int tnum )
+#else
+addForcedTname( token, tnum )
+char *token;
+int tnum;
+#endif
+{
+       TermEntry *p;
+       require(token!=NULL, "addTname: invalid token name");
+
+       if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;
+       p = newTermEntry( token );
+       Ttrack( p->str );
+       p->token = tnum;
+       hash_add(Tname, token, (Entry *)p);
+       return p->token;
+}
+
+/*
+ * Add a token expr.  Return the token number associated with it.  If it already
+ * exists, then return the token number assigned to it.
+ */
+int
+#ifdef __STDC__
+addTexpr( char *expr )
+#else
+addTexpr( expr )
+char *expr;
+#endif
+{
+       TermEntry *p;
+       require(expr!=NULL, "addTexpr: invalid regular expression");
+
+       if ( (p=(TermEntry *)hash_get(Texpr, expr)) != NULL ) return p->token;
+       p = newTermEntry( expr );
+       Ttrack( p->str );
+       /* track the order in which they occur */
+       list_add(&ExprOrder, (void *)newExpr(p->str));
+       p->token = TokenNum++;
+       hash_add(Texpr, expr, (Entry *)p);
+       return p->token;
+}
+
+/* return the token number of 'term'.  Return 0 if no 'term' exists */
+int
+#ifdef __STDC__
+Tnum( char *term )
+#else
+Tnum( term )
+char *term;
+#endif
+{
+       TermEntry *p;
+       require(term!=NULL, "Tnum: invalid terminal");
+       
+       if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term);
+       else p = (TermEntry *) hash_get(Tname, term);
+       if ( p == NULL ) return 0;
+       else return p->token;
+}
+
+/* associate a Name with an expr.  If both have been already assigned
+ * token numbers, then an error is reported.  Add the token or expr
+ * that has not been added if no error.  This 'represents' the #token
+ * ANTLR pseudo-op.  If both have not been defined, define them both
+ * linked to same token number.
+ */
+void
+#ifdef __STDC__
+Tklink( char *token, char *expr )
+#else
+Tklink( token, expr )
+char *token;
+char *expr;
+#endif
+{
+       TermEntry *p, *q;
+       require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr");
+
+       p = (TermEntry *) hash_get(Tname, token);
+       q = (TermEntry *) hash_get(Texpr, expr);
+       if ( p != NULL && q != NULL )   /* both defined */
+       {
+               warn( eMsg2("token name %s and rexpr %s already defined; ignored",
+                                       token, expr) );
+               return;
+       }
+       if ( p==NULL && q==NULL )               /* both not defined */
+       {
+               int t = addTname( token );
+               q = newTermEntry( expr );
+               hash_add(Texpr, expr, (Entry *)q);
+               q->token = t;
+               /* note: we use the actual ExprStr array
+                * here as TokenInd doesn't exist yet
+                */
+               ExprStr[t] = q->str;
+               /* track the order in which they occur */
+               list_add(&ExprOrder, (void *)newExpr(q->str));
+               return;
+       }
+       if ( p != NULL )                                /* one is defined, one is not */
+       {
+               q = newTermEntry( expr );
+               hash_add(Texpr, expr, (Entry *)q);
+               q->token = p->token;
+               ExprStr[p->token] = q->str;     /* both expr and token str defined now */
+               list_add(&ExprOrder, (void *)newExpr(q->str));
+       }
+       else                                                    /* trying to associate name with expr here*/
+       {
+               p = newTermEntry( token );
+               hash_add(Tname, token, (Entry *)p);
+               p->token = q->token;
+               TokenStr[p->token] = p->str;/* both expr and token str defined now */
+       }
+}
+
+/*
+ * Given a string, this function allocates and returns a pointer to a
+ * hash table record of size 'sz' whose "str" pointer is reset to a position
+ * in the string table.
+ */
+Entry *
+#ifdef __STDC__
+newEntry( char *text, int sz )
+#else
+newEntry( text, sz )
+char *text;
+int sz;
+#endif
+{
+       Entry *p;
+       require(text!=NULL, "new: NULL terminal");
+       
+       if ( (p = (Entry *) calloc(1,sz)) == 0 )
+       {
+               fatal_internal("newEntry: out of memory for terminals\n");
+               exit(PCCTS_EXIT_FAILURE);
+       }
+       p->str = mystrdup(text);
+       
+       return(p);
+}
+
+/*
+ * add an element to a list.
+ *
+ * Any non-empty list has a sentinel node whose 'elem' pointer is really
+ * a pointer to the last element.  (i.e. length(list) = #elemIn(list)+1).
+ * Elements are appended to the list.
+ */
+void
+#ifdef __STDC__
+list_add( ListNode **list, void *e )
+#else
+list_add( list, e )
+ListNode **list;
+void *e;
+#endif
+{
+       ListNode *p, *tail;
+       require(e!=NULL, "list_add: attempting to add NULL list element");
+
+       p = newListNode;
+       require(p!=NULL, "list_add: cannot alloc new list node");
+       p->elem = e;
+       if ( *list == NULL )
+       {
+               ListNode *sentinel = newListNode;
+               require(sentinel!=NULL, "list_add: cannot alloc sentinel node");
+               *list=sentinel;
+               sentinel->next = p;
+               sentinel->elem = (char *)p;             /* set tail pointer */
+       }
+       else                                                            /* find end of list */
+       {
+               tail = (ListNode *) (*list)->elem;      /* get tail pointer */
+               tail->next = p;
+               (*list)->elem = (char *) p;             /* reset tail */
+       }
+}
+
+void
+#ifdef __STDC__
+list_apply( ListNode *list, void (*f)(void *) )
+#else
+list_apply( list, f )
+ListNode *list;
+void (*f)();
+#endif
+{
+       ListNode *p;
+       require(f!=NULL, "list_apply: NULL function to apply");
+
+       if ( list == NULL ) return;
+       for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem );
+}
+
+                       /* F O L L O W  C y c l e  S t u f f */
+               
+/* make a key based upon (rulename, computation, k value).
+ * Computation values are 'i'==FIRST, 'o'==FOLLOW.
+ */
+char *
+#ifdef __STDC__
+Fkey( char *rule, int computation, int k )
+#else
+Fkey( rule, computation, k )
+char *rule;
+int computation;
+int k;
+#endif
+{
+       static char key[MaxRuleName+2+1];
+       int i;
+       
+       if ( k > 255 ) 
+               fatal("k>255 is too big for this implementation of ANTLR!\n");
+       if ( (i=strlen(rule)) > MaxRuleName )
+               fatal( eMsgd("rule name > max of %d\n", MaxRuleName) );
+       strcpy(key,rule);
+       key[i] = (int) computation;
+       key[i+1] = (char) ((unsigned int) k);
+       key[i+2] = '\0';
+       return key;
+}
+
+/* Push a rule onto the kth FOLLOW stack */
+void
+#ifdef __STDC__
+FoPush( char *rule, int k )
+#else
+FoPush( rule, k )
+char *rule;
+int k;
+#endif
+{
+       RuleEntry *r;
+       require(rule!=NULL, "FoPush: tried to push NULL rule");
+       require(k<=CLL_k,       "FoPush: tried to access non-existent stack");
+
+       /*fprintf(stderr, "FoPush(%s)\n", rule);*/
+       r = (RuleEntry *) hash_get(Rname, rule);
+       if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );}
+       if ( FoStack[k] == NULL )               /* Does the kth stack exist yet? */
+       {
+               /*fprintf(stderr, "allocating FoStack\n");*/
+               FoStack[k] = (int *) calloc(FoStackSize, sizeof(int));
+               require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n");
+       }
+       if ( FoTOS[k] == NULL )
+       {
+               FoTOS[k]=FoStack[k];
+               *(FoTOS[k]) = r->rulenum;
+       }
+       else
+       {
+#ifdef MEMCHK
+               require(valid(FoStack[k]), "FoPush: invalid FoStack");
+#endif
+               if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) )
+                       fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n",
+                                               FoStackSize) );
+               require(FoTOS[k]>=FoStack[k],
+                               eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox",
+                                         rule));
+               ++(FoTOS[k]);
+               *(FoTOS[k]) = r->rulenum;
+       }
+       {
+               /*
+               int *p;
+               fprintf(stderr, "FoStack[k=%d]:\n", k);
+               for (p=FoStack[k]; p<=FoTOS[k]; p++)
+               {
+                       fprintf(stderr, "\t%s\n", RulePtr[*p]->rname);
+               }
+               */
+       }
+}
+
+/* Pop one rule off of the FOLLOW stack.  TOS ptr is NULL if empty. */
+void
+#ifdef __STDC__
+FoPop( int k )
+#else
+FoPop( k )
+int k;
+#endif
+{
+       require(k<=CLL_k, "FoPop: tried to access non-existent stack");
+       /*fprintf(stderr, "FoPop\n");*/
+       require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),
+                       "FoPop: FoStack stack-ptr is playing out of its sandbox");
+       if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL;
+       else (FoTOS[k])--;
+}
+
+/* Compute FOLLOW cycle.
+ * Mark all FOLLOW sets for rules in cycle as incomplete.
+ * Then, save cycle on the cycle list (Cycles) for later resolution.
+ * The Cycle is stored in the form:
+ *             (head of cycle==croot, rest of rules in cycle==cyclicDep)
+ *
+ * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on)
+ *
+ *             Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x)
+ *                                                                                ^----Infinite recursion (cycle)
+ *
+ * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}).  Fo(x) depends
+ * on the FOLLOW of a,b, and c.  The root of a cycle is always complete after
+ * Fo(x) finishes.  Fo(a,b,c) however are not.  It turns out that all rules
+ * in a FOLLOW cycle have the same FOLLOW set.
+ */
+void
+#ifdef __STDC__
+RegisterCycle( char *rule, int k )
+#else
+RegisterCycle( rule, k )
+char *rule;
+int k;
+#endif
+{
+       CacheEntry *f;
+       Cycle *c;
+       int *p;
+       RuleEntry *r;
+       require(rule!=NULL, "RegisterCycle: tried to register NULL rule");
+       require(k<=CLL_k,       "RegisterCycle: tried to access non-existent stack");
+
+       /*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/
+       /* Find cycle start */
+       r = (RuleEntry *) hash_get(Rname, rule);
+       require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule));
+       require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),
+                       eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox",
+                                 rule));
+/*     if ( FoTOS[k]<FoStack[k]||FoTOS[k]>&(FoStack[k][FoStackSize-1]) )
+       {
+               fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n",
+                                               rule);
+               fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n",
+                                               FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1]));
+               exit(PCCTS_EXIT_FAILURE);
+       }
+*/
+#ifdef MEMCHK
+       require(valid(FoStack[k]), "RegisterCycle: invalid FoStack");
+#endif
+       for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;}
+       require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief");
+       if ( p == FoTOS[k] ) return;    /* don't worry about cycles to oneself */
+       
+       /* compute cyclic dependents (rules in cycle except head) */
+       c = newCycle;
+       require(c!=NULL, "RegisterCycle: couldn't alloc new cycle");
+       c->cyclicDep = empty;
+       c->croot = *p++;                /* record root of cycle */
+       for (; p<=FoTOS[k]; p++)
+       {
+               /* Mark all dependent rules as incomplete */
+               f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k));
+               if ( f==NULL )
+               {
+                       f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) );
+                       hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f);
+               }
+               f->incomplete = TRUE;
+               
+               set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */
+       }
+       list_add(&(Cycles[k]), (void *)c);
+}
+
+/* make all rules in cycle complete
+ *
+ * while ( some set has changed ) do
+ *             for each cycle do
+ *                     if degree of FOLLOW set for croot > old degree then
+ *                             update all FOLLOW sets for rules in cyclic dependency
+ *                             change = TRUE
+ *                     endif
+ *             endfor
+ * endwhile
+ */
+void
+#ifdef __STDC__
+ResolveFoCycles( int k )
+#else
+ResolveFoCycles( k )
+int k;
+#endif
+{
+       ListNode *p, *q;
+       Cycle *c;
+       int changed = 1;
+       CacheEntry *f,*g;
+       int r,i;
+       unsigned d;
+       
+       /*fprintf(stderr, "Resolving following cycles for %d\n", k);*/
+       while ( changed )
+       {
+               changed = 0;
+               i = 0;
+               for (p = Cycles[k]->next; p!=NULL; p=p->next)
+               {
+                       c = (Cycle *) p->elem;
+                       /*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/
+                       /*s_fprT(stderr, c->cyclicDep);*/
+                       /*fprintf(stderr, "\n");*/
+                       f = (CacheEntry *)
+                                       hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k));
+                       require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) );
+                       if ( (d=set_deg(f->fset)) > c->deg )
+                       {
+                               /*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/
+                               changed = 1;
+                               c->deg = d;             /* update cycle FOLLOW set degree */
+                               while ( !set_nil(c->cyclicDep) )
+                               {
+                                       r = set_int(c->cyclicDep);
+                                       set_rm(r, c->cyclicDep);
+                                       /*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/
+                                       g = (CacheEntry *)
+                                                       hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k));
+                                       require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) );
+                                       set_orin(&(g->fset), f->fset);
+                                       g->incomplete = FALSE;
+                               }
+                       }
+               }
+               if ( i == 1 ) changed = 0;      /* if only 1 cycle, no need to repeat */
+       }
+       /* kill Cycle list */
+       for (q = Cycles[k]->next; q != NULL; q=p)
+       {
+               p = q->next;
+               set_free( ((Cycle *)q->elem)->cyclicDep );
+               free((char *)q);
+       }
+       free( (char *)Cycles[k] );
+       Cycles[k] = NULL;
+}
+
+
+                       /* P r i n t i n g  S y n t a x  D i a g r a m s */
+
+static void
+#ifdef __STDC__
+pBlk( Junction *q, int btype )
+#else
+pBlk( q, btype )
+Junction *q;
+int btype;
+#endif
+{
+       int k,a;
+       Junction *alt, *p;
+
+       q->end->pvisited = TRUE;
+       if ( btype == aLoopBegin )
+       {
+               require(q->p2!=NULL, "pBlk: invalid ()* block");
+               PRINT(q->p1);
+               alt = (Junction *)q->p2;
+               PRINT(alt->p1);
+               if ( PrintAnnotate )
+               {
+                       printf(" /* Opt ");
+                       k = 1;
+                       while ( !set_nil(alt->fset[k]) )
+                       {
+                               s_fprT(stdout, alt->fset[k]);
+                               if ( k++ == CLL_k ) break;
+                               if ( !set_nil(alt->fset[k]) ) printf(", ");
+                       }
+                       printf(" */\n");
+               }
+               return;
+       }
+       for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++)
+       {
+               if ( alt->p1 != NULL ) PRINT(alt->p1);
+               if ( PrintAnnotate )
+               {
+                       printf( " /* [%d] ", alt->altnum);
+                       k = 1;
+                       while ( !set_nil(alt->fset[k]) )
+                       {
+                               s_fprT(stdout, alt->fset[k]);
+                               if ( k++ == CLL_k ) break;
+                               if ( !set_nil(alt->fset[k]) ) printf(", ");
+                       }
+                       if ( alt->p2 == NULL && btype == aOptBlk )
+                               printf( " (optional branch) */\n");
+                       else printf( " */\n");
+               }
+
+               /* ignore implied empty alt of Plus blocks */
+               if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break;
+
+               if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) )
+               {
+                       if ( pLevel == 1 )
+                       {
+                               printf("\n");
+                               if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>");
+                               printf("\t");
+                       }
+                       else printf(" ");
+                       printf("|");
+                       if ( pLevel == 1 )
+                       {
+                               p = (Junction *) ((Junction *)alt->p2)->p1;
+                               while ( p!=NULL )
+                               {
+                                       if ( p->ntype==nAction )
+                                       {
+                                               p=(Junction *)((ActionNode *)p)->next;
+                                               continue;
+                                       }
+                                       if ( p->ntype!=nJunction )
+                                       {
+                                               break;
+                                       }
+                                       if ( p->jtype==EndBlk || p->jtype==EndRule )
+                                       {
+                                               p = NULL;
+                                               break;
+                                       }
+                                       p = (Junction *)p->p1;
+                               }
+                               if ( p==NULL ) printf("\n\t");  /* Empty alt? */
+                       }
+               }
+       }
+       q->end->pvisited = FALSE;
+}
+
+/* How to print out a junction */
+void
+#ifdef __STDC__
+pJunc( Junction *q )
+#else
+pJunc( q )
+Junction *q;
+#endif
+{
+       int dum_k;
+       int doing_rule;
+       require(q!=NULL, "pJunc: NULL node");
+       require(q->ntype==nJunction, "pJunc: not junction");
+       
+       if ( q->pvisited == TRUE ) return;
+       q->pvisited = TRUE;
+       switch ( q->jtype )
+       {
+               case aSubBlk :
+                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+                       if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction &&
+                                ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1;
+                       else doing_rule = 0;
+                       pLevel++;
+                       if ( pLevel==1 )
+                       {
+                               if ( pAlt1==1 ) printf("=>");
+                               printf("\t");
+                       }
+                       else printf(" ");
+                       if ( doing_rule )
+                       {
+                               if ( pLevel==1 ) printf(" ");
+                               pBlk(q,q->jtype);
+                       }
+                       else {
+                               printf("(");
+                               if ( pLevel==1 ) printf(" ");
+                               pBlk(q,q->jtype);
+                               if ( pLevel>1 ) printf(" ");
+                               printf(")");
+                       }
+                       if ( q->guess ) printf("?");
+                       pLevel--;
+                       if ( PrintAnnotate ) freeBlkFsets(q);
+                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+                       break;
+               case aOptBlk :
+                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+                       pLevel++;
+                       if ( pLevel==1 )
+                       {
+                               if ( pAlt1==1 ) printf("=>");
+                               printf("\t");
+                       }
+                       else printf(" ");
+                       printf("{");
+                       if ( pLevel==1 ) printf(" ");
+                       pBlk(q,q->jtype);
+                       if ( pLevel>1 ) printf(" ");
+                       else printf("\n\t");
+                       printf("}");
+                       pLevel--;
+                       if ( PrintAnnotate ) freeBlkFsets(q);
+                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+                       break;
+               case aLoopBegin :
+                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+                       pLevel++;
+                       if ( pLevel==1 )
+                       {
+                               if ( pAlt1==1 ) printf("=>");
+                               printf("\t");
+                       }
+                       else printf(" ");
+                       printf("(");
+                       if ( pLevel==1 ) printf(" ");
+                       pBlk(q,q->jtype);
+                       if ( pLevel>1 ) printf(" ");
+                       else printf("\n\t");
+                       printf(")*");
+                       pLevel--;
+                       if ( PrintAnnotate ) freeBlkFsets(q);
+                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+                       break;
+               case aLoopBlk :
+                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+                       pBlk(q,q->jtype);
+                       if ( PrintAnnotate ) freeBlkFsets(q);
+                       break;
+               case aPlusBlk :
+                       if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+                       pLevel++;
+                       if ( pLevel==1 )
+                       {
+                               if ( pAlt1==1 ) printf("=>");
+                               printf("\t");
+                       }
+                       else printf(" ");
+                       printf("(");
+                       if ( pLevel==1 ) printf(" ");
+                       pBlk(q,q->jtype);
+                       if ( pLevel>1 ) printf(" ");
+                       printf(")+");
+                       pLevel--;
+                       if ( PrintAnnotate ) freeBlkFsets(q);
+                       if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+                       break;
+               case EndBlk :
+                       break;
+               case RuleBlk :
+                       printf( "\n%s :\n", q->rname);
+                       PRINT(q->p1);
+                       if ( q->p2 != NULL ) PRINT(q->p2);
+                       break;
+               case Generic :
+                       if ( q->p1 != NULL ) PRINT(q->p1);
+                       q->pvisited = FALSE;
+                       if ( q->p2 != NULL ) PRINT(q->p2);
+                       break;
+               case EndRule :
+                       printf( "\n\t;\n");
+                       break;
+       }
+       q->pvisited = FALSE;
+}
+
+/* How to print out a rule reference node */
+void
+#ifdef __STDC__
+pRuleRef( RuleRefNode *p )
+#else
+pRuleRef( p )
+RuleRefNode *p;
+#endif
+{
+       require(p!=NULL, "pRuleRef: NULL node");
+       require(p->ntype==nRuleRef, "pRuleRef: not rule ref node");
+       
+       printf( " %s", p->text);
+       PRINT(p->next);
+}
+
+/* How to print out a terminal node */
+void
+#ifdef __STDC__
+pToken( TokNode *p )
+#else
+pToken( p )
+TokNode *p;
+#endif
+{
+       require(p!=NULL, "pToken: NULL node");
+       require(p->ntype==nToken, "pToken: not token node");
+
+       if ( p->wild_card ) printf(" .");
+       printf( " %s", TerminalString(p->token));
+       PRINT(p->next);
+}
+
+/* How to print out a terminal node */
+void
+#ifdef __STDC__
+pAction( ActionNode *p )
+#else
+pAction( p )
+ActionNode *p;
+#endif
+{
+       require(p!=NULL, "pAction: NULL node");
+       require(p->ntype==nAction, "pAction: not action node");
+       
+       PRINT(p->next);
+}
+
+                                       /* F i l l  F o l l o w  L i s t s */
+
+/*
+ * Search all rules for all rule reference nodes, q to rule, r.
+ * Add q->next to follow list dangling off of rule r.
+ * i.e.
+ *
+ *             r: -o-R-o-->o--> Ptr to node following rule r in another rule
+ *                                     |
+ *                                     o--> Ptr to node following another reference to r.
+ *
+ * This is the data structure employed to avoid FOLLOW set computation.  We
+ * simply compute the FIRST (reach) of the EndRule Node which follows the
+ * list found at the end of all rules which are referenced elsewhere.  Rules
+ * not invoked by other rules have no follow list (r->end->p1==NULL).
+ * Generally, only start symbols are not invoked by another rule.
+ *
+ * Note that this mechanism also gives a free cross-reference mechanism.
+ *
+ * The entire syntax diagram is layed out like this:
+ *
+ * SynDiag
+ *     |
+ *     v
+ *     o-->R1--o
+ *     |
+ *     o-->R2--o
+ *     |
+ *     ...
+ *     |
+ *     o-->Rn--o
+ *
+ */
+void
+#ifdef __STDC__
+FoLink( Node *p )
+#else
+FoLink( p )
+Node *p;
+#endif
+{
+       RuleEntry *q;
+       Junction *j = (Junction *) p;
+       RuleRefNode *r = (RuleRefNode *) p;
+
+       if ( p==NULL ) return;
+       require(p->ntype>=1 && p->ntype<=NumNodeTypes,
+                       eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype));
+       switch ( p->ntype )
+       {
+               case nJunction :
+                       if ( j->fvisited ) return;
+                       if ( j->jtype == EndRule ) return;
+                       j->fvisited = TRUE;
+                       FoLink( j->p1 );
+                       FoLink( j->p2 );
+                       return;
+               case nRuleRef :
+                       if ( r->linked ) return;
+                       q = (RuleEntry *) hash_get(Rname, r->text);
+                       if ( q == NULL )
+                       {
+                               warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line );
+                       }
+                       else
+                       {
+                               if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL )
+                               {
+                                       warnFL( eMsg1("rule %s accepts no parameter(s)", r->text),
+                                                       FileStr[r->file], r->line );
+                               }
+                               if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL )
+                               {
+                                       warnFL( eMsg1("rule %s requires parameter(s)", r->text),
+                                                       FileStr[r->file], r->line );
+                               }
+                               if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL )
+                               {
+                                       warnFL( eMsg1("rule %s yields no return value(s)", r->text),
+                                                       FileStr[r->file], r->line );
+                               }
+                               if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL )
+                               {
+                                       warnFL( eMsg1("rule %s returns a value(s)", r->text),
+                                                       FileStr[r->file], r->line );
+                               }
+                               if ( !r->linked )
+                               {
+                                       addFoLink(      r->next, r->rname, RulePtr[q->rulenum] );
+                                       r->linked = TRUE;
+                               }
+                       }
+                       FoLink( r->next );
+                       return;
+               case nToken :
+                       FoLink( ((TokNode *)p)->next );
+                       return;
+               case nAction :
+                       FoLink( ((ActionNode *)p)->next );
+                       return;
+               default :
+                       fatal_internal("invalid node type");
+       }
+}
+
+/*
+ * Add a reference to the end of a rule.
+ *
+ * 'r' points to the RuleBlk node in a rule.  r->end points to the last node
+ * (EndRule jtype) in a rule.
+ *
+ * Initial:
+ *             r->end -->      o
+ *
+ * After:
+ *             r->end -->      o-->o--> Ptr to node following rule r in another rule
+ *                                             |
+ *                                             o--> Ptr to node following another reference to r.
+ *
+ * Note that the links are added to the head of the list so that r->end->p1
+ * always points to the most recently added follow-link.  At the end, it should
+ * point to the last reference found in the grammar (starting from the 1st rule).
+ */
+void
+#ifdef __STDC__
+addFoLink( Node *p, char *rname, Junction *r )
+#else
+addFoLink( p, rname, r )
+Node *p;
+char *rname;
+Junction *r;
+#endif
+{
+       Junction *j;
+       require(r!=NULL,                                "addFoLink: incorrect rule graph");
+       require(r->end!=NULL,                   "addFoLink: incorrect rule graph");
+       require(r->end->jtype==EndRule, "addFoLink: incorrect rule graph");
+       require(p!=NULL,                                "addFoLink: NULL FOLLOW link");
+
+       j = newJunction();
+       j->rname = rname;                       /* rname on follow links point to target rule */
+       j->p1 = p;                                      /* link to other rule */
+       j->p2 = (Node *) r->end->p1;/* point to head of list */
+       r->end->p1 = (Node *) j;        /* reset head to point to new node */
+}
+
+void
+#ifdef __STDC__
+GenCrossRef( Junction *p )
+#else
+GenCrossRef( p )
+Junction *p;
+#endif
+{
+       set a;
+       Junction *j;
+       RuleEntry *q;
+       unsigned e;
+       require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?");
+
+       printf("Cross Reference:\n\n");
+       a = empty;
+       for (; p!=NULL; p = (Junction *)p->p2)
+       {
+               printf("Rule %11s referenced by {", p->rname);
+               /* make a set of rules for uniqueness */
+               for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2)
+               {
+                       q = (RuleEntry *) hash_get(Rname, j->rname);
+                       require(q!=NULL, "GenCrossRef: FoLinks are screwed up");
+                       set_orel(q->rulenum, &a);
+               }
+               for (; !set_nil(a); set_rm(e, a))
+               {
+                       e = set_int(a);
+                       printf(" %s", RulePtr[e]->rname);
+               }
+               printf(" }\n");
+       }
+       set_free( a );
+}
diff --git a/antlr/pred.c b/antlr/pred.c
new file mode 100755 (executable)
index 0000000..0c32795
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * pred.c -- source for predicate detection, manipulation
+ *
+ * $Id: pred.c,v 1.6 95/09/26 12:58:44 parrt Exp $
+ * $Revision: 1.6 $
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ * 
+ * We encourage users to develop software with PCCTS.  However, we do ask
+ * that credit is given to us for developing PCCTS.  By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc...  If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS.  In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+#include <stdio.h>
+#ifdef __cplusplus
+#ifndef __STDC__
+#define __STDC__
+#endif
+#endif
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+#include <ctype.h>
+
+#ifdef __STDC__
+static void complete_context_sets(RuleRefNode *, Predicate *);
+static void complete_context_trees(RuleRefNode *, Predicate *);
+#else
+static void complete_context_sets();
+static void complete_context_trees();
+#endif
+
+static Predicate pred_empty = {
+       NULL,NULL,NULL,NULL,NULL,NULL,0,
+       {set_init,set_init},set_init
+};
+
+char *PRED_AND_LIST = "AND";
+char *PRED_OR_LIST = "OR";
+
+/*
+ * In C mode, return the largest constant integer found as the
+ * sole argument to LATEXT(i).
+ *
+ * In C++ mode, return the largest constant integer found as the
+ * sole argument to LT(i) given that the char before is nonalpha.
+ */
+static int
+#ifdef __STDC__
+predicateLookaheadDepth(ActionNode *a)
+#else
+predicateLookaheadDepth(a)
+ActionNode *a;
+#endif
+{
+       int max_k=0;
+
+       if ( GenCC )
+       {
+               /* scan for LT(i) */
+               int k = 0;
+               char *p = a->action;
+               while ( p!=NULL )
+               {
+                       p = strstr(p, "LT(");
+                       if ( p!=NULL )
+                       {
+                               if ( p>=a->action && !isalpha(*(p-1)) )
+                               {
+                                       k = atoi(p+strlen("LT("));
+                                       if ( k>max_k ) max_k=k;
+                               }
+                               p += strlen("LT(");
+                       }
+               }
+       }
+       else {
+               /* scan for LATEXT(i) */
+               int k = 0;
+               char *p = a->action;
+               while ( p!=NULL )
+               {
+                       p = strstr(p, "LATEXT(");
+                       if ( p!=NULL )
+                       {
+                               p += strlen("LATEXT(");
+                               k = atoi(p);
+                               if ( k>max_k ) max_k=k;
+                       }
+               }
+       }
+
+       if ( max_k==0 )
+       {
+               if ( !a->frmwarned )
+               {
+                       a->frmwarned = 1;
+                       warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1",
+                                                GenCC?"LT(i)":"LATEXT(i)"),
+                                  FileStr[a->file], a->line);
+               }
+               max_k = 1;
+       }
+
+       return max_k;
+}
+
+/* Find all predicates in a block of alternatives.  DO NOT find predicates
+ * behind the block because that predicate could depend on things set in
+ * one of the nonoptional blocks
+ */
+Predicate *
+#ifdef __STDC__
+find_in_aSubBlk( Junction *alt )
+#else
+find_in_aSubBlk( alt )
+Junction *alt;
+#endif
+{
+       Predicate *a, *head=NULL, *tail, *root=NULL;
+       Junction *p = alt;
+
+       for (; p!=NULL; p=(Junction *)p->p2)
+       {
+               /* ignore empty alts */
+               if ( p->p1->ntype != nJunction ||
+                        ((Junction *)p->p1)->jtype != EndBlk )
+               {
+                       a = find_predicates(p->p1);     /* get preds for this alt */
+                       if ( a==NULL ) continue;
+
+                       /* make an OR list of predicates */
+                       if ( head==NULL )
+                       {
+                               root = new_pred();
+                               root->expr = PRED_OR_LIST;
+                               head = tail = a;
+                               root->down = head;
+                       }
+                       else {
+                               tail->right = a;
+                               a->left = tail;
+                               a->up = tail->up;
+                               tail = a;
+                       }
+               }
+       }
+
+       /* if just one pred, remove OR root */
+       if ( root!=NULL && root->down->right == NULL )
+       {
+               Predicate *d = root->down;
+               free(root);
+               return d;
+       }
+
+       return root;
+}
+
+Predicate *
+#ifdef __STDC__
+find_in_aOptBlk( Junction *alt )
+#else
+find_in_aOptBlk( alt )
+Junction *alt;
+#endif
+{
+       return find_in_aSubBlk( alt );
+}
+
+Predicate *
+#ifdef __STDC__
+find_in_aLoopBegin( Junction *alt )
+#else
+find_in_aLoopBegin( alt )
+Junction *alt;
+#endif
+{
+       return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */
+}
+
+Predicate *
+#ifdef __STDC__
+find_in_aPlusBlk( Junction *alt )
+#else
+find_in_aPlusBlk( alt )
+Junction *alt;
+#endif
+{
+       require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk");
+       return find_in_aSubBlk( alt );
+}
+
+/* Look for a predicate;
+ *
+ * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs.
+ * This means that a "hoisting distance" of zero is the only distance
+ * allowable.  Init actions are ignored.
+ *
+ * WARNING:
+ *             Assumes no (..)? block after predicate for the moment.
+ *             Does not check to see if pred is in production that can generate
+ *                     a sequence contained in the set of ambiguous tuples.
+ *
+ * Return the predicate found if any.
+ */
+Predicate *
+#ifdef __STDC__
+find_predicates( Node *alt )
+#else
+find_predicates( alt )
+Node *alt;
+#endif
+{
+#ifdef DBG_PRED
+       Junction *j;
+       RuleRefNode *r;
+       TokNode *t;
+#endif
+       Predicate *pred;
+
+       if ( alt==NULL ) return NULL;
+
+#ifdef DBG_PRED
+       switch ( alt->ntype )
+       {
+               case nJunction :
+                       j = (Junction *) alt;
+                       fprintf(stderr, "Junction(in %s)", j->rname);
+                       switch ( j->jtype )
+                       {
+                               case aSubBlk :
+                                       fprintf(stderr,"aSubBlk\n");
+                                       break;
+                               case aOptBlk :
+                                       fprintf(stderr,"aOptBlk\n");
+                                       break;
+                               case aLoopBegin :
+                                       fprintf(stderr,"aLoopBeginBlk\n");
+                                       break;
+                               case aLoopBlk :
+                                       fprintf(stderr,"aLoopBlk\n");
+                                       break;
+                               case aPlusBlk :
+                                       fprintf(stderr,"aPlusBlk\n");
+                                       break;
+                               case EndBlk :
+                                       fprintf(stderr,"EndBlk\n");
+                                       break;
+                               case RuleBlk :
+                                       fprintf(stderr,"RuleBlk\n");
+                                       break;
+                               case Generic :
+                                       fprintf(stderr,"Generic\n");
+                                       break;
+                               case EndRule :
+                                       fprintf(stderr,"EndRule\n");
+                                       break;
+                       }
+                       break;
+               case nRuleRef :
+                       r = (RuleRefNode *) alt;
+                       fprintf(stderr, "RuleRef(in %s)\n", r->rname);
+                       break;
+               case nToken :
+                       t = (TokNode *) alt;
+                       fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token));
+                       break;
+               case nAction :
+                       fprintf(stderr, "Action\n");
+                       break;
+       }
+#endif
+
+       switch ( alt->ntype )
+       {
+               case nJunction :
+               {
+                       Predicate *a, *b;
+                       Junction *p = (Junction *) alt; 
+
+                       /* lock nodes */
+                       if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
+                                p->jtype==aPlusBlk || p->jtype==EndRule )
+                       {
+                               require(p->pred_lock!=NULL, "rJunc: lock array is NULL");
+                               if ( p->pred_lock[1] )
+                               {
+                                       return NULL;
+                               }
+                               p->pred_lock[1] = TRUE;
+                       }
+
+                       switch ( p->jtype )
+                       {
+                               case aSubBlk :
+                                       a = find_in_aSubBlk(p);
+                                       return a;       /* nothing is visible past this guy */
+                               case aOptBlk :
+                                       a = find_in_aOptBlk(p);
+                                       return a;
+                               case aLoopBegin :
+                                       a = find_in_aLoopBegin(p);
+                                       return a;
+                               case aLoopBlk :
+                                       a = find_in_aSubBlk(p);
+                                       p->pred_lock[1] = FALSE;
+                                       return a;
+                               case aPlusBlk :
+                                       a = find_in_aPlusBlk(p);
+                                       p->pred_lock[1] = FALSE;
+                                       return a;       /* nothing is visible past this guy */
+                               case RuleBlk :
+                                       a = find_predicates(p->p1);
+                                       p->pred_lock[1] = FALSE;
+                                       return a;
+                               case Generic :
+                                       a = find_predicates(p->p1);
+                                       b = find_predicates(p->p2);
+                                       if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE;
+                                       if ( a==NULL ) return b;
+                                       if ( b==NULL ) return a;
+                                       /* otherwise OR the two preds together */
+                                       {
+                                       fatal_internal("hit unknown situation during predicate hoisting");
+                                       }
+                               case EndBlk :
+                               case EndRule :  /* Find no predicates after a rule ref */
+                                       return NULL;
+                               default:
+                                       fatal_internal("this cannot be printed\n");
+                                       break;
+                       }
+               }
+               case nAction :
+               {
+                       ActionNode *p = (ActionNode *) alt;
+                       if ( p->init_action ) return find_predicates(p->next);
+                       if ( p->is_predicate )
+                       {
+                               Tree *t;
+#ifdef DBG_PRED
+                               fprintf(stderr, "predicate: <<%s>>?\n", p->action);
+#endif
+                               if ( p->guardpred!=NULL )
+                               {
+                                       pred = p->guardpred;
+                               }
+                               else
+                               {
+                                       pred = new_pred();
+                                       pred->k = predicateLookaheadDepth(p);
+                                       pred->source = p;
+                                       pred->expr = p->action;
+                                       if ( HoistPredicateContext && pred->k > 1 )
+                                       {
+                                               if ( first_item_is_guess_block((Junction *)p->next) )
+                                               {
+                                                       warnFL("cannot compute context of predicate in front of (..)? block", FileStr[p->file], p->line);
+                                               }
+                                               else
+                                               {
+                                                       ConstrainSearch = 0;
+                                                       TRAV(p->next,
+                                                                pred->k,
+                                                                &(pred->completion), t);
+                                                       pred->tcontext = t;
+#ifdef DBG_PRED
+                                                       fprintf(stderr, "LL(%d) context:", pred->k);
+                                                       preorder(t);
+                                                       fprintf(stderr, "\n");
+#endif
+                                               }
+                                       }
+                                       else if ( HoistPredicateContext && pred->k == 1 )
+                                       {
+                                               pred->scontext[1] = empty;
+                                               if ( first_item_is_guess_block((Junction *)p->next) )
+                                               {
+                                                       warnFL("cannot compute context of predicate in front of (..)? block", FileStr[p->file], p->line);
+                                               }
+                                               else
+                                               {
+                                                       REACH((Junction *)p->next,
+                                                                 1,
+                                                                 &(pred->completion),
+                                                                 pred->scontext[1]);
+#ifdef DBG_PRED
+                                                       fprintf(stderr, "LL(1) context:");
+                                                       s_fprT(stderr, pred->scontext[1]);
+                                                       fprintf(stderr, "\n");
+#endif
+                                               }
+                                       }
+                               }
+                               {
+                                       Predicate *d = find_predicates(p->next), *root;
+/* Warning: Doesn't seem like the up pointers will all be set correctly;
+ * TJP: that's ok, we're not using them now.
+ */
+                                       if ( d!=NULL )
+                                       {
+                                               root = new_pred();
+                                               root->expr = PRED_AND_LIST;
+                                               root->down = pred;
+                                               pred->right = d;
+                                               pred->up = root;
+                                               d->left = pred;
+                                               d->up = pred->up;
+                                               return root;
+                                       }
+                               }
+                               return pred;
+                       }
+                       return NULL;
+               }
+               case nRuleRef :
+               {
+                       Predicate *a;
+                       RuleRefNode *p = (RuleRefNode *) alt;
+                       Junction *r;
+                       int save_halt;
+                       RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
+                       if ( q == NULL )
+                       {
+                               warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );
+                               return NULL;
+                       }
+                       r = RulePtr[q->rulenum];
+                       if ( r->pred_lock[1] )
+                       {
+                               /* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis
+                                * must have seen it earlier.
+                                */
+                               return NULL;
+                       }
+                       save_halt = r->end->halt;
+                       r->end->halt = TRUE;
+/*                     a = find_predicates((Node *)r->p1);*/
+                       a = find_predicates((Node *)r);
+                       r->end->halt = save_halt;
+                       if ( a==NULL ) return NULL;
+                       /* attempt to compute the "local" FOLLOW just like in normal lookahead
+                        * computation if needed
+                        */
+                       complete_context_sets(p,a);
+                       complete_context_trees(p,a);
+                       return a;
+               }
+               case nToken :
+                       break;
+       }
+
+       return NULL;
+}
+
+Predicate *
+#ifdef __STDC__
+new_pred( void )
+#else
+new_pred( )
+#endif
+{
+       Predicate *p = (Predicate *) malloc(sizeof(Predicate));
+       require(p!=NULL, "new_pred: cannot alloc predicate");
+       *p = pred_empty;
+       return p;
+}
+
+static void
+#ifdef __STDC__
+complete_context_sets( RuleRefNode *p, Predicate *a )
+#else
+complete_context_sets( p, a )
+RuleRefNode *p;
+Predicate *a;
+#endif
+{
+       set rk2, b;
+       int k2;
+
+#ifdef DBG_PRED
+       fprintf(stderr, "enter complete_context_sets\n");
+#endif
+       for (; a!=NULL; a=a->right)
+       {
+               if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
+               {
+                       complete_context_sets(p, a->down);
+                       continue;
+               }
+               rk2 = b = empty;
+               while ( !set_nil(a->completion) )
+               {
+                       k2 = set_int(a->completion);
+                       set_rm(k2, a->completion);
+                       REACH(p->next, k2, &rk2, b);
+                       set_orin(&(a->scontext[1]), b);
+                       set_free(b);
+               }
+               set_orin(&(a->completion), rk2);/* remember what we couldn't do */
+               set_free(rk2);
+#ifdef DBG_PRED
+               fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a);
+               s_fprT(stderr, a->scontext[1]);
+               fprintf(stderr, "\n");
+#endif
+/*             complete_context_sets(p, a->down);*/
+       }
+#ifdef DBG_PRED
+       fprintf(stderr, "exit complete_context_sets\n");
+#endif
+}
+
+static void
+#ifdef __STDC__
+complete_context_trees( RuleRefNode *p, Predicate *a )
+#else
+complete_context_trees( p, a )
+RuleRefNode *p;
+Predicate *a;
+#endif
+{
+       set rk2;
+       int k2;
+       Tree *u;
+
+#ifdef DBG_PRED
+       fprintf(stderr, "enter complete_context_trees\n");
+#endif
+       for (; a!=NULL; a=a->right)
+       {
+               if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
+               {
+                       complete_context_trees(p, a->down);
+                       continue;
+               }
+               rk2 = empty;
+               /* any k left to do? if so, link onto tree */
+               while ( !set_nil(a->completion) )
+               {       
+                       k2 = set_int(a->completion);
+                       set_rm(k2, a->completion);
+                       u = NULL;
+                       TRAV(p->next, k2, &rk2, u);
+                       /* any subtrees missing k2 tokens, add u onto end */
+                       a->tcontext = tlink(a->tcontext, u, k2);
+               }
+               set_orin(&(a->completion), rk2);/* remember what we couldn't do */
+               set_free(rk2);
+#ifdef DBG_PRED
+               fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k);
+               preorder(a->tcontext);
+               fprintf(stderr, "\n");
+#endif
+/*             complete_context_trees(p, a->down);*/
+       }
+#ifdef DBG_PRED
+       fprintf(stderr, "exit complete_context_trees\n");
+#endif
+}
+
+/* Walk a list of predicates and return the set of all tokens in scontext[1]'s */
+set
+#ifdef __STDC__
+covered_set( Predicate *p )
+#else
+covered_set( p )
+Predicate *p;
+#endif
+{
+       set a;
+
+       a = empty;
+       for (; p!=NULL; p=p->right)
+       {
+               if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST )
+               {
+                       set_orin(&a, covered_set(p->down));
+                       continue;
+               }
+               set_orin(&a, p->scontext[1]);
+               set_orin(&a, covered_set(p->down));
+       }
+       return a;
+}