main.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:48k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * main.c -- main program for PCCTS ANTLR.
  3.  *
  4.  * SOFTWARE RIGHTS
  5.  *
  6.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  7.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  8.  * company may do whatever they wish with source code distributed with
  9.  * PCCTS or the code generated by PCCTS, including the incorporation of
  10.  * PCCTS, or its output, into commerical software.
  11.  *
  12.  * We encourage users to develop software with PCCTS.  However, we do ask
  13.  * that credit is given to us for developing PCCTS.  By "credit",
  14.  * we mean that if you incorporate our source code into one of your
  15.  * programs (commercial product, research project, or otherwise) that you
  16.  * acknowledge this fact somewhere in the documentation, research report,
  17.  * etc...  If you like PCCTS and have developed a nice tool with the
  18.  * output, please mention that you developed it using PCCTS.  In
  19.  * addition, we ask that this header remain intact in our source code.
  20.  * As long as these guidelines are kept, we expect to continue enhancing
  21.  * this system and expect to make other tools available as they are
  22.  * completed.
  23.  *
  24.  * ANTLR 1.33
  25.  * Terence Parr
  26.  * Parr Research Corporation
  27.  * with Purdue University and AHPCRC, University of Minnesota
  28.  * 1989-1998
  29.  */
  30. #include <stdio.h>
  31. #ifdef __cplusplus
  32. #ifndef __STDC__
  33. #define __STDC__
  34. #endif
  35. #endif
  36. #include "stdpccts.h"
  37. #define MAX_INT_STACK 50
  38. static int istack[MAX_INT_STACK]; /* Int stack */
  39. static int isp = MAX_INT_STACK;
  40. static int DontAcceptFiles = 0; /* if stdin, don't read files */
  41. static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */
  42. static int tnodes_used_in_guard_predicates_etc;     /* MR10 */
  43. /* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */
  44. typedef struct _Opt {
  45. char *option;
  46. int  arg;
  47. #ifdef __cplusplus
  48. void (*process)(...);
  49. #else
  50. void (*process)();
  51. #endif
  52. char *descr;
  53. } Opt;
  54. #ifdef __STDC__
  55. extern void ProcessArgs(int, char **, Opt *);
  56. #else
  57. extern void ProcessArgs();
  58. #endif
  59. #ifdef __STDC__
  60. int ci_strequ(char *a,char *b)
  61. #else
  62. int ci_strequ(a,b)
  63.   char  *a;
  64.   char  *b;
  65. #endif
  66. {
  67.   for ( ;*a != 0 && *b != 0; a++, b++) {
  68.     if (toupper(*a) != toupper(*b)) return 0;
  69.   }
  70.   return (*a == *b);
  71. }
  72. static void
  73. #ifdef __STDC__
  74. pStdin( void )
  75. #else
  76. pStdin( )
  77. #endif
  78. {
  79. if ( DontAcceptStdin )
  80. {
  81. warnNoFL("'-' (stdin) ignored as files were specified first");
  82. return;
  83. }
  84. require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  85. FileStr[NumFiles++] = "stdin";
  86. DontAcceptFiles = 1;
  87. }
  88. static void
  89. #ifdef __STDC__
  90. pFile( char *s )
  91. #else
  92. pFile( s )
  93. char *s;
  94. #endif
  95. {
  96. if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
  97. if ( DontAcceptFiles )
  98. {
  99. warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
  100. return;
  101. }
  102. require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  103. FileStr[NumFiles++] = s;
  104. DontAcceptStdin = 1;
  105. }
  106. /* MR14
  107.         Allow input to be a file containing a list of files
  108.         Bernard Giroud (b_giroud@decus.ch)
  109. */
  110. static void
  111. #ifdef __STDC__
  112. pFileList( char *s, char *t )
  113. #else
  114. pFileList( s, t )
  115. char *s;
  116. char *t;
  117. #endif
  118. {
  119. #define MaxFLArea 1024
  120. FILE *fl;
  121. static char Fn_in_Fl[MaxFLArea] = "";
  122.         char one_fn[MaxFileName];
  123. char *flp = &Fn_in_Fl[0];
  124. int fnl, left = MaxFLArea, i;
  125. if ( *t=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",t) ); return; }
  126. if ( DontAcceptFiles )
  127. {
  128. warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",t));
  129. return;
  130. }
  131.         if ((fl = fopen(t, "r")) == NULL)
  132. {
  133. warnNoFL(eMsg1("file '%s' can't be opened", t));
  134. return;
  135. }
  136.         for (;;)
  137. {
  138. if (fgets(one_fn, 128 - 1, fl) == NULL)
  139. break;
  140. fnl = strlen(one_fn);
  141. require(fnl<=left, "no more room in File List Area");
  142. /* drop the trailing LF */
  143. if (one_fn[fnl - 1] == 0x0a) one_fn[fnl - 1] = ' ';
  144. strcat(Fn_in_Fl, one_fn);
  145. left = left - fnl;
  146. require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  147. FileStr[NumFiles++] = flp;
  148. flp = flp + fnl;
  149. }
  150. fclose(fl);
  151. for (i=0;i < MaxFLArea;i++) if (Fn_in_Fl[i] == ' ') Fn_in_Fl[i] = '';
  152. DontAcceptStdin = 1;
  153. }
  154. static void
  155. #ifdef __STDC__
  156. pLLK( char *s, char *t )
  157. #else
  158. pLLK( s, t )
  159. char *s;
  160. char *t;
  161. #endif
  162. {
  163. LL_k = atoi(t);
  164. if ( LL_k <= 0 ) {
  165. warnNoFL("must have at least one token of lookahead (setting to 1)");
  166. LL_k = 1;
  167. }
  168. }
  169. static void
  170. #ifdef __STDC__
  171. pCk( char *s, char *t )
  172. #else
  173. pCk( s, t )
  174. char *s;
  175. char *t;
  176. #endif
  177. {
  178. CLL_k = atoi(t);
  179. if ( CLL_k <= 0 ) {
  180. warnNoFL("must have at least one token of look-ahead (setting to 1)");
  181. CLL_k = 1;
  182. }
  183. }
  184. static void                                      /* MR6 */
  185. #ifdef __STDC__
  186. pTab( char *s, char *t )                               /* MR6 */
  187. #else
  188. pTab( s, t )                                   /* MR6 */
  189. char *s;                                  /* MR6 */
  190. char *t;                                  /* MR6 */
  191. #endif
  192. {                                      /* MR6 */
  193. TabWidth = atoi(t);                              /* MR6 */
  194. if ( TabWidth < 0 || TabWidth > 8 ) {                   /* MR6 */
  195. warnNoFL("tab width must be between 1 and 8");               /* MR6 */
  196.   TabWidth=0;                              /* MR6 */
  197. }                                      /* MR6 */
  198. }                                          /* MR6 */
  199. static int ambAidDepthSpecified=0;                                   /* MR11 */
  200. static void                                      /* MR11 */
  201. #ifdef __STDC__
  202. pAAd( char *s, char *t )                               /* MR11 */
  203. #else
  204. pAAd( s, t )                                   /* MR11 */
  205. char *s;                                  /* MR11 */
  206. char *t;                                  /* MR11 */
  207. #endif
  208. {                                      /* MR11 */
  209.     ambAidDepthSpecified=1;                                          /* MR11 */
  210. MR_AmbAidDepth = atoi(t);                          /* MR11 */
  211. }                                          /* MR11 */
  212. static void                                      /* MR11 */
  213. #ifdef __STDC__
  214. pTreport( char *s, char *t )                              /* MR11 */
  215. #else
  216. pTreport( s, t )                                 /* MR11 */
  217.     char *s;                              /* MR11 */
  218.     char *t;                              /* MR11 */
  219. #endif
  220. {                                      /* MR11 */
  221. TnodesReportThreshold = atoi(t);                  /* MR11 */
  222. }                                          /* MR11 */
  223. #ifdef __STDC__
  224. void chkGTFlag(void)                                     /* 7-Apr-97 MR1 */
  225. #else
  226. void chkGTFlag()                                            /* 7-Apr-97 MR1 */
  227. #endif
  228. {
  229. if ( !GenAST )
  230. warn("#-variable or other AST item referenced w/o -gt option");
  231. }
  232. #ifdef __STDC__
  233. static void pInfo(char *s, char *t)                         /* MR10 */
  234. #else
  235. static void pInfo(s,t)                                      /* MR10 */
  236.   char  *s;
  237.   char  *t;
  238. #endif
  239. {
  240.   char  *p;
  241.   int   q;
  242.   for (p=t; *p != 0; p++) {
  243.     q=tolower(*p);
  244.     if (q=='t') {
  245.       InfoT=1;
  246.     } else if (q=='p') {
  247.       InfoP=1;
  248.     } else if (q=='m') {
  249.       InfoM=1;
  250.     } else if (q=='o') {
  251.       InfoO=1;
  252.     } else if (q=='0') {
  253.       ; /* nothing */
  254.     } else if (q=='f') {
  255.       InfoF=1;
  256.     } else {
  257.       warnNoFL(eMsgd("unrecognized -info option "%c"",(int)*p));
  258.     };
  259.   };
  260. }
  261. #ifdef __STDC__
  262. static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; }
  263. static void pLGen(void) { LexGen = FALSE; }
  264. static void pXTGen(void){ MR_Inhibit_Tokens_h_Gen = TRUE; }
  265. static void pTGen(void) { TraceGen = TRUE; }
  266. static void pSGen(void) { GenExprSetsOpt = FALSE; }
  267. static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); }
  268. static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  269. static void pAst(void) { GenAST = TRUE; }
  270. static void pANSI(void) { GenANSI = TRUE; }
  271. static void pCr(void) { GenCR = TRUE; }
  272. /*static void pCt(void) { warnNoFL("-ct option is now the default"); }*/
  273. static void pLI(void) { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */
  274. static void pLIms(void) { GenLineInfo = TRUE; GenLineInfoMS = TRUE; }  /* MR14 */
  275. static void pFr(char *s, char *t) {RemapFileName = t;}
  276. static void pFe(char *s, char *t) {ErrFileName = t;}
  277. static void pFl(char *s, char *t) {DlgFileName = t;}
  278. static void pFm(char *s, char *t) {ModeFileName = t;}
  279. static void pFt(char *s, char *t) {DefFileName = t;}
  280. static void pE1(void) { elevel = 1; }
  281. static void pE2(void) { elevel = 2; }
  282. static void pE3(void) { elevel = 3; }
  283. static void pEGen(void) { GenEClasseForRules = 1; }
  284. static void pDL(void)
  285. {
  286.     DemandLookahead = 1;
  287.     if ( GenCC ) {
  288. warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
  289. DemandLookahead = 0;
  290.     }
  291. }
  292. static void pAA(char *s,char *t) {MR_AmbAidRule = t;}               /* MR11 */
  293. static void pAAm(char *s){MR_AmbAidMultiple = 1;}                   /* MR11 */
  294. static void pGHdr(void) { GenStdPccts = 1; }
  295. static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
  296. static void pW1(void) { WarningLevel = 1; }
  297. static void pNewAST(void) { NewAST = 1; }                           /* MR13 */
  298. static void pAlpha(void) { AlphaBetaTrace = 1; }                    /* MR14 */
  299. static void pStdout(void) {UseStdout = 1; }                     /* MR6 */
  300. static void pW2(void) { WarningLevel = 2; }
  301. static void pCC(void) { GenCC = TRUE; }
  302. #else
  303. static void pCGen() { CodeGen = FALSE; LexGen = FALSE; }
  304. static void pLGen() { LexGen = FALSE; }
  305. static void pXTGen(){ MR_Inhibit_Tokens_h_Gen = TRUE; }             /* MR14 */
  306. static void pTGen() { TraceGen = TRUE; }
  307. static void pSGen() { GenExprSetsOpt = FALSE; }
  308. static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); }
  309. static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  310. static void pAst() { GenAST = TRUE; }
  311. static void pANSI() { GenANSI = TRUE; }
  312. static void pCr() { GenCR = TRUE; }
  313. /*static void pCt() { warnNoFL("-ct option is now the default"); }*/
  314. static void pLI()     { GenLineInfo = TRUE; GenLineInfoMS = FALSE; }  /* MR14 */
  315. static void pLIms()     { GenLineInfo = TRUE; GenLineInfoMS = TRUE; }   /* MR14 */
  316. static void pFr(s,t) char *s, *t; {RemapFileName = t;}
  317. static void pFe(s,t) char *s, *t; {ErrFileName = t;}
  318. static void pFl(s,t) char *s, *t; {DlgFileName = t;}
  319. static void pFm(s,t) char *s, *t; {ModeFileName = t;}
  320. static void pFt(s,t) char *s, *t; {DefFileName = t;}
  321. static void pE1() { elevel = 1; }
  322. static void pE2() { elevel = 2; }
  323. static void pE3() { elevel = 3; }
  324. static void pEGen() { GenEClasseForRules = 1; }
  325. static void pDL()
  326. {
  327.     DemandLookahead = 1;
  328.     if ( GenCC ) {
  329.           warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
  330.       DemandLookahead = 0;
  331.     }
  332. }
  333. static void pAA(s,t) char *s; char *t; {MR_AmbAidRule = t;}          /* MR11 BJS 20-Mar-98 */
  334. static void pAAm(s) char *s; {MR_AmbAidMultiple = 1;}                /* MR11 BJS 20-Mar-98 */
  335. static void pGHdr() { GenStdPccts = 1; }
  336. static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
  337. static void pW1() { WarningLevel = 1; }
  338. static void pNewAST() { NewAST = 1; }                                /* MR13 */
  339. static void pAlpha() { AlphaBetaTrace = 1; }                         /* MR14 */
  340. static void pStdout() {UseStdout = 1; }                              /* MR6 */
  341. static void pW2() { WarningLevel = 2; }
  342. static void pCC() { GenCC = TRUE; }
  343. #endif
  344. static void
  345. #ifdef __STDC__
  346. pPre( char *s, char *t )
  347. #else
  348. pPre( s, t )
  349. char *s;
  350. char *t;
  351. #endif
  352. {
  353. RulePrefix = t;
  354. }
  355. static void
  356. #ifdef __STDC__
  357. pOut( char *s, char *t )
  358. #else
  359. pOut( s, t )
  360. char *s;
  361. char *t;
  362. #endif
  363. {
  364. OutputDirectory = t;
  365. }
  366. static void
  367. #ifdef __STDC__
  368. pPred( void )
  369. #else
  370. pPred( )
  371. #endif
  372. {
  373. warnNoFL("-pr is no longer used (predicates employed if present); see -prc, -mrhoist, -mrhoistk");
  374. /*
  375. ** if ( DemandLookahead )
  376. ** warnNoFL("-gk conflicts with -pr; -gk turned off");
  377. ** DemandLookahead = 0;
  378. ** HoistPredicateContext = 0;
  379. */
  380. }
  381. static void
  382. #ifdef __STDC__
  383. pPredCtx( char *s, char *t )
  384. #else
  385. pPredCtx(s,t)
  386. char *s;
  387. char *t;
  388. #endif
  389. {
  390. if ( ci_strequ(t,"on")) HoistPredicateContext = 1;
  391. else if ( ci_strequ(t,"off")) HoistPredicateContext = 0;
  392. if ( DemandLookahead )
  393. {
  394. warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
  395. DemandLookahead = 0;
  396. }
  397. }
  398. static void
  399. #ifdef __STDC__
  400. pMRhoist( char *s, char *t )
  401. #else
  402. pMRhoist(s,t)
  403. char *s;
  404. char *t;
  405. #endif
  406. {
  407. if ( ci_strequ(t,"on")) MRhoisting = 1;
  408. else if ( ci_strequ(t,"off")==0 ) MRhoisting = 0;
  409.     if (MRhoisting) {
  410.         fprintf(stderr,"Maintenance Release style hoisting enabled for predicates with lookahead depth = 1n");
  411.         fprintf(stderr,"  No longer considered experimentaln");
  412.         fprintf(stderr,"  Can't consider suppression for predicates with lookahead depth > 1n");
  413.         fprintf(stderr,"  Implies -prc on but does *not* imply -mrhoistk for k>1 predicatesn");
  414.     };
  415. }
  416. static void
  417. #ifdef __STDC__
  418. pMRhoistk( char *s, char *t )
  419. #else
  420. pMRhoistk(s,t)
  421. char *s;
  422. char *t;
  423. #endif
  424. {
  425. if ( ci_strequ(t,"on")) MRhoistingk = 1;
  426. else if ( ci_strequ(t,"off")==0 ) MRhoistingk = 0;
  427.     if (MRhoistingk) {
  428.         fprintf(stderr,"EXPERIMENTAL Maintenance Release style hoisting enabledn");
  429.         fprintf(stderr,"  Applies to predicates with lookahead depth > 1n");
  430.         fprintf(stderr,"  Implies -prc on and -mrhoist onn");
  431.     };
  432. }
  433. static void
  434. #ifdef __STDC__
  435. pTRes( char *s, char *t )
  436. #else
  437. pTRes( s, t )
  438. char *s;
  439. char *t;
  440. #endif
  441. {
  442. TreeResourceLimit = atoi(t);
  443. if ( TreeResourceLimit <= 0 )
  444. {
  445. warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
  446. TreeResourceLimit = -1; /* set to no limit */
  447. }
  448. }
  449. Opt options[] = {
  450. #ifdef __cplusplus
  451.     { "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"},
  452.     { "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"},
  453.     { "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"},
  454.     { "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"},
  455.     { "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"},
  456.     { "-e3", 0, (void (*)(...)) pE3,
  457.      "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},
  458.     { "-f",  1, (void (*)(...)) pFileList,"Read names of grammar files from specified file"}, /* MR14 */
  459.     { "-fe", 1, (void (*)(...)) pFe, "Rename err.c"},
  460.     { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"},
  461.     { "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"},
  462.     { "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"},
  463.     { "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"},
  464.     { "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"},
  465.     { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"},
  466.     { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"},
  467.     { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"},
  468.     { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
  469.     { "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  470.     { "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches until needed"},
  471.     { "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in parser"},
  472.     { "-glms", 0, (void (*)(...)) pLIms,"Like -gl but replace '\' with '/' in #line filenames for MS C/C++ systems"},
  473.     { "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"},
  474.     { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
  475.     { "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  476.     { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
  477.     { "-gxt",0, (void (*)(...)) pXTGen, "Do not generate tokens.h (default=FALSE)"},
  478.     { "-k",  1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"},
  479.     { "-o",  1, (void (*)(...)) pOut, OutputDirectoryOption},
  480.     { "-p",  0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"},
  481.     { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  482.     { "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"},
  483.     { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  484.     { "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"},
  485.     { "-stdout",0,  (void (*)(...)) pStdout,"Send grammar.c/grammar.cpp to stdout"},           /* MR6 */
  486. { "-tab", 1, (void (*)(...)) pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */
  487. { "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"},
  488. { "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
  489. { "-",   0, (void (*)(...)) pStdin, "Read grammar from stdin" },
  490.     { "-mrhoist",1, (void (*)(...)) pMRhoist,                                                  /* MR9 */
  491.                                         "Turn on/off k=1 Maintenance Release style hoisting"},  /* MR9 */
  492.     { "-mrhoistk",1, (void (*)(...)) pMRhoistk,                                                  /* MR9 */
  493.                                         "Turn on/off EXPERIMENTAL k>1 Maintenance Release style hoisting"},  /* MR13 */
  494.     { "-aa"  , 1, (void (*)(...)) pAA,  "Ambiguity aid for a rule (rule name or line number)"},          /* MR11 */
  495.     { "-aam" , 0, (void (*)(...)) pAAm,
  496.                                          "Lookahead token may appear multiple times in -aa listing"},    /* MR11 */
  497.     { "-aad" , 1, (void (*)(...)) pAAd,
  498.                                          "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */
  499. { "-info", 1, (void (*)(...)) pInfo,
  500.       "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"},                          /* MR12 */
  501.     { "-treport",1,(void (*)(...)) pTreport,
  502.                         "Report when tnode usage exceeds value during ambiguity resolution"},            /* MR11 */
  503. { "-newAST", 0, (void (*)(...)) pNewAST,
  504.                  "In C++ mode use "newAST(...)" rather than "new AST(...)""},                        /* MR13 */
  505.     { "-alpha",0,(void (*)(...)) pAlpha,
  506.                  "Provide additional information for "(alpha)? beta" error messages"},                 /* MR14 */
  507. { "*",   0, (void (*)(...)) pFile,  "" }, /* anything else is a file */
  508. #else
  509.     { "-CC", 0, pCC, "Generate C++ output (default=FALSE)"},
  510.     { "-cr", 0, pCr, "Generate cross reference (default=FALSE)"},
  511.     { "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"},
  512.     { "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"},
  513.     { "-e2", 0, pE2, "Ambiguities/errors shown in more detail"},
  514.     { "-e3", 0, pE3,    "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},
  515.     { "-f",  1, pFileList,"Read names of grammar files from specified file"},   /* MR14 */
  516.     { "-fe", 1, pFe, "Rename err.c"},
  517.     { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"},
  518.     { "-fl", 1, pFl, "Rename lexical output--parser.dlg"},
  519.     { "-fm", 1, pFm, "Rename mode.h"},
  520.     { "-fr", 1, pFr, "Rename remap.h"},
  521.     { "-ft", 1, pFt, "Rename tokens.h"},
  522.     { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"},
  523.     { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"},
  524.     { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"},
  525.     { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
  526.     { "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  527.     { "-gk", 0, pDL, "Generate parsers that delay lookahead fetches until needed"},
  528.     { "-gl", 0, pLI, "Generate line info about grammar actions in C parser"},
  529.     { "-glms", 0, pLIms,"Like -gl but replace '\' with '/' in #line filenames for MS C/C++ systems"},
  530.     { "-gp", 1, pPre, "Prefix all generated rule functions with a string"},
  531.     { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
  532.     { "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  533.     { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
  534.     { "-gxt",0, pXTGen, "Do not generate tokens.h (default=FALSE)"},
  535.     { "-k",  1, pLLK, "Set full LL(k) lookahead depth (default==1)"},
  536.     { "-o",  1, pOut, OutputDirectoryOption},
  537.     { "-p",  0, pPrt, "Print out the grammar w/o actions (default=no)"},
  538.     { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  539.     { "-pr",0, pPred, "no longer used; predicates employed if present"},
  540.     { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  541.     { "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"},
  542.     { "-stdout",0, pStdout, "Send grammar.c/grammar.cpp to stdout"},               /* MR6 */
  543.     { "-tab", 1, pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */
  544. { "-w1", 0, pW1, "Set the warning level to 1 (default)"},
  545. { "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
  546.     { "-mrhoist",1,pMRhoist,                                                       /* MR9 */
  547.                          "Turn on/off k=1 Maintenance Release style hoisting"},  /* MR9 */
  548.     { "-mrhoistk",1,pMRhoistk,                                                       /* MR13 */
  549.                          "Turn on/off k>1 EXPERIMENTAL Maintenance Release style hoisting"},  /* MR13 */
  550.     { "-aa"  ,1,pAA,     "Ambiguity aid for a rule (rule name or line number)"},          /* MR11 */
  551.     { "-aam" ,0,pAAm,
  552.                          "Lookahead token may appear multiple times in -aa listing"},     /* MR11 */
  553.     { "-aad" ,1,pAAd,
  554.                          "Limits exp growth of -aa listing - default=1 (max=ck value)"},  /* MR11 */
  555. { "-info",1,pInfo,
  556.       "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"},           /* MR11 */
  557.     { "-treport",1,pTreport,
  558.                         "Report when tnode usage exceeds value during ambiguity resolution"},   /* MR11 */
  559. { "-newAST", 0, pNewAST,
  560.                  "In C++ mode use "newAST(...)" rather than "new AST(...)""},         /* MR13 */
  561.     { "-alpha",0, pAlpha,
  562.                  "Provide additional information for "(alpha)? beta" error messages"},  /* MR14 */
  563. { "-",   0, pStdin, "Read grammar from stdin" },
  564. { "*",   0, pFile,  "" }, /* anything else is a file */
  565. #endif
  566. { NULL,  0, NULL }
  567.  };
  568. void readDescr();
  569. void cleanUp();
  570. #ifdef __STDC__
  571. static void buildRulePtr( void );
  572. static void help( void );
  573. static void init( void );
  574. static void CompleteTokenSetRefs( void );
  575. static void ensure_no_C_file_collisions(char *);
  576. static void CompleteContextGuards();
  577. #else
  578. static void buildRulePtr( );
  579. static void help( );
  580. static void init( );
  581. static void CompleteTokenSetRefs( );
  582. static void ensure_no_C_file_collisions();
  583. static void CompleteContextGuards();
  584. #endif
  585. static void
  586. #ifdef __STDC__  /* <BJS> */
  587. report_numericPredLabels(ActionNode *a)
  588. #else
  589. report_numericPredLabels(a)
  590. ActionNode *a;
  591. #endif
  592. {                                                                           /* MR10 */
  593.   warnFL("numeric references to attributes (e.g. $i or $i.j) in semantic pred will be null during guess mode",  /* MR10 */
  594.             FileStr[a->file],a->line);                                      /* MR10 */
  595. }                                                                           /* MR10 */
  596. /* M a i n */
  597. int
  598. #ifdef __STDC__
  599. main( int argc, char *argv[] )
  600. #else
  601. main( argc, argv )
  602. int argc;
  603. char *argv[];
  604. #endif
  605. {
  606. int i;
  607. static char EPSTR[] = "[Ep]";
  608.     Save_argc=argc;                                                  /* MR10 */
  609.     Save_argv=argv;                                                  /* MR10 */
  610. /* malloc_debug(8);*/
  611. #ifdef SPECIAL_INITS
  612.     special_inits();                                                 /* MR1 */
  613. #endif
  614. fprintf(stderr, "Antlr parser generator   Version %s   1989-1998n", Version);
  615. if ( argc == 1 ) { help(); zzDIE; }
  616. ProcessArgs(argc-1, &(argv[1]), options);
  617. /* MR14 */    if (MR_AmbAidRule && AlphaBetaTrace) {
  618. /* MR14 */       fatal("Can't specify both -aa (ambiguity aid) and -alpha ("(alpha)? beta" aid)");
  619. /* MR14 */    }
  620.     if (MRhoistingk) {              /* MR13 */
  621.       HoistPredicateContext=1;      /* MR13 */
  622.       MRhoisting=1;                 /* MR13 */
  623.     };                              /* MR13 */
  624.     if (MRhoisting && ! HoistPredicateContext) {
  625. /***      warnNoFL("Using "-mrhoist" forces "-prc on"");    ***/
  626.       HoistPredicateContext=1;
  627.     };
  628.     if (HoistPredicateContext && ! MRhoisting) {
  629.         warnNoFL("When using predicate context (-prc on) -mrhoist on is recommended");
  630.     }
  631. /* Fix lookahead depth */
  632. /* Compressed lookahead must always be larger than or equal to full lookahead */
  633. if ( CLL_k < LL_k  && CLL_k>0 )
  634. {
  635. warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
  636. CLL_k = LL_k;
  637. }
  638. if ( CLL_k == -1 ) CLL_k = LL_k;
  639. OutputLL_k = CLL_k;
  640. if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
  641. int n;
  642. for(n=1; n<CLL_k; n<<=1) {;}
  643. OutputLL_k = n;
  644. };
  645.     if ( ! ambAidDepthSpecified) {
  646.       MR_AmbAidDepth=1;
  647.     } else {
  648.       if (MR_AmbAidDepth > CLL_k || MR_AmbAidDepth <= 0) {
  649.         warnNoFL(eMsgd(
  650.             "Ambiguity aid depth ("-aad ...") must be a number between 1 and max(k,ck)=%d",CLL_k));
  651.         MR_AmbAidDepth=1;
  652.       };
  653.       if (MR_AmbAidDepth == 0) {
  654.         MR_AmbAidDepth=2;
  655.       };
  656.     };
  657.     if (MR_AmbAidRule != NULL) MR_AmbAidLine=atoi(MR_AmbAidRule);
  658. fpTrans = &(C_Trans[0]); /* Translate to C Language */
  659. fpJTrans = &(C_JTrans[0]);
  660. init();
  661. lexclass(LexStartSymbol);
  662. readDescr();
  663. LastTokenCounted = TokenNum;
  664. RemapForcedTokens();
  665. if ( CannotContinue ) {cleanUp(); zzDIE;}
  666. if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
  667. if ( WarningLevel>1 && HdrAction == NULL )
  668.    warnNoFL("no #header action was found");
  669. if ( FoundAtOperator && ! FoundExceptionGroup) {
  670.    warnNoFL("found the exception operator '@' - but no exception group was found");
  671. };
  672. EpToken = addTname(EPSTR); /* add imaginary token epsilon */
  673. set_orel(EpToken, &imag_tokens);
  674. /* this won't work for hand-built scanners since EofToken is not
  675.  * known.  Forces EOF to be token type 1.
  676.  */
  677. set_orel(EofToken, &imag_tokens);
  678. set_size(NumWords(TokenNum-1));
  679. /* compute the set of all known token types
  680.  * It represents the set of tokens from 1 to last_token_num + the
  681.  * reserved positions above that (if any).  Don't include the set of
  682.  * imaginary tokens such as the token/error classes or EOF.
  683.  */
  684. {
  685. set a;
  686. a = set_dup(reserved_positions);
  687. for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
  688. all_tokens = set_dif(a, imag_tokens);
  689. set_free(a);
  690. }
  691. ComputeTokSets(); /* Compute #tokclass sets */
  692. CompleteTokenSetRefs(); /* Change complex nodes in syn diag */
  693.     CompleteContextGuards();        /* MR13 */
  694. if ( CodeGen ) genDefFile(); /* create tokens.h */
  695. if ( LexGen ) genLexDescr(); /* create parser.dlg */
  696. if ( GenStdPccts )
  697. {
  698. FILE *f = fopen(OutMetaName(stdpccts), "w");
  699. if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
  700. else
  701. {
  702. #ifdef SPECIAL_FOPEN
  703. special_fopen_actions(OutMetaName(stdpccts));            /* MR1 */
  704. #endif
  705.             if (strcmp(stdpccts,"stdpccts.h") == 0) {                /* MR10 */
  706.            genStdPCCTSIncludeFile(f,NULL);                        /* MR10 */
  707.             } else {                                                 /* MR10 */
  708.            genStdPCCTSIncludeFile(f,baseName(stdpccts));          /* MR10 */
  709.             };
  710. fclose(f);
  711. }
  712. }
  713. buildRulePtr(); /* create mapping from rule # to RuleBlk junction */
  714. ComputeErrorSets();
  715. FoLink( (Node *)SynDiag ); /* add follow links to end of all rules */
  716. if ( GenCR ) GenCrossRef( SynDiag );
  717. if ( CodeGen )
  718. {
  719. if ( SynDiag == NULL )
  720. {
  721. warnNoFL("no grammar description recognized");
  722. cleanUp();
  723. zzDIE;
  724. }
  725. else if ( !GenCC ) {
  726. ErrFile = fopen(OutMetaName(ErrFileName), "w");
  727. require(ErrFile != NULL, "main: can't open err file");
  728. #ifdef SPECIAL_FOPEN
  729.               special_fopen_actions(OutMetaName(ErrFileName));   /* MR1 */
  730. #endif
  731. NewSetWd();
  732. GenErrHdr();
  733. TRANS(SynDiag); /* Translate to the target language */
  734. DumpSetWd();
  735. DumpRemainingTokSets();
  736. fclose( ErrFile );
  737. }
  738. else {
  739. strcpy(Parser_h_Name, CurrentClassName);
  740. strcat(Parser_h_Name, ".h");
  741. strcpy(Parser_c_Name, CurrentClassName);
  742. strcat(Parser_c_Name, CPP_FILE_SUFFIX);
  743. ensure_no_C_file_collisions(Parser_c_Name);
  744. Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
  745. require(Parser_h != NULL, "main: can't open class Parserx.h file");
  746. #ifdef SPECIAL_FOPEN
  747.     special_fopen_actions(OutMetaName(Parser_h_Name));       /* MR1 */
  748. #endif
  749. Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
  750. require(Parser_c != NULL, "main: can't open class Parserx.c file");
  751. #ifdef SPECIAL_FOPEN
  752.     special_fopen_actions(OutMetaName(Parser_c_Name));       /* MR1 */
  753. #endif
  754. GenParser_h_Hdr();
  755. if ( class_before_actions != NULL )
  756. {
  757. ListNode *p;
  758. for (p = class_before_actions->next; p!=NULL; p=p->next)
  759. {
  760. UserAction *ua = (UserAction *)p->elem;
  761. dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
  762. }
  763. }
  764. GenParser_c_Hdr();
  765. NewSetWd();
  766. TRANS(SynDiag); /* Translate to the target language */
  767. DumpSetWd();
  768. GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
  769. if ( class_after_actions != NULL )
  770. {
  771. ListNode *p;
  772. for (p = class_after_actions->next; p!=NULL; p=p->next)
  773. {
  774. UserAction *ua = (UserAction *)p->elem;
  775. dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
  776. }
  777. }
  778. DumpRemainingTokSets();
  779. fprintf(Parser_h, "};n");
  780. fprintf(Parser_h, "n#endif /* %s_h */n", CurrentClassName);
  781. fclose( Parser_h );
  782. fclose( Parser_c );
  783. }
  784. }
  785.     MR_orphanRules(stderr);
  786. if ( PrintOut )
  787. {
  788. if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
  789. else PRINT(SynDiag);
  790. }
  791. #ifdef DBG_LL1
  792. #endif
  793. GenRemapFile(); /* create remap.h */
  794. /* MR10 */    if (FoundGuessBlk) {
  795. #ifdef __cplusplus__
  796. /* MR10 */      list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);
  797. #else
  798. #ifdef __STDC__
  799. /* MR10 */      list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);
  800. #else
  801. /* MR10 */      list_apply(NumericPredLabels,report_numericPredLabels);
  802. #endif
  803. #endif
  804. /* MR10 */    };
  805.     if (InfoT && TnodesAllocated > 0) {
  806.       if (TnodesPeak > 10000) {
  807.         fprintf(stdout,"nTree Nodes:  peak %dk  created %dk  lost %dn",
  808.                         (TnodesPeak/1000),
  809.                         (TnodesAllocated/1000),
  810.                         TnodesInUse-tnodes_used_in_guard_predicates_etc);
  811.        } else {
  812.          fprintf(stdout,"nTree Nodes:  peak %d  created %d  lost %dn",
  813.                         TnodesPeak,
  814.                         TnodesAllocated,
  815.                         TnodesInUse-tnodes_used_in_guard_predicates_etc);
  816.        };
  817.     };
  818.     if (InfoF) {
  819.       DumpFcache();
  820.     };
  821.     if (MR_skipped_e3_report) {
  822.       fprintf(stderr,"note: use -e3 to get exact information on ambiguous tuplesn");
  823.     };
  824.     if (MR_BadExprSets != 0) {
  825.       fprintf(stderr,"note: Unreachable C or C++ code was generated for empty expression sets,n");
  826.       fprintf(stderr,"        probably due to undefined rules or infinite left recursion.n");
  827.       fprintf(stderr,"      To locate: search the generated code for "empty set expression"n");
  828.     };
  829.     if (MR_AmbAidRule != NULL && MR_matched_AmbAidRule==0) {
  830.       RuleEntry *q = (RuleEntry *) hash_get(Rname,MR_AmbAidRule);
  831.       if (MR_AmbAidLine == 0 && q == NULL) {
  832.          warnNoFL(eMsg2("there is no rule "%s" so "-aa %s" will never match",
  833.                                                         MR_AmbAidRule,MR_AmbAidRule));
  834.       } else {
  835.         warnNoFL(eMsg1("there was no ambiguity that matched "-aa %s"",MR_AmbAidRule));
  836.       };
  837.     };
  838.     if (AlphaBetaTrace) {
  839.       if (MR_AlphaBetaMessageCount == 0) {
  840.          fprintf(stderr,"note: there were no messages about "(alpha)? beta" blocks added to the generated coden");
  841.       } else {
  842.          fprintf(stderr,"note: there were %d messages about "(alpha)? beta" blocks added to the generated coden",
  843.                     MR_AlphaBetaMessageCount);
  844.       }
  845.       if (set_null(MR_CompromisedRules)) {
  846.          fprintf(stderr,"note: the list of rules with compromised follow sets is emptyn");
  847.       } else {
  848.          fprintf(stderr,"note: the following is a list of rules which *may* have incorrectn");
  849.          fprintf(stderr,"      follow sets computed as a result of an "(alpha)? beta" blockn");
  850.          fprintf(stderr,"n");
  851.          MR_dumpRuleSet(MR_CompromisedRules);
  852.          fprintf(stderr,"n");
  853.       }
  854.     }
  855. cleanUp();
  856. exit(PCCTS_EXIT_SUCCESS);
  857.     return 0;           /* MR11 make compilers happy */
  858. }
  859. static void
  860. #ifdef __STDC__
  861. init( void )
  862. #else
  863. init( )
  864. #endif
  865. {
  866. SignalEntry *q;
  867. Tname = newHashTable();
  868. Rname = newHashTable();
  869. Fcache = newHashTable();
  870. Tcache = newHashTable();
  871. Sname = newHashTable();
  872.     Pname = newHashTable();     /* MR11 */
  873. /* Add default signal names */
  874. q = (SignalEntry *)hash_add(Sname,
  875.   "NoViableAlt",
  876.   (Entry *)newSignalEntry("NoViableAlt"));
  877. require(q!=NULL, "cannot alloc signal entry");
  878. q->signum = sigNoViableAlt;
  879. q = (SignalEntry *)hash_add(Sname,
  880.   "MismatchedToken",
  881.   (Entry *)newSignalEntry("MismatchedToken"));
  882. require(q!=NULL, "cannot alloc signal entry");
  883. q->signum = sigMismatchedToken;
  884. q = (SignalEntry *)hash_add(Sname,
  885.   "NoSemViableAlt",
  886.   (Entry *)newSignalEntry("NoSemViableAlt"));
  887. require(q!=NULL, "cannot alloc signal entry");
  888. q->signum = sigNoSemViableAlt;
  889. reserved_positions = empty;
  890. all_tokens = empty;
  891. imag_tokens = empty;
  892. tokclasses = empty;
  893. TokenStr = (char **) calloc(TSChunk, sizeof(char *));
  894. require(TokenStr!=NULL, "main: cannot allocate TokenStr");
  895. FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
  896. require(FoStack!=NULL, "main: cannot allocate FoStack");
  897. FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
  898. require(FoTOS!=NULL, "main: cannot allocate FoTOS");
  899. Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
  900. require(Cycles!=NULL, "main: cannot allocate Cycles List");
  901.     MR_CompromisedRules=empty;  /* MR14 */
  902. }
  903. static void
  904. #ifdef __STDC__
  905. help( void )
  906. #else
  907. help( )
  908. #endif
  909. {
  910. Opt *p = options;
  911. fprintf(stderr, "antlr [options] f1 f2 ... fnn");
  912. while ( *(p->option) != '*' )
  913. {
  914. fprintf(stderr, "    %-9s%s   %sn",
  915. p->option,
  916. (p->arg)?"___":"   ",
  917. p->descr);
  918. p++;
  919. }
  920. }
  921. /* The RulePtr array is filled in here.  RulePtr exists primarily
  922.  * so that sets of rules can be maintained for the FOLLOW caching
  923.  * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n
  924.  * to a pointer to its RuleBlk junction where n is the number of rules.
  925.  */
  926. static void
  927. #ifdef __STDC__
  928. buildRulePtr( void )
  929. #else
  930. buildRulePtr( )
  931. #endif
  932. {
  933. int r=1;
  934. Junction *p  = SynDiag;
  935. RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
  936. require(RulePtr!=NULL, "cannot allocate RulePtr array");
  937. while ( p!=NULL )
  938. {
  939. require(r<=NumRules, "too many rules???");
  940. RulePtr[r++] = p;
  941. p = (Junction *)p->p2;
  942. }
  943. }
  944. void
  945. #ifdef __STDC__
  946. dlgerror(const char *s)
  947. #else
  948. dlgerror(s)
  949. char *s;
  950. #endif
  951. {
  952. fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  953. fprintf(stderr, " lexical error: %s (text was '%s')n",
  954. ((s == NULL) ? "Lexical error" : s), zzlextext);
  955. }
  956. void
  957. #ifdef __STDC__
  958. readDescr( void )
  959. #else
  960. readDescr( )
  961. #endif
  962. {
  963. zzerr = dlgerror;
  964. input = NextFile();
  965. if ( input==NULL ) fatal("No grammar description found (exiting...)");
  966. ANTLR(grammar(), input);
  967.     tnodes_used_in_guard_predicates_etc=TnodesInUse;    /* MR10 */
  968. }
  969. FILE *
  970. #ifdef __STDC__
  971. NextFile( void )
  972. #else
  973. NextFile( )
  974. #endif
  975. {
  976. FILE *f;
  977. for (;;)
  978. {
  979. CurFile++;
  980. if ( CurFile >= NumFiles ) return(NULL);
  981. if ( ci_strequ(FileStr[CurFile],"stdin")) return stdin;
  982. f = fopen(FileStr[CurFile], "r");
  983. if ( f == NULL )
  984. {
  985. warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
  986. }
  987. else
  988. {
  989. return(f);
  990. }
  991. }
  992. }
  993. /*
  994.  * Return a string corresponding to the output file name associated
  995.  * with the input file name passed in.
  996.  *
  997.  * Observe the following rules:
  998.  *
  999.  * f.e --> f".c"
  1000.  * f --> f".c"
  1001.  * f. --> f".c"
  1002.  * f.e.g --> f.e".c"
  1003.  *
  1004.  * Where f,e,g are arbitrarily long sequences of characters in a file
  1005.  * name.
  1006.  *
  1007.  * In other words, if a ".x" appears on the end of a file name, make it
  1008.  * ".c".  If no ".x" appears, append ".c" to the end of the file name.
  1009.  *
  1010.  * C++ mode using .cpp not .c.
  1011.  *
  1012.  * Use malloc() for new string.
  1013.  */
  1014. char *
  1015. #ifdef __STDC__
  1016. outname( char *fs )
  1017. #else
  1018. outname( fs )
  1019. char *fs;
  1020. #endif
  1021. {
  1022.     if ( GenCC) {
  1023.       return outnameX(fs,CPP_FILE_SUFFIX);
  1024.     } else {
  1025.       return outnameX(fs,".c");
  1026.     };
  1027. }
  1028. char *
  1029. #ifdef __STDC__
  1030. outnameX( char *fs ,char *suffix)
  1031. #else
  1032. outnameX( fs , suffix )
  1033. char *fs;
  1034. char *suffix;
  1035. #endif
  1036. {
  1037. static char buf[MaxFileName+1];
  1038. char *p;
  1039. require(fs!=NULL&&*fs!='', "outname: NULL filename");
  1040. p = buf;
  1041. strcpy(buf, fs);
  1042. while ( *p != '' )  {p++;} /* Stop on '' */
  1043. while ( *p != '.' && p != buf ) {--p;} /* Find '.' */
  1044. if ( p != buf ) *p = ''; /* Found '.' */
  1045. require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");
  1046.     strcat(buf,suffix);
  1047. return( buf );
  1048. }
  1049. void
  1050. #ifdef __STDC__
  1051. fatalFL( char *err_, char *f, int l )
  1052. #else
  1053. fatalFL( err_, f, l )
  1054. char *err_;
  1055. char *f;
  1056. int l;
  1057. #endif
  1058. {
  1059. fprintf(stderr, ErrHdr, f, l);
  1060. fprintf(stderr, " %sn", err_);
  1061. cleanUp();
  1062. exit(PCCTS_EXIT_FAILURE);
  1063. }
  1064. void
  1065. #ifdef __STDC__
  1066. fatal_intern( char *err_, char *f, int l )
  1067. #else
  1068. fatal_intern( err_, f, l )
  1069. char *err_;
  1070. char *f;
  1071. int l;
  1072. #endif
  1073. {
  1074. fprintf(stderr, ErrHdr, f, l);
  1075. fprintf(stderr, " #$%%*&@# internal error: %sn", err_);
  1076. fprintf(stderr, ErrHdr, f, l);
  1077. fprintf(stderr, " [complain to nearest government officialn");
  1078. fprintf(stderr, ErrHdr, f, l);
  1079. fprintf(stderr, "  or send hate-mail to parrt@parr-research.com;n");
  1080. fprintf(stderr, ErrHdr, f, l);
  1081. fprintf(stderr, "  please pray to the ``bug'' gods that there is a trival fix.]n");
  1082. cleanUp();
  1083. exit(PCCTS_EXIT_FAILURE);
  1084. }
  1085. void
  1086. #ifdef __STDC__
  1087. cleanUp( void )
  1088. #else
  1089. cleanUp( )
  1090. #endif
  1091. {
  1092. if ( DefFile != NULL) fclose( DefFile );
  1093. }
  1094. /* sprintf up to 3 strings */
  1095. char *
  1096. #ifdef __STDC__
  1097. eMsg3( char *s, char *a1, char *a2, char *a3 )
  1098. #else
  1099. eMsg3( s, a1, a2, a3 )
  1100. char *s;
  1101. char *a1;
  1102. char *a2;
  1103. char *a3;
  1104. #endif
  1105. {
  1106. static char buf[250]; /* DANGEROUS as hell !!!!!! */
  1107. sprintf(buf, s, a1, a2, a3);
  1108. return( buf );
  1109. }
  1110. /* sprintf a decimal */
  1111. char *
  1112. #ifdef __STDC__
  1113. eMsgd( char *s, int d )
  1114. #else
  1115. eMsgd( s, d )
  1116. char *s;
  1117. int d;
  1118. #endif
  1119. {
  1120. static char buf[250]; /* DANGEROUS as hell !!!!!! */
  1121. sprintf(buf, s, d);
  1122. return( buf );
  1123. }
  1124. char *
  1125. #ifdef __STDC__
  1126. eMsgd2( char *s, int d1,int d2)
  1127. #else
  1128. eMsgd2( s, d1, d2 )
  1129. char *s;
  1130. int d1;
  1131. int d2;
  1132. #endif
  1133. {
  1134. static char buf[250]; /* DANGEROUS as hell !!!!!! */
  1135. sprintf(buf, s, d1, d2);
  1136. return( buf );
  1137. }
  1138. void
  1139. #ifdef __STDC__
  1140. s_fprT( FILE *f, set e )
  1141. #else
  1142. s_fprT( f, e )
  1143. FILE *f;
  1144. set e;
  1145. #endif
  1146. {
  1147. register unsigned *p;
  1148. unsigned *q;
  1149. if ( set_nil(e) ) return;
  1150. if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
  1151. fprintf(f, "{");
  1152. while ( *p != nil )
  1153. {
  1154. fprintf(f, " %s", TerminalString(*p));
  1155. p++;
  1156. }
  1157. fprintf(f, " }");
  1158. free((char *)q);
  1159. }
  1160. /* Return the token name or regular expression for a token number. */
  1161. char *
  1162. #ifdef __STDC__
  1163. TerminalString( int token )
  1164. #else
  1165. TerminalString( token )
  1166. int token;
  1167. #endif
  1168. {
  1169. int     j;
  1170.     static char    imag_name[20];
  1171. /* look in all lexclasses for the token */
  1172. if ( TokenString(token) != NULL ) return TokenString(token);
  1173. for (j=0; j<NumLexClasses; j++)
  1174. {
  1175. lexmode(j);
  1176. if ( ExprString(token) != NULL ) return ExprString(token);
  1177. }
  1178.     if (1) {
  1179.       sprintf(imag_name,"UnknownToken#%d",token);           /* MR13 */
  1180.       return imag_name;                                     /* MR13 */
  1181.     }
  1182. require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
  1183. return "invalid";
  1184. }
  1185.                     /* S i m p l e  I n t  S t a c k */
  1186. void
  1187. #ifdef __STDC__
  1188. pushint( int i )
  1189. #else
  1190. pushint( i )
  1191. int i;
  1192. #endif
  1193. {
  1194. require(isp>0, "pushint: stack overflow");
  1195. istack[--isp] = i;
  1196. }
  1197. int
  1198. #ifdef __STDC__
  1199. popint( void )
  1200. #else
  1201. popint( )
  1202. #endif
  1203. {
  1204. require(isp<MAX_INT_STACK, "popint: stack underflow");
  1205. return istack[isp++];
  1206. }
  1207. int
  1208. #ifdef __STDC__
  1209. istacksize( void )
  1210. #else
  1211. istacksize( )
  1212. #endif
  1213. {
  1214. return MAX_INT_STACK-isp;
  1215. }
  1216. void
  1217. #ifdef __STDC__
  1218. istackreset( void )
  1219. #else
  1220. istackreset( )
  1221. #endif
  1222. {
  1223. isp = MAX_INT_STACK;
  1224. }
  1225. int
  1226. #ifdef __STDC__
  1227. istackempty( void )
  1228. #else
  1229. istackempty( )
  1230. #endif
  1231. {
  1232. return isp==MAX_INT_STACK;
  1233. }
  1234. int
  1235. #ifdef __STDC__
  1236. topint( void )
  1237. #else
  1238. topint( )
  1239. #endif
  1240. {
  1241. require(isp<MAX_INT_STACK, "topint: stack underflow");
  1242. return istack[isp];
  1243. }
  1244. void
  1245. #ifdef __STDC__
  1246. ProcessArgs( int argc, char **argv, Opt *options )
  1247. #else
  1248. ProcessArgs( argc, argv, options )
  1249. int argc;
  1250. char **argv;
  1251. Opt *options;
  1252. #endif
  1253. {
  1254. Opt *p;
  1255. require(argv!=NULL, "ProcessArgs: command line NULL");
  1256. while ( argc-- > 0 )
  1257. {
  1258. p = options;
  1259. while ( p->option != NULL )
  1260. {
  1261. if ( strcmp(p->option, "*") == 0 ||
  1262.  ci_strequ(p->option, *argv) == 1 )
  1263. {
  1264. if ( p->arg )
  1265. {
  1266. /* MR9  26-Sep-97   Check for argv valid                */
  1267.                     if (argc-- > 0) {
  1268.          (*p->process)( *argv, *(argv+1) );
  1269.     argv++;
  1270.                     } else {
  1271. fprintf(stderr,"error: required argument for option %s omittedn",*argv);
  1272. exit(PCCTS_EXIT_FAILURE);
  1273.                     };
  1274. }
  1275. else
  1276. (*p->process)( *argv );
  1277. break;
  1278. }
  1279. p++;
  1280. }
  1281. argv++;
  1282. }
  1283. }
  1284. static void CompleteContextGuards()
  1285. {
  1286.     ListNode *      p;
  1287.     Predicate *     pred;
  1288.     if (ContextGuardPredicateList == NULL) return;
  1289.     for (p=ContextGuardPredicateList->next; p != NULL; p=p->next) {
  1290.       pred=(Predicate *)p->elem;
  1291.       recomputeContextGuard(pred);
  1292.     }
  1293. }
  1294. /* Go back into the syntax diagram and compute all meta tokens; i.e.
  1295.  * turn all '.', ranges, token class refs etc... into actual token sets
  1296.  */
  1297. static void
  1298. CompleteTokenSetRefs()
  1299. {
  1300. ListNode *p;
  1301. if ( MetaTokenNodes==NULL ) return;
  1302. for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
  1303. {
  1304. set a,b;
  1305. TokNode *q = (TokNode *)p->elem;
  1306. if ( q->wild_card )
  1307. {
  1308. q->tset = all_tokens;
  1309. }
  1310. else if ( q->tclass!=NULL )
  1311. {
  1312. if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
  1313. else q->tset = q->tclass->tset;
  1314. }
  1315. else if ( q->upper_range!=0 )
  1316. {
  1317. /* we have a range on our hands: make a set from q->token .. q->upper_range */
  1318. int i;
  1319. a = empty;
  1320. for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); }   /* MR13 */
  1321. /* MR13 */    if (q->complement) {
  1322. /* MR13 */      q->tset = set_dif(all_tokens, a);
  1323. /* MR13 */        set_free(a);
  1324. /* MR13 */      } else {
  1325. /* MR13 */       q->tset = a;
  1326. /* MR13 */      }
  1327.         }
  1328. /* at this point, it can only be a complemented single token */
  1329. else if ( q->complement )
  1330. {
  1331. a = set_of(q->token);
  1332. b = set_dif(all_tokens, a);
  1333. set_free(a);
  1334. q->tset=b;
  1335. }
  1336. else fatal("invalid meta token");
  1337. }
  1338. }
  1339. /* MR10: Jeff Vincent
  1340.    MR10: Changed to remove directory information from n only if
  1341.    MR10: if OutputDirectory was changed by user (-o option)
  1342. */
  1343. char *
  1344. #ifdef __USE_PROTOS
  1345. OutMetaName(char *n)
  1346. #else
  1347. OutMetaName(n)
  1348. char *n;
  1349. #endif
  1350. {
  1351.     static char *dir_sym = DirectorySymbol;
  1352.     static char newname[MaxFileName+1];
  1353.     char *p;
  1354. /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */
  1355.     if (strcmp(OutputDirectory, TopDirectory) == 0)
  1356. return n;
  1357. /* p will point to filename without path information */
  1358. if ((p = strrchr(n, *dir_sym)) != NULL)
  1359. p++;
  1360. else
  1361. p = n;
  1362. /* Copy new output directory into newname[] */
  1363. strcpy(newname, OutputDirectory);
  1364. /* if new output directory does not have trailing dir_sym, add it! */
  1365. if (newname[strlen(newname)-1] != *dir_sym)
  1366. strcat(newname, dir_sym);
  1367. /* contatenate FILE NAME ONLY to new output directory */
  1368. strcat(newname, p);
  1369. return newname;
  1370. }
  1371. char *
  1372. #ifdef __STDC__
  1373. baseName(char *n)
  1374. #else
  1375. baseName(n)
  1376. char *n;
  1377. #endif
  1378. {
  1379.     static char newname[MaxFileName+1];
  1380.     static char* dir_sym = DirectorySymbol;
  1381.     int count = 0;
  1382.     char *p;
  1383.     p = n;
  1384.     while ( *p != '' )  {p++;}                    /* go to end of string */
  1385.     while ( (*p != *dir_sym) && (p != n) ) {--p;}   /* Find last DirectorySymbol */
  1386.     while ( *p == *dir_sym) p++;                    /* step forward if we're on a dir symbol */
  1387.     while ( *p != '' && *p != '.')
  1388.     {
  1389.         newname[count++] = *p;
  1390.         p++;
  1391.     }                                               /* create a new name */
  1392.     newname[count] = '';
  1393.     return newname;
  1394. }
  1395. static void
  1396. #ifdef __STDC__
  1397. ensure_no_C_file_collisions(char *class_c_file)
  1398. #else
  1399. ensure_no_C_file_collisions(class_c_file)
  1400. char *class_c_file;
  1401. #endif
  1402. {
  1403. int i;
  1404. for (i=0; i<NumFiles; i++)
  1405. {
  1406. #ifdef PC
  1407. /* assume that file names are case insensitive */
  1408. if ( stricmp(outname(FileStr[i]), class_c_file)==0 )
  1409. #else
  1410. if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
  1411. #endif
  1412. {
  1413. fatal(eMsg1("class def output file conflicts with parser output file: %s",
  1414. outname(FileStr[i])));
  1415. }
  1416. }
  1417. }
  1418. void
  1419. #ifdef __STDC__
  1420. warnNoFL(char *err)
  1421. #else
  1422. warnNoFL(err)
  1423. char *err;
  1424. #endif
  1425. {
  1426. fprintf(stderr, "warning: %sn", err);
  1427. }
  1428. void
  1429. #ifdef __STDC__
  1430. warnFL(char *err,char *f,int l)
  1431. #else
  1432. warnFL(err,f,l)
  1433. char *f;
  1434. int l;
  1435. char *err;
  1436. #endif
  1437. {
  1438. fprintf(stderr, ErrHdr, f, l);
  1439. fprintf(stderr, " warning: %sn", err);
  1440. }
  1441. void
  1442. #ifdef __STDC__
  1443. warn(char *err)
  1444. #else
  1445. warn(err)
  1446. char *err;
  1447. #endif
  1448. {
  1449. /* back up the file number if we hit an error at the end of the last file */
  1450. if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1451. fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1452. fprintf(stderr, " warning: %sn", err);
  1453. }
  1454. void
  1455. #ifdef __STDC__
  1456. warnNoCR( char *err )
  1457. #else
  1458. warnNoCR( err )
  1459. char *err;
  1460. #endif
  1461. {
  1462. /* back up the file number if we hit an error at the end of the last file */
  1463. if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1464. fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1465. fprintf(stderr, " warning: %s", err);
  1466. }
  1467. void
  1468. #ifdef __STDC__
  1469. errNoFL(char *err)
  1470. #else
  1471. errNoFL(err)
  1472. char *err;
  1473. #endif
  1474. {
  1475. fprintf(stderr, "error: %sn", err);
  1476. }
  1477. void
  1478. #ifdef __STDC__
  1479. errFL(char *err,char *f,int l)
  1480. #else
  1481. errFL(err,f,l)
  1482. char *err;
  1483. char *f;
  1484. int l;
  1485. #endif
  1486. {
  1487. fprintf(stderr, ErrHdr, f, l);
  1488. fprintf(stderr, " error: %sn", err);
  1489. }
  1490. void
  1491. #ifdef __STDC__
  1492. err(char *err)
  1493. #else
  1494. err(err)
  1495. char *err;
  1496. #endif
  1497. {
  1498. /* back up the file number if we hit an error at the end of the last file */
  1499. if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1500. fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1501. fprintf(stderr, " error: %sn", err);
  1502. }
  1503. void
  1504. #ifdef __STDC__
  1505. errNoCR( char *err )
  1506. #else
  1507. errNoCR( err )
  1508. char *err;
  1509. #endif
  1510. {
  1511. /* back up the file number if we hit an error at the end of the last file */
  1512. if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
  1513. fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
  1514. fprintf(stderr, " error: %s", err);
  1515. }
  1516. UserAction *
  1517. #ifdef __STDC__
  1518. newUserAction(char *s)
  1519. #else
  1520. newUserAction(s)
  1521. char *s;
  1522. #endif
  1523. {
  1524. UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
  1525. require(ua!=NULL, "cannot allocate UserAction");
  1526. ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
  1527. strcpy(ua->action, s);
  1528. return ua;
  1529. }
  1530. /* Added by TJP September 1994 */
  1531. /* Take in file.h and return file_h; names w/o '.'s are left alone */
  1532. char *
  1533. #ifdef __USE_PROTOS
  1534. gate_symbol(char *name)
  1535. #else
  1536. gate_symbol(name)
  1537. char *name;
  1538. #endif
  1539. {
  1540. static char buf[100];
  1541. char *p;
  1542. sprintf(buf, "%s", name);
  1543. for (p=buf; *p!=''; p++)
  1544. {
  1545. if ( *p=='.' ) *p = '_';
  1546. }
  1547. return buf;
  1548. }
  1549. char *
  1550. #ifdef __USE_PROTOS
  1551. makeAltID(int blockid, int altnum)
  1552. #else
  1553. makeAltID(blockid, altnum)
  1554. int blockid;
  1555. int altnum;
  1556. #endif
  1557. {
  1558. static char buf[100];
  1559. char *p;
  1560. sprintf(buf, "_blk%d_alt%d", blockid, altnum);
  1561. p = (char *)malloc(strlen(buf)+1);
  1562. strcpy(p, buf);
  1563. return p;
  1564. }