home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pccts.zip / pccts / antlr / main.c < prev    next >
C/C++ Source or Header  |  1994-03-31  |  28KB  |  1,105 lines

  1. /*
  2.  * main.c -- main program for PCCTS ANTLR.
  3.  *
  4.  * $Id: main.c,v 1.6 1994/03/25 19:40:05 parrt Exp parrt $
  5.  * $Revision: 1.6 $
  6.  *
  7.  * SOFTWARE RIGHTS
  8.  *
  9.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  10.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  11.  * company may do whatever they wish with source code distributed with
  12.  * PCCTS or the code generated by PCCTS, including the incorporation of
  13.  * PCCTS, or its output, into commerical software.
  14.  * 
  15.  * We encourage users to develop software with PCCTS.  However, we do ask
  16.  * that credit is given to us for developing PCCTS.  By "credit",
  17.  * we mean that if you incorporate our source code into one of your
  18.  * programs (commercial product, research project, or otherwise) that you
  19.  * acknowledge this fact somewhere in the documentation, research report,
  20.  * etc...  If you like PCCTS and have developed a nice tool with the
  21.  * output, please mention that you developed it using PCCTS.  In
  22.  * addition, we ask that this header remain intact in our source code.
  23.  * As long as these guidelines are kept, we expect to continue enhancing
  24.  * this system and expect to make other tools available as they are
  25.  * completed.
  26.  *
  27.  * ANTLR 1.20
  28.  * Terence Parr
  29.  * Purdue University
  30.  * With AHPCRC, University of Minnesota
  31.  * 1989-1994
  32.  */
  33.  
  34. #include <stdio.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include "stdpccts.h"
  41.  
  42. #ifdef VAXC
  43. #define DIE        return 0;
  44. #else
  45. #define DIE        return 1;
  46. #endif
  47.  
  48. #define MAX_INT_STACK 50
  49. static int istack[MAX_INT_STACK];        /* Int stack */
  50. static int isp = MAX_INT_STACK;
  51.  
  52. static int DontAcceptFiles = 0;            /* if stdin, don't read files */
  53. static int DontAcceptStdin = 0;            /* if files seen first, don't accept stdin */
  54.  
  55.  
  56.         /* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */
  57.  
  58. typedef struct _Opt {
  59.             char *option;
  60.             int  arg;
  61. #ifdef __cplusplus
  62.             void (*process)(...);
  63. #else
  64.             void (*process)();
  65. #endif
  66.             char *descr;
  67.         } Opt;
  68.  
  69. #ifdef __STDC__
  70. extern void ProcessArgs(int, char **, Opt *);
  71. #else
  72. extern void ProcessArgs();
  73. #endif
  74.  
  75. static void
  76. #ifdef __STDC__
  77. pStdin( void )
  78. #else
  79. pStdin( )
  80. #endif
  81. {
  82.     if ( DontAcceptStdin )
  83.     {
  84.         warnNoFL("'-' (stdin) ignored as files were specified first");
  85.         return;
  86.     }
  87.  
  88.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  89.     FileStr[NumFiles++] = "stdin";
  90.     DontAcceptFiles = 1;
  91. }
  92.  
  93. static void
  94. #ifdef __STDC__
  95. pFile( char *s )
  96. #else
  97. pFile( s )
  98. char *s;
  99. #endif
  100. {
  101.     if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
  102.     if ( DontAcceptFiles )
  103.     {
  104.         warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
  105.         return;
  106.     }
  107.  
  108.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  109.     FileStr[NumFiles++] = s;
  110.     DontAcceptStdin = 1;
  111. }
  112.  
  113. static void
  114. #ifdef __STDC__
  115. pLLK( char *s, char *t )
  116. #else
  117. pLLK( s, t )
  118. char *s;
  119. char *t;
  120. #endif
  121. {
  122.     LL_k = atoi(t);
  123.     if ( LL_k <= 0 ) {
  124.         warnNoFL("must have at least one token of lookahead (setting to 1)");
  125.         LL_k = 1;
  126.     }
  127. }
  128.  
  129. static void
  130. #ifdef __STDC__
  131. pCk( char *s, char *t )
  132. #else
  133. pCk( s, t )
  134. char *s;
  135. char *t;
  136. #endif
  137. {
  138.     CLL_k = atoi(t);
  139.     if ( CLL_k <= 0 ) {
  140.         warnNoFL("must have at least one token of look-ahead (setting to 1)");
  141.         CLL_k = 1;
  142.     }
  143. }
  144.  
  145. #ifdef __STDC__
  146. static void pCGen(void)    { CodeGen = FALSE; LexGen = FALSE; }
  147. static void pLGen(void)    { LexGen = FALSE; }
  148. static void pTGen(void)    { TraceGen = TRUE; }
  149. static void pSGen(void)    { GenExprSets = FALSE; }
  150. static void pPrt(void)    { PrintOut = TRUE; pCGen(); pLGen(); }
  151. static void pPrtA(void)    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  152. static void pAst(void)    { GenAST = TRUE; }
  153. static void pANSI(void)    { GenANSI = TRUE; }
  154. static void pCr(void)    { GenCR = TRUE; }
  155. static void pCt(void)    { DontCopyTokens = TRUE; }
  156. static void pLI(void)    { GenLineInfo = TRUE; }
  157. static void pFr(char *s, char *t) {RemapFileName = t;}
  158. static void pFe(char *s, char *t) {ErrFileName = t;}
  159. static void pFl(char *s, char *t) {DlgFileName = t;}
  160. static void pFm(char *s, char *t) {ModeFileName = t;}
  161. static void pFt(char *s, char *t) {DefFileName = t;}
  162. static void pE1(void)    { elevel = 1; }
  163. static void pE2(void)    { elevel = 2; }
  164. static void pE3(void)    { elevel = 3; }
  165. static void pEGen(void)    { GenEClasseForRules = 1; }
  166. static void pDL(void)    { DemandLookahead = 1; }
  167. static void pGHdr(void)    { GenStdPccts = 1; }
  168. static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
  169. static void pW1(void) { WarningLevel = 1; }
  170. static void pW2(void) { WarningLevel = 2; }
  171. static void pCC(void) { GenCC = TRUE; }
  172. #else
  173. static void pCGen()    { CodeGen = FALSE; LexGen = FALSE; }
  174. static void pLGen()    { LexGen = FALSE; }
  175. static void pTGen()    { TraceGen = TRUE; }
  176. static void pSGen()    { GenExprSets = FALSE; }
  177. static void pPrt()        { PrintOut = TRUE; pCGen(); pLGen(); }
  178. static void pPrtA()    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  179. static void pAst()        { GenAST = TRUE; }
  180. static void pANSI()    { GenANSI = TRUE; }
  181. static void pCr()        { GenCR = TRUE; }
  182. static void pCt()        { DontCopyTokens = TRUE; }
  183. static void pLI()        { GenLineInfo = TRUE; }
  184. static void pFr(s,t) char *s, *t; {RemapFileName = t;}
  185. static void pFe(s,t) char *s, *t; {ErrFileName = t;}
  186. static void pFl(s,t) char *s, *t; {DlgFileName = t;}
  187. static void pFm(s,t) char *s, *t; {ModeFileName = t;}
  188. static void pFt(s,t) char *s, *t; {DefFileName = t;}
  189. static void pE1()        { elevel = 1; }
  190. static void pE2()        { elevel = 2; }
  191. static void pE3()        { elevel = 3; }
  192. static void pEGen()    { GenEClasseForRules = 1; }
  193. static void pDL()        { DemandLookahead = 1; }
  194. static void pGHdr()    { GenStdPccts = 1; }
  195. static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
  196. static void pW1() { WarningLevel = 1; }
  197. static void pW2() { WarningLevel = 2; }
  198. static void pCC() { GenCC = TRUE; }
  199. #endif
  200.  
  201. static void
  202. #ifdef __STDC__
  203. pPre( char *s, char *t )
  204. #else
  205. pPre( s, t )
  206. char *s;
  207. char *t;
  208. #endif
  209. {
  210.     RulePrefix = t;
  211. }
  212.  
  213. static void
  214. #ifdef __STDC__
  215. pOut( char *s, char *t )
  216. #else
  217. pOut( s, t )
  218. char *s;
  219. char *t;
  220. #endif
  221. {
  222.     OutputDirectory = t;
  223. }
  224.  
  225. static void
  226. #ifdef __STDC__
  227. pPred( void )
  228. #else
  229. pPred( )
  230. #endif
  231. {
  232.     warnNoFL("-pr is no longer used (predicates employed if present); see -prc");
  233. /*
  234.     if ( DemandLookahead )
  235.         warnNoFL("-gk conflicts with -pr; -gk turned off");
  236.     DemandLookahead = 0;
  237.     HoistPredicateContext = 0;
  238. */
  239. }
  240.  
  241. static void
  242. #ifdef __STDC__
  243. pPredCtx( char *s, char *t )
  244. #else
  245. pPredCtx(s,t)
  246. char *s;
  247. char *t;
  248. #endif
  249. {
  250.     if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
  251.     else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
  252.     else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
  253.     else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
  254.     if ( DemandLookahead )
  255.     {
  256.         warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
  257.         DemandLookahead = 0;
  258.     }
  259. }
  260.  
  261. static void
  262. #ifdef __STDC__
  263. pTRes( char *s, char *t )
  264. #else
  265. pTRes( s, t )
  266. char *s;
  267. char *t;
  268. #endif
  269. {
  270.     TreeResourceLimit = atoi(t);
  271.     if ( TreeResourceLimit <= 0 )
  272.     {
  273.         warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
  274.         TreeResourceLimit = -1; /* set to no limit */
  275.     }
  276. }
  277.  
  278. Opt options[] = {
  279. #ifdef __cplusplus
  280.     { "-CC", 0, (void (*)(...)) pCC,    "Generate C++ output (default=FALSE)"},
  281.     { "-ck", 1, (void (*)(...)) pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  282.     { "-cr", 0, (void (*)(...)) pCr,    "Generate cross reference (default=FALSE)"},
  283.     { "-ct", 0, (void (*)(...)) pCt,    "Do not copy tokens in C++ mode (default=to copy)"},
  284.     { "-e1", 0, (void (*)(...)) pE1,    "Ambiguities/errors shown in low detail (default)"},
  285.     { "-e2", 0, (void (*)(...)) pE2,    "Ambiguities/errors shown in more detail"},
  286.     { "-e3", 0, (void (*)(...)) pE3,    "Ambiguities/errors shown in excruciating detail"},
  287.     { "-fe", 1, (void (*)(...)) pFe,    "Rename err.c"},
  288.     { "-fh", 1, (void (*)(...)) pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  289.     { "-fl", 1, (void (*)(...)) pFl,    "Rename lexical output--parser.dlg"},
  290.     { "-fm", 1, (void (*)(...)) pFm,    "Rename mode.h"},
  291.     { "-fr", 1, (void (*)(...)) pFr,    "Rename remap.h"},
  292.     { "-ft", 1, (void (*)(...)) pFt,    "Rename tokens.h"},
  293.     { "-ga", 0, (void (*)(...)) pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  294.     { "-gc", 0, (void (*)(...)) pCGen,    "Do not generate output parser code (default=FALSE)"},
  295.     { "-gd", 0, (void (*)(...)) pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  296.     { "-ge", 0, (void (*)(...)) pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  297.     { "-gh", 0, (void (*)(...)) pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  298.     { "-gk", 0, (void (*)(...)) pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  299.     { "-gl", 0, (void (*)(...)) pLI,    "Generate line info about grammar actions in C parser"},
  300.     { "-gp", 1, (void (*)(...)) pPre,    "Prefix all generated rule functions with a string"},
  301.     { "-gs", 0, (void (*)(...)) pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  302.     { "-gt", 0, (void (*)(...)) pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  303.     { "-gx", 0, (void (*)(...)) pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  304.     { "-k",  1, (void (*)(...)) pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  305.     { "-o",  1, (void (*)(...)) pOut,    "Directory where all output files should go (default=\".\")"},
  306.     { "-p",  0, (void (*)(...)) pPrt,    "Print out the grammar w/o actions (default=no)"},
  307.     { "-pa", 0, (void (*)(...)) pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  308.     { "-pr",0, (void (*)(...)) pPred,    "no longer used; predicates employed if present"},
  309.     { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  310.        { "-rl", 1, (void (*)(...)) pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  311.     { "-w1", 0, (void (*)(...)) pW1,    "Set the warning level to 1 (default)"},
  312.     { "-w2", 0, (void (*)(...)) pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  313.     { "-",   0, (void (*)(...)) pStdin,    "Read grammar from stdin" },
  314.     { "*",   0, (void (*)(...)) pFile,     "" },    /* anything else is a file */
  315. #else
  316.     { "-CC", 0, pCC,    "Generate C++ output (default=FALSE)"},
  317.     { "-cr", 0, pCr,    "Generate cross reference (default=FALSE)"},
  318.     { "-ct", 0, pCt,    "Do not copy tokens in C++ mode (default=to copy)"},
  319.     { "-ck", 1, pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  320.     { "-e1", 0, pE1,    "Ambiguities/errors shown in low detail (default)"},
  321.     { "-e2", 0, pE2,    "Ambiguities/errors shown in more detail"},
  322.     { "-e3", 0, pE3,    "Ambiguities/errors shown in excrutiating detail"},
  323.     { "-fe", 1, pFe,    "Rename err.c"},
  324.     { "-fh", 1, pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  325.     { "-fl", 1, pFl,    "Rename lexical output--parser.dlg"},
  326.     { "-fm", 1, pFm,    "Rename mode.h"},
  327.     { "-fr", 1, pFr,    "Rename remap.h"},
  328.     { "-ft", 1, pFt,    "Rename tokens.h"},
  329.     { "-ga", 0, pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  330.     { "-gc", 0, pCGen,    "Do not generate output parser code (default=FALSE)"},
  331.     { "-gd", 0, pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  332.     { "-ge", 0, pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  333.     { "-gh", 0, pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  334.     { "-gk", 0, pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  335.     { "-gl", 0, pLI,    "Generate line info about grammar actions in C parser"},
  336.     { "-gp", 1, pPre,    "Prefix all generated rule functions with a string"},
  337.     { "-gs", 0, pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  338.     { "-gt", 0, pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  339.     { "-gx", 0, pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  340.     { "-k",  1, pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  341.     { "-o",  1, pOut,    "Directory where all output files should go (default=\".\")"},
  342.     { "-p",  0, pPrt,    "Print out the grammar w/o actions (default=no)"},
  343.     { "-pa", 0, pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  344.     { "-pr",0, pPred,    "no longer used; predicates employed if present"},
  345.     { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  346.        { "-rl", 1, pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  347.     { "-w1", 0, pW1,    "Set the warning level to 1 (default)"},
  348.     { "-w2", 0, pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  349.     { "-",   0, pStdin,    "Read grammar from stdin" },
  350.     { "*",   0, pFile,     "" },    /* anything else is a file */
  351. #endif
  352.     { NULL,  0, NULL }
  353. };
  354.  
  355. void readDescr();
  356. void cleanUp();
  357.  
  358. #ifdef __STDC__
  359. static void buildRulePtr( void );
  360. static void help( void );
  361. static void init( void );
  362. static void CompleteTokenSetRefs( void );
  363. static void ensure_no_C_file_collisions(char *);
  364. #else
  365. static void buildRulePtr( );
  366. static void help( );
  367. static void init( );
  368. static void CompleteTokenSetRefs( );
  369. static void ensure_no_C_file_collisions();
  370. #endif
  371.  
  372.                                 /* M a i n */
  373.  
  374. int
  375. #ifdef __STDC__
  376. main( int argc, char *argv[] )
  377. #else
  378. main( argc, argv )
  379. int argc;
  380. char *argv[];
  381. #endif
  382. {
  383.     int i;
  384.     static char EPSTR[] = "[Ep]";
  385.  
  386.     fprintf(stderr, "Antlr parser generator   Version %s   1989-1994\n", Version);
  387.     if ( argc == 1 ) { help(); DIE; }
  388.     ProcessArgs(argc-1, &(argv[1]), options);
  389.  
  390.     /* Fix lookahead depth */
  391.     /* Compressed lookahead must always be larger than or equal to full lookahead */
  392.     if ( CLL_k < LL_k  && CLL_k>0 )
  393.     {
  394.         warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
  395.         CLL_k = LL_k;
  396.     }
  397.     if ( CLL_k == -1 ) CLL_k = LL_k;
  398.     OutputLL_k = CLL_k;
  399.     if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
  400.         int n;
  401.         for(n=1; n<CLL_k; n<<=1) {;}
  402.         OutputLL_k = n;
  403.     }
  404.  
  405.     fpTrans = &(C_Trans[0]);        /* Translate to C Language */
  406.     fpJTrans = &(C_JTrans[0]);
  407.     init();
  408.     lexclass(LexStartSymbol);
  409.  
  410.     readDescr();
  411.     LastTokenCounted = TokenNum;
  412.     RemapForcedTokens();
  413.     if ( CannotContinue ) {cleanUp(); DIE;}
  414.     if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
  415.     if ( WarningLevel>1 && HdrAction == NULL )
  416.        warnNoFL("no #header action was found");
  417.  
  418.     EpToken = addTname(EPSTR);        /* add imaginary token epsilon */
  419.     set_orel(EpToken, &imag_tokens);
  420.  
  421.     /* this won't work for hand-built scanners since EofToken is not
  422.      * known.  Forces EOF to be token type 1.
  423.      */
  424.     set_orel(EofToken, &imag_tokens);
  425.  
  426.     set_size(NumWords(TokenNum-1));
  427.  
  428.     /* compute the set of all known token types 
  429.      * It represents the set of tokens from 1 to last_token_num + the
  430.      * reserved positions above that (if any).  Don't include the set of
  431.      * imaginary tokens such as the token/error classes or EOF.
  432.      */
  433.     {
  434.         set a;
  435.         a = set_dup(reserved_positions);
  436.         for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
  437.         all_tokens = set_dif(a, imag_tokens);
  438.         set_free(a);
  439.     }
  440.  
  441.     ComputeTokSets();
  442.     CompleteTokenSetRefs();
  443.  
  444.     if ( CodeGen ) genDefFile();    /* create tokens.h */
  445.     if ( LexGen ) genLexDescr();    /* create parser.dlg */
  446.  
  447.     if ( GenStdPccts )
  448.     {
  449.         FILE *f = fopen(OutMetaName(stdpccts), "w");
  450.         if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
  451.         else
  452.         {
  453.             genStdPCCTSIncludeFile(f);
  454.             fclose(f);
  455.         }
  456.     }
  457.  
  458.     buildRulePtr();                    /* create mapping from rule # to RuleBlk junction */
  459.     ComputeErrorSets();
  460.     FoLink( (Node *)SynDiag );        /* add follow links to end of all rules */
  461.     
  462.     if ( GenCR ) GenCrossRef( SynDiag );
  463.  
  464.     if ( CodeGen )
  465.     {
  466.         if ( SynDiag == NULL )
  467.         {
  468.             warnNoFL("no grammar description recognized");
  469.             cleanUp();
  470.             DIE;
  471.         }
  472.         else if ( !GenCC ) {
  473.             ErrFile = fopen(OutMetaName(ErrFileName), "w");
  474.             require(ErrFile != NULL, "main: can't open err file");
  475.             NewSetWd();
  476.             GenErrHdr();
  477.             TRANS(SynDiag);            /* Translate to the target language */
  478.             DumpSetWd();
  479.             fclose( ErrFile );
  480.         }
  481.         else {
  482.             strcpy(Parser_h_Name, CurrentClassName);
  483.             strcat(Parser_h_Name, ".h");
  484.             strcpy(Parser_c_Name, CurrentClassName);
  485.             strcat(Parser_c_Name, ".C");
  486.             ensure_no_C_file_collisions(Parser_c_Name);
  487.             Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
  488.             require(Parser_h != NULL, "main: can't open class Parserx.h file");
  489.             Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
  490.             require(Parser_c != NULL, "main: can't open class Parserx.c file");
  491.             GenParser_h_Hdr();
  492.             GenParser_c_Hdr();
  493.             NewSetWd();
  494.             TRANS(SynDiag);            /* Translate to the target language */
  495.             DumpSetWd();
  496.             GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
  497.             /* Dump class members */
  498.             if ( class_actions != NULL )
  499.             {
  500.                 ListNode *p;
  501.                 for (p = class_actions->next; p!=NULL; p=p->next)
  502.                 dumpAction( (char *)p->elem, Parser_h, 0, -1, 0, 1);
  503.             }
  504.             fprintf(Parser_h, "};\n");
  505.             fclose( Parser_h );
  506.             fclose( Parser_c );
  507.         }
  508.     }
  509.  
  510.     if ( PrintOut )
  511.     {
  512.         if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
  513.         else PRINT(SynDiag);
  514.     }
  515.  
  516.     GenRemapFile();                    /* create remap.h */
  517.  
  518.     cleanUp();
  519. #ifdef VAXC
  520.     return 1;               /* report all is well for make etc... */
  521. #else
  522.     return 0;               /* report all is well for make etc... */
  523. #endif
  524. }
  525.  
  526. static void
  527. #ifdef __STDC__
  528. init( void )
  529. #else
  530. init( )
  531. #endif
  532. {
  533.     Tname = newHashTable();
  534.     Rname = newHashTable();
  535.     Fcache = newHashTable();
  536.     Tcache = newHashTable();
  537.     reserved_positions = empty;
  538.     all_tokens = empty;
  539.     imag_tokens = empty;
  540.     TokenStr = (char **) calloc(TSChunk, sizeof(char *));
  541.     require(TokenStr!=NULL, "main: cannot allocate TokenStr");
  542.     FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
  543.     require(FoStack!=NULL, "main: cannot allocate FoStack");
  544.     FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
  545.     require(FoTOS!=NULL, "main: cannot allocate FoTOS");
  546.     Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
  547.     require(Cycles!=NULL, "main: cannot allocate Cycles List");
  548. }
  549.  
  550. static void
  551. #ifdef __STDC__
  552. help( void )
  553. #else
  554. help( )
  555. #endif
  556. {
  557.     Opt *p = options;
  558.     fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
  559.     while ( *(p->option) != '*' )
  560.     {
  561.         fprintf(stderr, "\t%-4s %s   %s\n",
  562.                         p->option,
  563.                         (p->arg)?"___":"   ",
  564.                         p->descr);
  565.         p++;
  566.     }
  567. }
  568.  
  569. /* The RulePtr array is filled in here.  RulePtr exists primarily
  570.  * so that sets of rules can be maintained for the FOLLOW caching
  571.  * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n
  572.  * to a pointer to its RuleBlk junction where n is the number of rules.
  573.  */
  574. static void
  575. #ifdef __STDC__
  576. buildRulePtr( void )
  577. #else
  578. buildRulePtr( )
  579. #endif
  580. {
  581.     int r=1;
  582.     Junction *p  = SynDiag;
  583.     RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
  584.     require(RulePtr!=NULL, "cannot allocate RulePtr array");
  585.     
  586.     while ( p!=NULL )
  587.     {
  588.         require(r<=NumRules, "too many rules???");
  589.         RulePtr[r++] = p;
  590.         p = (Junction *)p->p2;
  591.     }
  592. }
  593.  
  594. void
  595. #ifdef __STDC__
  596. dlgerror(char *s)
  597. #else
  598. dlgerror(s)
  599. char *s;
  600. #endif
  601. {
  602.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  603.     fprintf(stderr, " lexical error: %s (text was '%s')\n",
  604.                     ((s == NULL) ? "Lexical error" : s), zzlextext);
  605. }
  606.  
  607. void
  608. #ifdef __STDC__
  609. readDescr( void )
  610. #else
  611. readDescr( )
  612. #endif
  613. {
  614.     zzerr = dlgerror;
  615.     input = NextFile();
  616.     if ( input==NULL ) fatal("No grammar description found (exiting...)");
  617.     ANTLR(grammar(), input);
  618. }
  619.  
  620. FILE *
  621. #ifdef __STDC__
  622. NextFile( void )
  623. #else
  624. NextFile( )
  625. #endif
  626. {
  627.     FILE *f;
  628.  
  629.     for (;;)
  630.     {
  631.         CurFile++;
  632.         if ( CurFile >= NumFiles ) return(NULL);
  633.         if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
  634.         f = fopen(FileStr[CurFile], "r");
  635.         if ( f == NULL )
  636.         {
  637.             warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
  638.         }
  639.         else
  640.         {
  641.             return(f);
  642.         }
  643.     }
  644. }
  645.  
  646. /*
  647.  * Return a string corresponding to the output file name associated
  648.  * with the input file name passed in.
  649.  *
  650.  * Observe the following rules:
  651.  *
  652.  *        f.e        --> f".c"
  653.  *        f        --> f".c"
  654.  *        f.        --> f".c"
  655.  *        f.e.g    --> f.e".c"
  656.  *
  657.  * Where f,e,g are arbitrarily long sequences of characters in a file
  658.  * name.
  659.  *
  660.  * In other words, if a ".x" appears on the end of a file name, make it
  661.  * ".c".  If no ".x" appears, append ".c" to the end of the file name.
  662.  *
  663.  * C++ mode using .C not .c.
  664.  *
  665.  * Use malloc() for new string.
  666.  */
  667. char *
  668. #ifdef __STDC__
  669. outname( char *fs )
  670. #else
  671. outname( fs )
  672. char *fs;
  673. #endif
  674. {
  675.     static char buf[MaxFileName+1];
  676.     char *p;
  677.     require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
  678.  
  679.     p = buf;
  680.     strcpy(buf, fs);
  681.     while ( *p != '\0' )  {p++;}            /* Stop on '\0' */
  682.     while ( *p != '.' && p != buf ) {--p;}    /* Find '.' */
  683.     if ( p != buf ) *p = '\0';                /* Found '.' */
  684.     require(strlen(buf) + 2 < MaxFileName, "outname: filename too big");
  685.     if ( GenCC ) strcat(buf, ".C");
  686.     else strcat(buf, ".c");
  687.     return( buf );
  688. }
  689.  
  690. void
  691. #ifdef __STDC__
  692. fatalFL( char *err_, char *f, int l )
  693. #else
  694. fatalFL( err_, f, l )
  695. char *err_;
  696. char *f;
  697. int l;
  698. #endif
  699. {
  700.     fprintf(stderr, ErrHdr, f, l);
  701.     fprintf(stderr,    " %s\n", err_);
  702.     cleanUp();
  703.     exit(1);
  704. }
  705.  
  706. void
  707. #ifdef __STDC__
  708. fatal_internal( char *err_, char *f, int l )
  709. #else
  710. fatal_internal( err_, f, l )
  711. char *err_;
  712. char *f;
  713. int l;
  714. #endif
  715. {
  716.     fprintf(stderr, ErrHdr, f, l);
  717.     fprintf(stderr,    " #$%%*&@# internal error: %s\n", err_);
  718.     fprintf(stderr, ErrHdr, f, l);
  719.     fprintf(stderr, " [complain to nearest government official\n");
  720.     fprintf(stderr, ErrHdr, f, l);
  721.     fprintf(stderr, "  or send hate-mail to parrt@acm.org;\n");
  722.     fprintf(stderr, ErrHdr, f, l);
  723.     fprintf(stderr, "  please pray to the ``bug'' gods that there is a trival fix.]\n");
  724.     cleanUp();
  725.     exit(1);
  726. }
  727.  
  728. void
  729. #ifdef __STDC__
  730. cleanUp( void )
  731. #else
  732. cleanUp( )
  733. #endif
  734. {
  735.     if ( DefFile != NULL) fclose( DefFile );
  736. }
  737.  
  738. /* sprintf up to 3 strings */
  739. char *
  740. #ifdef __STDC__
  741. eMsg3( char *s, char *a1, char *a2, char *a3 )
  742. #else
  743. eMsg3( s, a1, a2, a3 )
  744. char *s;
  745. char *a1;
  746. char *a2;
  747. char *a3;
  748. #endif
  749. {
  750.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  751.     
  752.     sprintf(buf, s, a1, a2, a3);
  753.     return( buf );
  754. }
  755.  
  756. /* sprintf a decimal */
  757. char *
  758. #ifdef __STDC__
  759. eMsgd( char *s, int d )
  760. #else
  761. eMsgd( s, d )
  762. char *s;
  763. int d;
  764. #endif
  765. {
  766.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  767.     
  768.     sprintf(buf, s, d);
  769.     return( buf );
  770. }
  771.  
  772. void
  773. #ifdef __STDC__
  774. s_fprT( FILE *f, set e )
  775. #else
  776. s_fprT( f, e )
  777. FILE *f;
  778. set e;
  779. #endif
  780. {
  781.     register unsigned *p;
  782.     unsigned *q;
  783.  
  784.     if ( set_nil(e) ) return;
  785.     if ( (q=p=set_pdq(e)) == NULL ) fatal("Can't alloc space for set_pdq");
  786.     fprintf(f, "{");
  787.     while ( *p != nil )
  788.     {
  789.         fprintf(f, " %s", TerminalString(*p));
  790.         p++;
  791.     }
  792.     fprintf(f, " }");
  793.     free(q);
  794. }
  795.  
  796. /* Return the token name or regular expression for a token number. */
  797. char *
  798. #ifdef __STDC__
  799. TerminalString( int token )
  800. #else
  801. TerminalString( token )
  802. int token;
  803. #endif
  804. {
  805.     int j;
  806.  
  807.     /* look in all lexclasses for the token */
  808.     if ( TokenString(token) != NULL ) return TokenString(token);
  809.     for (j=0; j<NumLexClasses; j++)
  810.     {
  811.         lexmode(j);
  812.         if ( ExprString(token) != NULL ) return ExprString(token);
  813.     }
  814.     require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
  815.     return "invalid";
  816. }
  817.  
  818.                     /* S i m p l e  I n t  S t a c k */
  819.  
  820. void
  821. #ifdef __STDC__
  822. pushint( int i )
  823. #else
  824. pushint( i )
  825. int i;
  826. #endif
  827. {
  828.     require(isp>0, "pushint: stack overflow");
  829.     istack[--isp] = i;
  830. }
  831.  
  832. int
  833. #ifdef __STDC__
  834. popint( void )
  835. #else
  836. popint( )
  837. #endif
  838. {
  839.     require(isp<MAX_INT_STACK, "popint: stack underflow");
  840.     return istack[isp++];
  841. }
  842.  
  843. int
  844. #ifdef __STDC__
  845. istacksize( void )
  846. #else
  847. istacksize( )
  848. #endif
  849. {
  850.     return MAX_INT_STACK-isp;
  851. }
  852.  
  853. void
  854. #ifdef __STDC__
  855. istackreset( void )
  856. #else
  857. istackreset( )
  858. #endif
  859. {
  860.     isp = MAX_INT_STACK;
  861. }
  862.  
  863. int
  864. #ifdef __STDC__
  865. istackempty( void )
  866. #else
  867. istackempty( )
  868. #endif
  869. {
  870.     return isp==MAX_INT_STACK;
  871. }
  872.  
  873. int
  874. #ifdef __STDC__
  875. topint( void )
  876. #else
  877. topint( )
  878. #endif
  879. {
  880.     require(isp<MAX_INT_STACK, "topint: stack underflow");
  881.     return istack[isp];
  882. }
  883.  
  884. void
  885. #ifdef __STDC__
  886. ProcessArgs( int argc, char **argv, Opt *options )
  887. #else
  888. ProcessArgs( argc, argv, options )
  889. int argc;
  890. char **argv;
  891. Opt *options;
  892. #endif
  893. {
  894.     Opt *p;
  895.     require(argv!=NULL, "ProcessArgs: command line NULL");
  896.  
  897.     while ( argc-- > 0 )
  898.     {
  899.         p = options;
  900.         while ( p->option != NULL )
  901.         {
  902.             if ( strcmp(p->option, "*") == 0 ||
  903.                  strcmp(p->option, *argv) == 0 )
  904.             {
  905.                 if ( p->arg )
  906.                 {
  907.                     (*p->process)( *argv, *(argv+1) );
  908.                     argv++;
  909.                     argc--;
  910.                 }
  911.                 else
  912.                     (*p->process)( *argv );
  913.                 break;
  914.             }
  915.             p++;
  916.         }
  917.         argv++;
  918.     }
  919. }
  920.  
  921. /* Go back into the syntax diagram and compute all meta tokens; i.e.
  922.  * turn all '.', ranges, token class refs etc... into actual token sets
  923.  */
  924. static void
  925. CompleteTokenSetRefs()
  926. {
  927.     ListNode *p;
  928.  
  929.     if ( MetaTokenNodes==NULL ) return;
  930.     for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
  931.     {
  932.         set a,b;
  933.  
  934.         TokNode *q = (TokNode *)p->elem;
  935.         if ( q->wild_card )
  936.         {
  937.             q->tset = all_tokens;
  938.         }
  939.         else if ( q->tclass!=NULL )
  940.         {
  941.             if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
  942.             else q->tset = q->tclass->tset;
  943.         }
  944.         else if ( q->upper_range!=0 )
  945.         {
  946.             /* we have a range on our hands: make a set from q->token .. q->upper_range */
  947.             int i;
  948.             a = empty;
  949.             for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); }
  950.             q->tset = a;
  951.         }
  952.         /* at this point, it can only be a complemented single token */
  953.         else if ( q->complement )
  954.         {
  955.             a = set_of(q->token);
  956.             b = set_dif(all_tokens, a);
  957.             set_free(a);
  958.             q->tset=b;
  959.         }
  960.         else fatal("invalid meta token");
  961.     }
  962. }
  963.  
  964. char *
  965. #ifdef __STDC__
  966. OutMetaName(char *n)
  967. #else
  968. OutMetaName(n)
  969. char *n;
  970. #endif
  971. {
  972.     static char buf[MaxFileName+1];
  973.  
  974.     strcpy(buf, OutputDirectory);
  975.     strcat(buf, DirectorySymbol);
  976.     strcat(buf, n);
  977.     return buf;
  978. }
  979.  
  980. static void
  981. #ifdef __STDC__
  982. ensure_no_C_file_collisions(char *class_c_file)
  983. #else
  984. ensure_no_C_file_collisions(class_c_file)
  985. char *class_c_file;
  986. #endif
  987. {
  988.     int i;
  989.  
  990.     for (i=0; i<NumFiles; i++)
  991.     {
  992.         if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
  993.         {
  994.             fatal(eMsg1("class def output file conflicts with parser output file: %s",
  995.                         outname(FileStr[i])));
  996.         }
  997.     }
  998. }
  999.  
  1000. void
  1001. #ifdef __STDC__
  1002. warnNoFL(char *err)
  1003. #else
  1004. warnNoFL(err)
  1005. char *err;
  1006. #endif
  1007. {
  1008.     fprintf(stderr, "warning: %s\n", err);
  1009. }
  1010.  
  1011. void
  1012. #ifdef __STDC__
  1013. warnFL(char *err,char *f,int l)
  1014. #else
  1015. warnFL(err,f,l)
  1016. char *f;
  1017. int l;
  1018. char *err;
  1019. #endif
  1020. {
  1021.     fprintf(stderr, ErrHdr, f, l);                        
  1022.     fprintf(stderr, " warning: %s\n", err);
  1023. }
  1024.  
  1025. void
  1026. #ifdef __STDC__
  1027. warn(char *err)                                                
  1028. #else
  1029. warn(err)                                                
  1030. char *err;
  1031. #endif
  1032. {
  1033.     /* back up the file number if we hit an error at the end of the last file */
  1034.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1035.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1036.     fprintf(stderr, " warning: %s\n", err);
  1037. }
  1038.  
  1039. void
  1040. #ifdef __STDC__
  1041. warnNoCR( char *err )
  1042. #else
  1043. warnNoCR( err )                                            
  1044. char *err;
  1045. #endif
  1046. {
  1047.     /* back up the file number if we hit an error at the end of the last file */
  1048.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1049.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1050.     fprintf(stderr, " warning: %s", err);
  1051. }
  1052.  
  1053. void
  1054. #ifdef __STDC__
  1055. errNoFL(char *err)
  1056. #else
  1057. errNoFL(err)
  1058. char *err;
  1059. #endif
  1060. {
  1061.     fprintf(stderr, "error: %s\n", err);
  1062. }
  1063.  
  1064. void
  1065. #ifdef __STDC__
  1066. errFL(char *err,char *f,int l)                                            
  1067. #else
  1068. errFL(err,f,l)                                            
  1069. char *err;
  1070. char *f;
  1071. int l;
  1072. #endif
  1073. {
  1074.     fprintf(stderr, ErrHdr, f, l);                        
  1075.     fprintf(stderr, " error: %s\n", err);
  1076. }
  1077.  
  1078. void
  1079. #ifdef __STDC__
  1080. err(char *err)                                                
  1081. #else
  1082. err(err)                                                
  1083. char *err;
  1084. #endif
  1085. {
  1086.     /* back up the file number if we hit an error at the end of the last file */
  1087.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1088.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1089.     fprintf(stderr, " error: %s\n", err);
  1090. }
  1091.  
  1092. void
  1093. #ifdef __STDC__
  1094. errNoCR( char *err )                                            
  1095. #else
  1096. errNoCR( err )                                            
  1097. char *err;
  1098. #endif
  1099. {
  1100.     /* back up the file number if we hit an error at the end of the last file */
  1101.     if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1102.     fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1103.     fprintf(stderr, " error: %s", err);
  1104. }
  1105.