home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pccts1.zip / ANTLR / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-09-02  |  21KB  |  798 lines

  1. /*
  2.  * main.c -- main program for PCCTS ANTLR.
  3.  *
  4.  * $Id: main.c,v 1.12 1993/08/24 14:44:32 pccts Exp pccts $
  5.  * $Revision: 1.12 $
  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.10
  28.  * Terence Parr
  29.  * Purdue University
  30.  * 1989-1993
  31.  */
  32.  
  33. #include <stdio.h>
  34. #ifdef __cplusplus
  35. #ifndef __STDC__
  36. #define __STDC__
  37. #endif
  38. #endif
  39. #include "stdpccts.h"
  40.  
  41. #ifdef VAXC
  42. #define DIE        return 0;
  43. #else
  44. #define DIE        return 1;
  45. #endif
  46.  
  47. #define MAX_INT_STACK 50
  48. static int istack[MAX_INT_STACK];        /* Int stack */
  49. static int isp = MAX_INT_STACK;
  50.  
  51. static int DontAcceptFiles = 0;            /* if stdin, don't read files */
  52. static int DontAcceptStdin = 0;            /* if files seen first, don't accept stdin */
  53.  
  54.         /* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */
  55.  
  56. typedef struct _Opt {
  57.             char *option;
  58.             int  arg;
  59. #ifdef __cplusplus
  60.             void (*process)(...);
  61. #else
  62.             void (*process)();
  63. #endif
  64.             char *descr;
  65.         } Opt;
  66.  
  67. #ifdef __STDC__
  68. extern void ProcessArgs(int, char **, Opt *);
  69. #else
  70. extern void ProcessArgs();
  71. #endif
  72.  
  73. static void
  74. #ifdef __STDC__
  75. pStdin( void )
  76. #else
  77. pStdin( )
  78. #endif
  79. {
  80.     if ( DontAcceptStdin )
  81.     {
  82.         warnNoFL("'-' (stdin) ignored as files were specified first");
  83.         return;
  84.     }
  85.  
  86.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  87.     FileStr[NumFiles++] = "stdin";
  88.     DontAcceptFiles = 1;
  89. }
  90.  
  91. static void
  92. #ifdef __STDC__
  93. pFile( char *s )
  94. #else
  95. pFile( s )
  96. char *s;
  97. #endif
  98. {
  99.     if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
  100.     if ( DontAcceptFiles )
  101.     {
  102.         warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
  103.         return;
  104.     }
  105.  
  106.     require(NumFiles<MaxNumFiles,"exceeded max # of input files");
  107.     FileStr[NumFiles++] = s;
  108.     DontAcceptStdin = 1;
  109. }
  110.  
  111. static void
  112. #ifdef __STDC__
  113. pLLK( char *s, char *t )
  114. #else
  115. pLLK( s, t )
  116. char *s;
  117. char *t;
  118. #endif
  119. {
  120.     LL_k = atoi(t);
  121.     if ( LL_k <= 0 ) {
  122.         warnNoFL("must have at least one token of lookahead (setting to 1)");
  123.         LL_k = 1;
  124.     }
  125. }
  126.  
  127. static void
  128. #ifdef __STDC__
  129. pCk( char *s, char *t )
  130. #else
  131. pCk( s, t )
  132. char *s;
  133. char *t;
  134. #endif
  135. {
  136.     CLL_k = atoi(t);
  137.     if ( CLL_k <= 0 ) {
  138.         warnNoFL("must have at least one token of look-ahead (setting to 1)");
  139.         CLL_k = 1;
  140.     }
  141. }
  142.  
  143. #ifdef __STDC__
  144. static void pCGen(void)    { CodeGen = FALSE; LexGen = FALSE; }
  145. static void pLGen(void)    { LexGen = FALSE; }
  146. static void pTGen(void)    { TraceGen = TRUE; }
  147. static void pSGen(void)    { GenExprSets = FALSE; }
  148. static void pPrt(void)    { PrintOut = TRUE; pCGen(); pLGen(); }
  149. static void pPrtA(void)    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  150. static void pAst(void)    { GenAST = TRUE; }
  151. static void pANSI(void)    { GenANSI = TRUE; }
  152. static void pCr(void)    { GenCR = TRUE; }
  153. static void pLI(void)    { GenLineInfo = TRUE; }
  154. static void pFr(char *s, char *t) {RemapFileName = t;}
  155. static void pFe(char *s, char *t) {ErrFileName = t;}
  156. static void pFl(char *s, char *t) {DlgFileName = t;}
  157. static void pFm(char *s, char *t) {ModeFileName = t;}
  158. static void pFt(char *s, char *t) {DefFileName = t;}
  159. static void pE1(void)    { elevel = 1; }
  160. static void pE2(void)    { elevel = 2; }
  161. static void pE3(void)    { elevel = 3; }
  162. static void pEGen(void)    { GenEClasseForRules = 1; }
  163. static void pDL(void)    { DemandLookahead = 1; }
  164. static void pGHdr(void)    { GenStdPccts = 1; }
  165. static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
  166. static void pW1(void) { WarningLevel = 1; }
  167. static void pW2(void) { WarningLevel = 2; }
  168. static void pAI(void) { AImode = 1; }
  169. #else
  170. static void pCGen()    { CodeGen = FALSE; LexGen = FALSE; }
  171. static void pLGen()    { LexGen = FALSE; }
  172. static void pTGen()    { TraceGen = TRUE; }
  173. static void pSGen()    { GenExprSets = FALSE; }
  174. static void pPrt()        { PrintOut = TRUE; pCGen(); pLGen(); }
  175. static void pPrtA()    { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
  176. static void pAst()        { GenAST = TRUE; }
  177. static void pANSI()    { GenANSI = TRUE; }
  178. static void pCr()        { GenCR = TRUE; }
  179. static void pLI()        { GenLineInfo = TRUE; }
  180. static void pFr(s,t) char *s, *t; {RemapFileName = t;}
  181. static void pFe(s,t) char *s, *t; {ErrFileName = t;}
  182. static void pFl(s,t) char *s, *t; {DlgFileName = t;}
  183. static void pFm(s,t) char *s, *t; {ModeFileName = t;}
  184. static void pFt(s,t) char *s, *t; {DefFileName = t;}
  185. static void pE1()        { elevel = 1; }
  186. static void pE2()        { elevel = 2; }
  187. static void pE3()        { elevel = 3; }
  188. static void pEGen()    { GenEClasseForRules = 1; }
  189. static void pDL()        { DemandLookahead = 1; }
  190. static void pGHdr()    { GenStdPccts = 1; }
  191. static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
  192. static void pW1() { WarningLevel = 1; }
  193. static void pW2() { WarningLevel = 2; }
  194. static void pAI() { /* AImode = 1; -- not available yet*/ }
  195. #endif
  196.  
  197. static void
  198. #ifdef __STDC__
  199. pPre( char *s, char *t )
  200. #else
  201. pPre( s, t )
  202. char *s;
  203. char *t;
  204. #endif
  205. {
  206.     RulePrefix = t;
  207. }
  208.  
  209. static void
  210. #ifdef __STDC__
  211. pPred( void )
  212. #else
  213. pPred( )
  214. #endif
  215. {
  216.     warnNoFL("-pr is no longer used (predicates employed is present); see -prc");
  217. /*
  218.     if ( DemandLookahead )
  219.         warnNoFL("-gk conflicts with -pr; -gk turned off");
  220.     DemandLookahead = 0;
  221.     HoistPredicateContext = 0;
  222. */
  223. }
  224.  
  225. static void
  226. #ifdef __STDC__
  227. pPredCtx( char *s, char *t )
  228. #else
  229. pPredCtx(s,t)
  230. char *s;
  231. char *t;
  232. #endif
  233. {
  234.     if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
  235.     else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
  236.     else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
  237.     else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
  238.     if ( DemandLookahead )
  239.     {
  240.         warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
  241.         DemandLookahead = 0;
  242.     }
  243. }
  244.  
  245. static void
  246. #ifdef __STDC__
  247. pTRes( char *s, char *t )
  248. #else
  249. pTRes( s, t )
  250. char *s;
  251. char *t;
  252. #endif
  253. {
  254.     TreeResourceLimit = atoi(t);
  255.     if ( TreeResourceLimit <= 0 )
  256.     {
  257.         warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
  258.         TreeResourceLimit = -1; /* set to no limit */
  259.     }
  260. }
  261.  
  262. Opt options[] = {
  263. #ifdef __cplusplus
  264.     { "-ai", 0, (void (*)(...)) pAI,    "ANTLR interative mode (really cool, but not done yet)"},
  265.     { "-ck", 1, (void (*)(...)) pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  266.     { "-cr", 0, (void (*)(...)) pCr,    "Generate cross reference (default=FALSE)"},
  267.     { "-e1", 0, (void (*)(...)) pE1,    "Ambiguities/errors shown in low detail (default)"},
  268.     { "-e2", 0, (void (*)(...)) pE2,    "Ambiguities/errors shown in more detail"},
  269.     { "-e3", 0, (void (*)(...)) pE3,    "Ambiguities/errors shown in excruciating detail"},
  270.     { "-fe", 1, (void (*)(...)) pFe,    "Rename err.c"},
  271.     { "-fh", 1, (void (*)(...)) pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  272.     { "-fl", 1, (void (*)(...)) pFl,    "Rename lexical output--parser.dlg"},
  273.     { "-fm", 1, (void (*)(...)) pFm,    "Rename mode.h"},
  274.     { "-fr", 1, (void (*)(...)) pFr,    "Rename remap.h"},
  275.     { "-ft", 1, (void (*)(...)) pFt,    "Rename tokens.h"},
  276.     { "-ga", 0, (void (*)(...)) pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  277.     { "-gc", 0, (void (*)(...)) pCGen,    "Do not generate output parser code (default=FALSE)"},
  278.     { "-gd", 0, (void (*)(...)) pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  279.     { "-ge", 0, (void (*)(...)) pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  280.     { "-gh", 0, (void (*)(...)) pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  281.     { "-gk", 0, (void (*)(...)) pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  282.     { "-gl", 0, (void (*)(...)) pLI,    "Generate line info about grammar actions in C parser"},
  283.     { "-gp", 1, (void (*)(...)) pPre,    "Prefix all generated rule functions with a string"},
  284.     { "-gs", 0, (void (*)(...)) pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  285.     { "-gt", 0, (void (*)(...)) pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  286.     { "-gx", 0, (void (*)(...)) pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  287.     { "-k",  1, (void (*)(...)) pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  288.     { "-p",  0, (void (*)(...)) pPrt,    "Print out the grammar w/o actions (default=no)"},
  289.     { "-pa", 0, (void (*)(...)) pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  290.     { "-pr",0, (void (*)(...)) pPred,    "no longer used; predicates employed if present"},
  291.     { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  292.        { "-rl", 1, (void (*)(...)) pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  293.     { "-w1", 0, (void (*)(...)) pW1,    "Set the warning level to 1 (default)"},
  294.     { "-w2", 0, (void (*)(...)) pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  295.     { "-",   0, (void (*)(...)) pStdin,    "Read grammar from stdin" },
  296.     { "*",   0, (void (*)(...)) pFile,     "" },    /* anything else is a file */
  297. #else
  298.     { "-ai", 0, pAI,    "ANTLR interative mode (really cool, but not done yet)"},
  299.     { "-cr", 0, pCr,    "Generate cross reference (default=FALSE)"},
  300.     { "-ck", 1, pCk,    "Set compressed lookahead depth; fast approximate lookahead"},
  301.     { "-e1", 0, pE1,    "Ambiguities/errors shown in low detail (default)"},
  302.     { "-e2", 0, pE2,    "Ambiguities/errors shown in more detail"},
  303.     { "-e3", 0, pE3,    "Ambiguities/errors shown in excrutiating detail"},
  304.     { "-fe", 1, pFe,    "Rename err.c"},
  305.     { "-fh", 1, pFHdr,    "Rename stdpccts.h header (turns on -gh)"},
  306.     { "-fl", 1, pFl,    "Rename lexical output--parser.dlg"},
  307.     { "-fm", 1, pFm,    "Rename mode.h"},
  308.     { "-fr", 1, pFr,    "Rename remap.h"},
  309.     { "-ft", 1, pFt,    "Rename tokens.h"},
  310.     { "-ga", 0, pANSI,    "Generate ANSI-compatible code (default=FALSE)"},
  311.     { "-gc", 0, pCGen,    "Do not generate output parser code (default=FALSE)"},
  312.     { "-gd", 0, pTGen,    "Generate code to trace rule invocation (default=FALSE)"},
  313.     { "-ge", 0, pEGen,    "Generate an error class for each non-terminal (default=FALSE)"},
  314.     { "-gh", 0, pGHdr,    "Generate stdpccts.h for non-ANTLR-generated-files to include"},
  315.     { "-gk", 0, pDL,    "Generate parsers that delay lookahead fetches 'til needed"},
  316.     { "-gl", 0, pLI,    "Generate line info about grammar actions in C parser"},
  317.     { "-gp", 1, pPre,    "Prefix all generated rule functions with a string"},
  318.     { "-gs", 0, pSGen,    "Do not generate sets for token expression lists (default=FALSE)"},
  319.     { "-gt", 0, pAst,    "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
  320.     { "-gx", 0, pLGen,    "Do not generate lexical (dlg-related) files (default=FALSE)"},
  321.     { "-k",  1, pLLK,    "Set full LL(k) lookahead depth (default==1)"},
  322.     { "-p",  0, pPrt,    "Print out the grammar w/o actions (default=no)"},
  323.     { "-pa", 0, pPrtA,    "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
  324.     { "-pr",0, pPred,    "no longer used; predicates employed if present"},
  325.     { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
  326.        { "-rl", 1, pTRes,    "Limit max # of tree nodes used by grammar analysis"},
  327.     { "-w1", 0, pW1,    "Set the warning level to 1 (default)"},
  328.     { "-w2", 0, pW2,    "Ambiguities yield warnings even if predicates or (...)? block"},
  329.     { "-",   0, pStdin,    "Read grammar from stdin" },
  330.     { "*",   0, pFile,     "" },    /* anything else is a file */
  331. #endif
  332.     { NULL,  0, NULL }
  333. };
  334.  
  335. void readDescr();
  336. void cleanUp();
  337.  
  338. #ifdef __STDC__
  339. static void buildRulePtr( void );
  340. static void help( void );
  341. static void init( void );
  342. #else
  343. static void buildRulePtr( );
  344. static void help( );
  345. static void init( );
  346. #endif
  347.  
  348.                                 /* M a i n */
  349.  
  350. int
  351. #ifdef __STDC__
  352. main( int argc, char *argv[] )
  353. #else
  354. main( argc, argv )
  355. int argc;
  356. char *argv[];
  357. #endif
  358. {
  359.     static char EPSTR[] = "[Ep]";
  360.  
  361.     fprintf(stderr, "Antlr parser generator   Version %s   1989-1993\n", Version);
  362.     if ( argc == 1 ) { help(); DIE; }
  363.     ProcessArgs(argc-1, &(argv[1]), options);
  364.  
  365.     /* Fix lookahead depth */
  366.     /* Compressed lookahead must always be larger than or equal to full lookahead */
  367.     if ( CLL_k < LL_k  && CLL_k>0 )
  368.     {
  369.         warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
  370.         CLL_k = LL_k;
  371.     }
  372.     if ( CLL_k == -1 ) CLL_k = LL_k;
  373.     OutputLL_k = CLL_k;
  374.     if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
  375.         int n;
  376.         for(n=1; n<CLL_k; n<<=1) {;}
  377.         OutputLL_k = n;
  378.     }
  379.  
  380.     fpTrans = &(C_Trans[0]);        /* Translate to C Language */
  381.     fpJTrans = &(C_JTrans[0]);
  382.     init();
  383.     lexclass(LexStartSymbol);
  384.  
  385.     readDescr();
  386.     if ( CannotContinue ) {cleanUp(); DIE;}
  387.     if ( HdrAction == NULL ) warnNoFL("no #header action was found");
  388.  
  389.     EpToken = addTname(EPSTR);        /* add imaginary token epsilon */
  390.     set_size(NumWords(TokenNum-1));
  391.     
  392.     if ( CodeGen ) genDefFile();    /* create tokens.h */
  393.     if ( LexGen ) genLexDescr();    /* create parser.dlg */
  394.  
  395.     if ( GenStdPccts )
  396.     {
  397.         FILE *f = fopen(stdpccts, "w");
  398.         if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",stdpccts) );}
  399.         else
  400.         {
  401.             genStdPCCTSIncludeFile(f);
  402.             fclose(f);
  403.         }
  404.     }
  405.  
  406.     buildRulePtr();                    /* create mapping from rule # to RuleBlk junction */
  407.     ComputeErrorSets();
  408.     FoLink( (Node *)SynDiag );        /* add follow links to end of all rules */
  409.     if ( GenCR ) GenCrossRef( SynDiag );
  410.  
  411.     if ( CodeGen )
  412.     {
  413.         if ( SynDiag == NULL )
  414.         {
  415.             warnNoFL("no grammar description recognized");
  416.             cleanUp();
  417.             DIE;
  418.         }
  419.         else
  420.         {
  421.             ErrFile = fopen(ErrFileName, "w");
  422.             require(ErrFile != NULL, "main: can't open err file");
  423.             NewSetWd();
  424.             GenErrHdr();
  425.             TRANS(SynDiag);            /* Translate to the target language */
  426.             DumpSetWd();
  427.             fclose( ErrFile );
  428.         }
  429.     }
  430.  
  431.     if ( PrintOut )
  432.     {
  433.         if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
  434.         else PRINT(SynDiag);
  435.     }
  436.  
  437.     GenRemapFile();                    /* create remap.h */
  438.  
  439.     cleanUp();
  440. #ifdef VAXC
  441.     return 1;               /* report all is well for make etc... */
  442. #else
  443.     return 0;               /* report all is well for make etc... */
  444. #endif
  445. }
  446.  
  447. static void
  448. #ifdef __STDC__
  449. init( void )
  450. #else
  451. init( )
  452. #endif
  453. {
  454.     Tname = newHashTable();
  455.     Rname = newHashTable();
  456.     Fcache = newHashTable();
  457.     Tcache = newHashTable();
  458.     TokenStr = (char **) calloc(TSChunk, sizeof(char *));
  459.     require(TokenStr!=NULL, "main: cannot allocate TokenStr");
  460.     FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
  461.     require(FoStack!=NULL, "main: cannot allocate FoStack");
  462.     FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
  463.     require(FoTOS!=NULL, "main: cannot allocate FoTOS");
  464.     Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
  465.     require(Cycles!=NULL, "main: cannot allocate Cycles List");
  466. }
  467.  
  468. static void
  469. #ifdef __STDC__
  470. help( void )
  471. #else
  472. help( )
  473. #endif
  474. {
  475.     Opt *p = options;
  476.     fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
  477.     while ( *(p->option) != '*' )
  478.     {
  479.         fprintf(stderr, "\t%-4s %s   %s\n",
  480.                         p->option,
  481.                         (p->arg)?"___":"   ",
  482.                         p->descr);
  483.         p++;
  484.     }
  485. }
  486.  
  487. /* The RulePtr array is filled in here.  RulePtr exists primarily
  488.  * so that sets of rules can be maintained for the FOLLOW caching
  489.  * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n
  490.  * to a pointer to its RuleBlk junction where n is the number of rules.
  491.  */
  492. static void
  493. #ifdef __STDC__
  494. buildRulePtr( void )
  495. #else
  496. buildRulePtr( )
  497. #endif
  498. {
  499.     int r=1;
  500.     Junction *p  = SynDiag;
  501.     RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
  502.     require(RulePtr!=NULL, "cannot allocate RulePtr array");
  503.     
  504.     while ( p!=NULL )
  505.     {
  506.         require(r<=NumRules, "too many rules???");
  507.         RulePtr[r++] = p;
  508.         p = (Junction *)p->p2;
  509.     }
  510. }
  511.  
  512. void
  513. #ifdef __STDC__
  514. readDescr( void )
  515. #else
  516. readDescr( )
  517. #endif
  518. {
  519.     input = NextFile();
  520.     require(input!=NULL, "No grammar description found (exiting...)");
  521.     ANTLR(grammar(), input);
  522. }
  523.  
  524. FILE *
  525. #ifdef __STDC__
  526. NextFile( void )
  527. #else
  528. NextFile( )
  529. #endif
  530. {
  531.     FILE *f;
  532.  
  533.     for (;;)
  534.     {
  535.         CurFile++;
  536.         if ( CurFile >= NumFiles ) return(NULL);
  537.         if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
  538.         f = fopen(FileStr[CurFile], "r");
  539.         if ( f == NULL )
  540.         {
  541.             warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
  542.         }
  543.         else
  544.         {
  545.             return(f);
  546.         }
  547.     }
  548. }
  549.  
  550. /*
  551.  * Return a string corresponding to the output file name associated
  552.  * with the input file name passed in.
  553.  *
  554.  * Observe the following rules:
  555.  *
  556.  *        f.e        --> f".c"
  557.  *        f        --> f".c"
  558.  *        f.        --> f".c"
  559.  *        f.e.g    --> f.e".c"
  560.  *
  561.  * Where f,e,g are arbitrarily long sequences of characters in a file
  562.  * name.
  563.  *
  564.  * In other words, if a ".x" appears on the end of a file name, make it
  565.  * ".c".  If no ".x" appears, append ".c" to the end of the file name.
  566.  *
  567.  * Use malloc() for new string.
  568.  */
  569. char *
  570. #ifdef __STDC__
  571. outname( char *fs )
  572. #else
  573. outname( fs )
  574. char *fs;
  575. #endif
  576. {
  577.     static char buf[MaxFileName+1];
  578.     char *p;
  579.  
  580.     p = buf;
  581.     strcpy(buf, fs);
  582.     while ( *p != '\0' )  {p++;}            /* Stop on '\0' */
  583.     while ( *p != '.' && p != buf ) {--p;}    /* Find '.' */
  584.     if ( p != buf ) *p = '\0';                /* Found '.' */
  585.     require(strlen(buf) + 2 < MaxFileName, "outname: filename too big");
  586.     strcat(buf, ".c");
  587.     return( buf );
  588. }
  589.  
  590. void
  591. #ifdef __STDC__
  592. fatalFL( char *err_, char *f, int l )
  593. #else
  594. fatalFL( err_, f, l )
  595. char *err_;
  596. char *f;
  597. int l;
  598. #endif
  599. {
  600.     fprintf(stderr, ErrHdr, f, l);
  601.     fprintf(stderr, " %s\n", err_);
  602.     cleanUp();
  603.     exit(1);
  604. }
  605.  
  606. void
  607. #ifdef __STDC__
  608. cleanUp( void )
  609. #else
  610. cleanUp( )
  611. #endif
  612. {
  613.     if ( DefFile != NULL) fclose( DefFile );
  614. }
  615.  
  616. /* sprintf up to 3 strings */
  617. char *
  618. #ifdef __STDC__
  619. eMsg3( char *s, char *a1, char *a2, char *a3 )
  620. #else
  621. eMsg3( s, a1, a2, a3 )
  622. char *s;
  623. char *a1;
  624. char *a2;
  625. char *a3;
  626. #endif
  627. {
  628.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  629.     
  630.     sprintf(buf, s, a1, a2, a3);
  631.     return( buf );
  632. }
  633.  
  634. /* sprintf a decimal */
  635. char *
  636. #ifdef __STDC__
  637. eMsgd( char *s, int d )
  638. #else
  639. eMsgd( s, d )
  640. char *s;
  641. int d;
  642. #endif
  643. {
  644.     static char buf[250];            /* DANGEROUS as hell !!!!!! */
  645.     
  646.     sprintf(buf, s, d);
  647.     return( buf );
  648. }
  649.  
  650. void
  651. #ifdef __STDC__
  652. s_fprT( FILE *f, set e )
  653. #else
  654. s_fprT( f, e )
  655. FILE *f;
  656. set e;
  657. #endif
  658. {
  659.     register unsigned *p;
  660.     unsigned *q;
  661.  
  662.     if ( set_nil(e) ) return;
  663.     if ( (q=p=set_pdq(e)) == NULL ) fatal("Can't alloc space for set_pdq");
  664.     fprintf(f, "{");
  665.     while ( *p != nil )
  666.     {
  667.         fprintf(f, " %s", TerminalString(*p));
  668.         p++;
  669.     }
  670.     fprintf(f, " }");
  671.     free(q);
  672. }
  673.  
  674. /* Return the token name or regular expression for a token number. */
  675. char *
  676. #ifdef __STDC__
  677. TerminalString( int token )
  678. #else
  679. TerminalString( token )
  680. int token;
  681. #endif
  682. {
  683.     int j;
  684.  
  685.     /* look in all lexclasses for the token */
  686.     if ( TokenStr[token] != NULL ) return TokenStr[token];
  687.     for (j=0; j<NumLexClasses; j++)
  688.     {
  689.         lexmode(j);
  690.         if ( ExprStr[token] != NULL ) return ExprStr[token];
  691.     }
  692.     require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
  693.     return "invalid";
  694. }
  695.  
  696.                     /* S i m p l e  I n t  S t a c k */
  697.  
  698. void
  699. #ifdef __STDC__
  700. pushint( int i )
  701. #else
  702. pushint( i )
  703. int i;
  704. #endif
  705. {
  706.     require(isp>0, "pushint: stack overflow");
  707.     istack[--isp] = i;
  708. }
  709.  
  710. int
  711. #ifdef __STDC__
  712. popint( void )
  713. #else
  714. popint( )
  715. #endif
  716. {
  717.     require(isp<MAX_INT_STACK, "popint: stack underflow");
  718.     return istack[isp++];
  719. }
  720.  
  721. int
  722. #ifdef __STDC__
  723. istacksize( void )
  724. #else
  725. istacksize( )
  726. #endif
  727. {
  728.     return MAX_INT_STACK-isp;
  729. }
  730.  
  731. void
  732. #ifdef __STDC__
  733. istackreset( void )
  734. #else
  735. istackreset( )
  736. #endif
  737. {
  738.     isp = MAX_INT_STACK;
  739. }
  740.  
  741. int
  742. #ifdef __STDC__
  743. istackempty( void )
  744. #else
  745. istackempty( )
  746. #endif
  747. {
  748.     return isp==MAX_INT_STACK;
  749. }
  750.  
  751. int
  752. #ifdef __STDC__
  753. topint( void )
  754. #else
  755. topint( )
  756. #endif
  757. {
  758.     require(isp<MAX_INT_STACK, "topint: stack underflow");
  759.     return istack[isp];
  760. }
  761.  
  762. void
  763. #ifdef __STDC__
  764. ProcessArgs( int argc, char **argv, Opt *options )
  765. #else
  766. ProcessArgs( argc, argv, options )
  767. int argc;
  768. char **argv;
  769. Opt *options;
  770. #endif
  771. {
  772.     Opt *p;
  773.     require(argv!=NULL, "ProcessArgs: command line NULL");
  774.  
  775.     while ( argc-- > 0 )
  776.     {
  777.         p = options;
  778.         while ( p->option != NULL )
  779.         {
  780.             if ( strcmp(p->option, "*") == 0 ||
  781.                  strcmp(p->option, *argv) == 0 )
  782.             {
  783.                 if ( p->arg )
  784.                 {
  785.                     (*p->process)( *argv, *(argv+1) );
  786.                     argv++;
  787.                     argc--;
  788.                 }
  789.                 else
  790.                     (*p->process)( *argv );
  791.                 break;
  792.             }
  793.             p++;
  794.         }
  795.         argv++;
  796.     }
  797. }
  798.