]> pd.if.org Git - pccts/blobdiff - antlr/main.c
auto commit for import
[pccts] / antlr / main.c
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;
+}