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