2 * main.c -- main program for PCCTS ANTLR.
4 * $Id: main.c,v 1.7 95/10/05 11:57:08 parrt Exp $
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.
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
29 * Parr Research Corporation
30 * with Purdue University and AHPCRC, University of Minnesota
42 #define MAX_INT_STACK 50
43 static int istack[MAX_INT_STACK]; /* Int stack */
44 static int isp = MAX_INT_STACK;
46 static int DontAcceptFiles = 0; /* if stdin, don't read files */
47 static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */
50 /* C m d - L i n e O p t i o n S t r u c t & F u n c s */
64 extern void ProcessArgs(int, char **, Opt *);
66 extern void ProcessArgs();
76 if ( DontAcceptStdin )
78 warnNoFL("'-' (stdin) ignored as files were specified first");
82 require(NumFiles<MaxNumFiles,"exceeded max # of input files");
83 FileStr[NumFiles++] = "stdin";
95 if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
96 if ( DontAcceptFiles )
98 warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
102 require(NumFiles<MaxNumFiles,"exceeded max # of input files");
103 FileStr[NumFiles++] = s;
109 pLLK( char *s, char *t )
118 warnNoFL("must have at least one token of lookahead (setting to 1)");
125 pCk( char *s, char *t )
134 warnNoFL("must have at least one token of look-ahead (setting to 1)");
146 warn("#-variable or other AST item referenced w/o -gt option");
150 static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; }
151 static void pLGen(void) { LexGen = FALSE; }
152 static void pTGen(void) { TraceGen = TRUE; }
153 static void pSGen(void) { GenExprSets = FALSE; }
154 static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); }
155 static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
156 static void pAst(void) { GenAST = TRUE; }
157 static void pANSI(void) { GenANSI = TRUE; }
158 static void pCr(void) { GenCR = TRUE; }
159 /*static void pCt(void) { warnNoFL("-ct option is now the default"); }*/
160 static void pLI(void) { GenLineInfo = TRUE; }
161 static void pFr(char *s, char *t) {RemapFileName = t;}
162 static void pFe(char *s, char *t) {ErrFileName = t;}
163 static void pFl(char *s, char *t) {DlgFileName = t;}
164 static void pFm(char *s, char *t) {ModeFileName = t;}
165 static void pFt(char *s, char *t) {DefFileName = t;}
166 static void pE1(void) { elevel = 1; }
167 static void pE2(void) { elevel = 2; }
168 static void pE3(void) { elevel = 3; }
169 static void pEGen(void) { GenEClasseForRules = 1; }
170 static void pDL(void)
174 warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
179 static void pGHdr(void) { GenStdPccts = 1; }
180 static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
181 static void pW1(void) { WarningLevel = 1; }
182 static void pW2(void) { WarningLevel = 2; }
183 static void pCC(void) { GenCC = TRUE; }
185 static void pCGen() { CodeGen = FALSE; LexGen = FALSE; }
186 static void pLGen() { LexGen = FALSE; }
187 static void pTGen() { TraceGen = TRUE; }
188 static void pSGen() { GenExprSets = FALSE; }
189 static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); }
190 static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
191 static void pAst() { GenAST = TRUE; }
192 static void pANSI() { GenANSI = TRUE; }
193 static void pCr() { GenCR = TRUE; }
194 /*static void pCt() { warnNoFL("-ct option is now the default"); }*/
195 static void pLI() { GenLineInfo = TRUE; }
196 static void pFr(s,t) char *s, *t; {RemapFileName = t;}
197 static void pFe(s,t) char *s, *t; {ErrFileName = t;}
198 static void pFl(s,t) char *s, *t; {DlgFileName = t;}
199 static void pFm(s,t) char *s, *t; {ModeFileName = t;}
200 static void pFt(s,t) char *s, *t; {DefFileName = t;}
201 static void pE1() { elevel = 1; }
202 static void pE2() { elevel = 2; }
203 static void pE3() { elevel = 3; }
204 static void pEGen() { GenEClasseForRules = 1; }
209 warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
213 static void pGHdr() { GenStdPccts = 1; }
214 static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
215 static void pW1() { WarningLevel = 1; }
216 static void pW2() { WarningLevel = 2; }
217 static void pCC() { GenCC = TRUE; }
222 pPre( char *s, char *t )
234 pOut( char *s, char *t )
251 warnNoFL("-pr is no longer used (predicates employed if present); see -prc");
253 if ( DemandLookahead )
254 warnNoFL("-gk conflicts with -pr; -gk turned off");
256 HoistPredicateContext = 0;
262 pPredCtx( char *s, char *t )
269 if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
270 else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
271 else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
272 else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
273 if ( DemandLookahead )
275 warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
282 pTRes( char *s, char *t )
289 TreeResourceLimit = atoi(t);
290 if ( TreeResourceLimit <= 0 )
292 warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
293 TreeResourceLimit = -1; /* set to no limit */
299 { "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"},
300 { "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"},
301 { "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"},
302 { "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"},
303 { "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"},
304 { "-e3", 0, (void (*)(...)) pE3, "Ambiguities/errors shown in excruciating detail"},
305 { "-fe", 1, (void (*)(...)) pFe, "Rename err.c"},
306 { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"},
307 { "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"},
308 { "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"},
309 { "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"},
310 { "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"},
311 { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"},
312 { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"},
313 { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"},
314 { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
315 { "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
316 { "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches 'til needed"},
317 { "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in C parser"},
318 { "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"},
319 { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
320 { "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
321 { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
322 { "-k", 1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"},
323 { "-o", 1, (void (*)(...)) pOut, OutputDirectoryOption},
324 { "-p", 0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"},
325 { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
326 { "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"},
327 { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
328 { "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"},
329 { "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"},
330 { "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
331 { "-", 0, (void (*)(...)) pStdin, "Read grammar from stdin" },
332 { "*", 0, (void (*)(...)) pFile, "" }, /* anything else is a file */
334 { "-CC", 0, pCC, "Generate C++ output (default=FALSE)"},
335 { "-cr", 0, pCr, "Generate cross reference (default=FALSE)"},
336 { "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"},
337 { "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"},
338 { "-e2", 0, pE2, "Ambiguities/errors shown in more detail"},
339 { "-e3", 0, pE3, "Ambiguities/errors shown in excrutiating detail"},
340 { "-fe", 1, pFe, "Rename err.c"},
341 { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"},
342 { "-fl", 1, pFl, "Rename lexical output--parser.dlg"},
343 { "-fm", 1, pFm, "Rename mode.h"},
344 { "-fr", 1, pFr, "Rename remap.h"},
345 { "-ft", 1, pFt, "Rename tokens.h"},
346 { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"},
347 { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"},
348 { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"},
349 { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
350 { "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
351 { "-gk", 0, pDL, "Generate parsers that delay lookahead fetches 'til needed"},
352 { "-gl", 0, pLI, "Generate line info about grammar actions in C parser"},
353 { "-gp", 1, pPre, "Prefix all generated rule functions with a string"},
354 { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
355 { "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
356 { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
357 { "-k", 1, pLLK, "Set full LL(k) lookahead depth (default==1)"},
358 { "-o", 1, pOut, OutputDirectoryOption},
359 { "-p", 0, pPrt, "Print out the grammar w/o actions (default=no)"},
360 { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
361 { "-pr",0, pPred, "no longer used; predicates employed if present"},
362 { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
363 { "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"},
364 { "-w1", 0, pW1, "Set the warning level to 1 (default)"},
365 { "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
366 { "-", 0, pStdin, "Read grammar from stdin" },
367 { "*", 0, pFile, "" }, /* anything else is a file */
376 static void buildRulePtr( void );
377 static void help( void );
378 static void init( void );
379 static void CompleteTokenSetRefs( void );
380 static void ensure_no_C_file_collisions(char *);
382 static void buildRulePtr( );
385 static void CompleteTokenSetRefs( );
386 static void ensure_no_C_file_collisions();
393 main( int argc, char *argv[] )
401 static char EPSTR[] = "[Ep]";
403 /* malloc_debug(8);*/
406 fprintf(stderr, "Antlr parser generator Version %s 1989-1995\n", Version);
407 if ( argc == 1 ) { help(); zzDIE; }
408 ProcessArgs(argc-1, &(argv[1]), options);
410 /* Fix lookahead depth */
411 /* Compressed lookahead must always be larger than or equal to full lookahead */
412 if ( CLL_k < LL_k && CLL_k>0 )
414 warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
417 if ( CLL_k == -1 ) CLL_k = LL_k;
419 if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
421 for(n=1; n<CLL_k; n<<=1) {;}
425 fpTrans = &(C_Trans[0]); /* Translate to C Language */
426 fpJTrans = &(C_JTrans[0]);
428 lexclass(LexStartSymbol);
431 LastTokenCounted = TokenNum;
433 if ( CannotContinue ) {cleanUp(); zzDIE;}
434 if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
435 if ( WarningLevel>1 && HdrAction == NULL )
436 warnNoFL("no #header action was found");
438 EpToken = addTname(EPSTR); /* add imaginary token epsilon */
439 set_orel(EpToken, &imag_tokens);
441 /* this won't work for hand-built scanners since EofToken is not
442 * known. Forces EOF to be token type 1.
444 set_orel(EofToken, &imag_tokens);
446 set_size(NumWords(TokenNum-1));
448 /* compute the set of all known token types
449 * It represents the set of tokens from 1 to last_token_num + the
450 * reserved positions above that (if any). Don't include the set of
451 * imaginary tokens such as the token/error classes or EOF.
455 a = set_dup(reserved_positions);
456 for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
457 all_tokens = set_dif(a, imag_tokens);
461 ComputeTokSets(); /* Compute #tokclass sets */
462 CompleteTokenSetRefs(); /* Change complex nodes in syn diag */
464 if ( CodeGen ) genDefFile(); /* create tokens.h */
465 if ( LexGen ) genLexDescr(); /* create parser.dlg */
469 FILE *f = fopen(OutMetaName(stdpccts), "w");
470 if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
473 special_fopen_actions(OutMetaName(stdpccts));
474 genStdPCCTSIncludeFile(f);
479 buildRulePtr(); /* create mapping from rule # to RuleBlk junction */
481 FoLink( (Node *)SynDiag ); /* add follow links to end of all rules */
483 if ( GenCR ) GenCrossRef( SynDiag );
487 if ( SynDiag == NULL )
489 warnNoFL("no grammar description recognized");
494 ErrFile = fopen(OutMetaName(ErrFileName), "w");
495 require(ErrFile != NULL, "main: can't open err file");
496 special_fopen_actions(OutMetaName(ErrFileName));
499 TRANS(SynDiag); /* Translate to the target language */
501 DumpRemainingTokSets();
505 strcpy(Parser_h_Name, CurrentClassName);
506 strcat(Parser_h_Name, ".h");
507 strcpy(Parser_c_Name, CurrentClassName);
508 strcat(Parser_c_Name, CPP_FILE_SUFFIX);
509 ensure_no_C_file_collisions(Parser_c_Name);
510 Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
511 require(Parser_h != NULL, "main: can't open class Parserx.h file");
512 special_fopen_actions(OutMetaName(Parser_h_Name));
513 Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
514 require(Parser_c != NULL, "main: can't open class Parserx.c file");
515 special_fopen_actions(OutMetaName(Parser_c_Name));
517 if ( class_before_actions != NULL )
520 for (p = class_before_actions->next; p!=NULL; p=p->next)
522 UserAction *ua = (UserAction *)p->elem;
523 dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
528 TRANS(SynDiag); /* Translate to the target language */
530 GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
531 if ( class_after_actions != NULL )
534 for (p = class_after_actions->next; p!=NULL; p=p->next)
536 UserAction *ua = (UserAction *)p->elem;
537 dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
540 DumpRemainingTokSets();
541 fprintf(Parser_h, "};\n");
542 fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName);
550 if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
554 GenRemapFile(); /* create remap.h */
557 exit(PCCTS_EXIT_SUCCESS);
569 Tname = newHashTable();
570 Rname = newHashTable();
571 Fcache = newHashTable();
572 Tcache = newHashTable();
573 Sname = newHashTable();
574 /* Add default signal names */
575 q = (SignalEntry *)hash_add(Sname,
577 (Entry *)newSignalEntry("NoViableAlt"));
578 require(q!=NULL, "cannot alloc signal entry");
579 q->signum = sigNoViableAlt;
580 q = (SignalEntry *)hash_add(Sname,
582 (Entry *)newSignalEntry("MismatchedToken"));
583 require(q!=NULL, "cannot alloc signal entry");
584 q->signum = sigMismatchedToken;
585 q = (SignalEntry *)hash_add(Sname,
587 (Entry *)newSignalEntry("NoSemViableAlt"));
588 require(q!=NULL, "cannot alloc signal entry");
589 q->signum = sigNoSemViableAlt;
591 reserved_positions = empty;
595 TokenStr = (char **) calloc(TSChunk, sizeof(char *));
596 require(TokenStr!=NULL, "main: cannot allocate TokenStr");
597 FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
598 require(FoStack!=NULL, "main: cannot allocate FoStack");
599 FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
600 require(FoTOS!=NULL, "main: cannot allocate FoTOS");
601 Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
602 require(Cycles!=NULL, "main: cannot allocate Cycles List");
613 fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
614 while ( *(p->option) != '*' )
616 fprintf(stderr, "\t%-4s %s %s\n",
624 /* The RulePtr array is filled in here. RulePtr exists primarily
625 * so that sets of rules can be maintained for the FOLLOW caching
626 * mechanism found in rJunc(). RulePtr maps a rule num from 1 to n
627 * to a pointer to its RuleBlk junction where n is the number of rules.
637 Junction *p = SynDiag;
638 RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
639 require(RulePtr!=NULL, "cannot allocate RulePtr array");
643 require(r<=NumRules, "too many rules???");
645 p = (Junction *)p->p2;
651 dlgerror(const char *s)
657 fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
658 fprintf(stderr, " lexical error: %s (text was '%s')\n",
659 ((s == NULL) ? "Lexical error" : s), zzlextext);
671 if ( input==NULL ) fatal("No grammar description found (exiting...)");
672 ANTLR(grammar(), input);
687 if ( CurFile >= NumFiles ) return(NULL);
688 if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
689 f = fopen(FileStr[CurFile], "r");
692 warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
702 * Return a string corresponding to the output file name associated
703 * with the input file name passed in.
705 * Observe the following rules:
712 * Where f,e,g are arbitrarily long sequences of characters in a file
715 * In other words, if a ".x" appears on the end of a file name, make it
716 * ".c". If no ".x" appears, append ".c" to the end of the file name.
718 * C++ mode using .cpp not .c.
720 * Use malloc() for new string.
730 static char buf[MaxFileName+1];
732 require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
736 while ( *p != '\0' ) {p++;} /* Stop on '\0' */
737 while ( *p != '.' && p != buf ) {--p;} /* Find '.' */
738 if ( p != buf ) *p = '\0'; /* Found '.' */
739 require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");
740 if ( GenCC ) strcat(buf, CPP_FILE_SUFFIX);
741 else strcat(buf, ".c");
747 fatalFL( char *err_, char *f, int l )
749 fatalFL( err_, f, l )
755 fprintf(stderr, ErrHdr, f, l);
756 fprintf(stderr, " %s\n", err_);
758 exit(PCCTS_EXIT_FAILURE);
763 fatal_intern( char *err_, char *f, int l )
765 fatal_intern( err_, f, l )
771 fprintf(stderr, ErrHdr, f, l);
772 fprintf(stderr, " #$%%*&@# internal error: %s\n", err_);
773 fprintf(stderr, ErrHdr, f, l);
774 fprintf(stderr, " [complain to nearest government official\n");
775 fprintf(stderr, ErrHdr, f, l);
776 fprintf(stderr, " or send hate-mail to parrt@parr-research.com;\n");
777 fprintf(stderr, ErrHdr, f, l);
778 fprintf(stderr, " please pray to the ``bug'' gods that there is a trival fix.]\n");
780 exit(PCCTS_EXIT_FAILURE);
790 if ( DefFile != NULL) fclose( DefFile );
793 /* sprintf up to 3 strings */
796 eMsg3( char *s, char *a1, char *a2, char *a3 )
798 eMsg3( s, a1, a2, a3 )
805 static char buf[250]; /* DANGEROUS as hell !!!!!! */
807 sprintf(buf, s, a1, a2, a3);
811 /* sprintf a decimal */
814 eMsgd( char *s, int d )
821 static char buf[250]; /* DANGEROUS as hell !!!!!! */
829 s_fprT( FILE *f, set e )
836 register unsigned *p;
839 if ( set_nil(e) ) return;
840 if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
844 fprintf(f, " %s", TerminalString(*p));
851 /* Return the token name or regular expression for a token number. */
854 TerminalString( int token )
856 TerminalString( token )
862 /* look in all lexclasses for the token */
863 if ( TokenString(token) != NULL ) return TokenString(token);
864 for (j=0; j<NumLexClasses; j++)
867 if ( ExprString(token) != NULL ) return ExprString(token);
869 require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
873 /* S i m p l e I n t S t a c k */
883 require(isp>0, "pushint: stack overflow");
894 require(isp<MAX_INT_STACK, "popint: stack underflow");
895 return istack[isp++];
905 return MAX_INT_STACK-isp;
925 return isp==MAX_INT_STACK;
935 require(isp<MAX_INT_STACK, "topint: stack underflow");
941 ProcessArgs( int argc, char **argv, Opt *options )
943 ProcessArgs( argc, argv, options )
950 require(argv!=NULL, "ProcessArgs: command line NULL");
955 while ( p->option != NULL )
957 if ( strcmp(p->option, "*") == 0 ||
958 strcmp(p->option, *argv) == 0 )
962 (*p->process)( *argv, *(argv+1) );
967 (*p->process)( *argv );
976 /* Go back into the syntax diagram and compute all meta tokens; i.e.
977 * turn all '.', ranges, token class refs etc... into actual token sets
980 CompleteTokenSetRefs()
984 if ( MetaTokenNodes==NULL ) return;
985 for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
989 TokNode *q = (TokNode *)p->elem;
992 q->tset = all_tokens;
994 else if ( q->tclass!=NULL )
996 if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
997 else q->tset = q->tclass->tset;
999 else if ( q->upper_range!=0 )
1001 /* we have a range on our hands: make a set from q->token .. q->upper_range */
1004 for (i=q->token; i<=(int)q->upper_range; i++) { set_orel(i, &a); }
1007 /* at this point, it can only be a complemented single token */
1008 else if ( q->complement )
1010 a = set_of(q->token);
1011 b = set_dif(all_tokens, a);
1015 else fatal("invalid meta token");
1021 OutMetaName(char *n)
1027 static char buf[MaxFileName+1];
1029 if ( strcmp(OutputDirectory,TopDirectory)==0 ) return n;
1030 strcpy(buf, OutputDirectory);
1031 if ( strcmp(&buf[strlen(buf) - 1], DirectorySymbol ) )
1032 strcat(buf, DirectorySymbol);
1039 ensure_no_C_file_collisions(char *class_c_file)
1041 ensure_no_C_file_collisions(class_c_file)
1047 for (i=0; i<NumFiles; i++)
1050 /* assume that file names are case insensitive */
1051 if ( stricmp(outname(FileStr[i]), class_c_file)==0 )
1053 if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
1056 fatal(eMsg1("class def output file conflicts with parser output file: %s",
1057 outname(FileStr[i])));
1070 fprintf(stderr, "warning: %s\n", err);
1075 warnFL(char *err,char *f,int l)
1083 fprintf(stderr, ErrHdr, f, l);
1084 fprintf(stderr, " warning: %s\n", err);
1095 /* back up the file number if we hit an error at the end of the last file */
1096 if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
1097 fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
1098 fprintf(stderr, " warning: %s\n", err);
1103 warnNoCR( char *err )
1109 /* back up the file number if we hit an error at the end of the last file */
1110 if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
1111 fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
1112 fprintf(stderr, " warning: %s", err);
1123 fprintf(stderr, "error: %s\n", err);
1128 errFL(char *err,char *f,int l)
1136 fprintf(stderr, ErrHdr, f, l);
1137 fprintf(stderr, " error: %s\n", err);
1148 /* back up the file number if we hit an error at the end of the last file */
1149 if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
1150 fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
1151 fprintf(stderr, " error: %s\n", err);
1156 errNoCR( char *err )
1162 /* back up the file number if we hit an error at the end of the last file */
1163 if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
1164 fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
1165 fprintf(stderr, " error: %s", err);
1170 newUserAction(char *s)
1176 UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
1177 require(ua!=NULL, "cannot allocate UserAction");
1179 ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
1180 strcpy(ua->action, s);
1184 /* Added by TJP September 1994 */
1185 /* Take in file.h and return file_h; names w/o '.'s are left alone */
1188 gate_symbol(char *name)
1194 static char buf[100];
1196 sprintf(buf, "%s", name);
1198 for (p=buf; *p!='\0'; p++)
1200 if ( *p=='.' ) *p = '_';
1207 makeAltID(int blockid, int altnum)
1209 makeAltID(blockid, altnum)
1214 static char buf[100];
1216 sprintf(buf, "_blk%d_alt%d", blockid, altnum);
1217 p = (char *)malloc(strlen(buf)+1);