1 /*
2  * lex.c	--	Generate all of the lexical type files: parser.dlg tokens.h
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-2001
29  */
30 
31 #include <stdio.h>
32 #include <ctype.h>
33 /* MR1						                                                */
34 /* MR1  10-Apr-97  MR1	Replace use of __STDC__ with __USE_PROTOS	    */
35 /* MR1				                                                        */
36 #include "pcctscfg.h"
37 #include "set.h"
38 #include "syn.h"
39 #include "hash.h"
40 #include "generic.h"
41 
42 #define DLGErrorString "invalid token"
43 
44 /* Generate a complete lexical description of the lexemes found in the grammar */
45 void
46 #ifdef __USE_PROTOS
genLexDescr(void)47 genLexDescr( void )
48 #else
49 genLexDescr( )
50 #endif
51 {
52 	ListNode *p;
53 	FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");
54 	require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );
55 #ifdef SPECIAL_FOPEN
56 	special_fopen_actions(OutMetaName(DlgFileName));	             /* MR1 */
57 #endif
58 	fprintf(dlgFile, "<<\n");
59 	fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName);
60 	fprintf(dlgFile, " *\n");
61 	fprintf(dlgFile, " * Generated from:");
62 	{int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}
63 	fprintf(dlgFile, "\n");
64 	fprintf(dlgFile, " *\n");
65 	fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
66 	fprintf(dlgFile, " * Purdue University Electrical Engineering\n");
67 	fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");
68 	fprintf(dlgFile, " * ANTLR Version %s\n", Version);
69 	fprintf(dlgFile, " */\n\n");
70     if (FirstAction != NULL ) dumpAction( FirstAction, dlgFile, 0, -1, 0, 1 );  /* MR11 MR15b */
71     fprintf(dlgFile, "#define ANTLR_VERSION	%s\n", VersionDef);
72 	if ( GenCC )
73 	{
74 		if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
75 		else fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
76 		fprintf(dlgFile, "#include \"%s\"\n", ATOKEN_H);
77 		if ( GenAST ) fprintf(dlgFile, "#include \"%s\"\n", ASTBASE_H);
78 		if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
79 	}
80 	else
81 	{
82 		fprintf(dlgFile, "#include \"pcctscfg.h\"\n");
83 		fprintf(dlgFile, "#include \"pccts_stdio.h\"\n");
84 		if ( strcmp(ParserName, DefaultParserName)!=0 )
85 			fprintf(dlgFile, "#define %s %s\n", DefaultParserName, ParserName);
86 		if ( strcmp(ParserName, DefaultParserName)!=0 )
87 			fprintf(dlgFile, "#include \"%s\"\n", RemapFileName);
88 		if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
89 		if ( FoundGuessBlk )
90 		{
91 			fprintf(dlgFile, "#define ZZCAN_GUESS\n");
92 			fprintf(dlgFile, "#include \"pccts_setjmp.h\"\n");
93 		}
94 		if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);
95 		if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");
96         if (TraceGen) {
97           fprintf(dlgFile,"#ifndef zzTRACE_RULES\n");  /* MR20 */
98           fprintf(dlgFile,"#define zzTRACE_RULES\n");  /* MR20 */
99           fprintf(dlgFile,"#endif\n");  /* MR22 */
100         };
101 		fprintf(dlgFile, "#include \"antlr.h\"\n");
102 		if ( GenAST ) {
103 			fprintf(dlgFile, "#include \"ast.h\"\n");
104 		}
105 		if ( UserDefdTokens )
106 			fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
107 		/* still need this one as it has the func prototypes */
108 		fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
109 		fprintf(dlgFile, "#include \"dlgdef.h\"\n");
110 		fprintf(dlgFile, "LOOKAHEAD\n");
111 		fprintf(dlgFile, "\n");
112 		fprintf(dlgFile, "void\n");
113 		fprintf(dlgFile, "#ifdef __USE_PROTOS\n");
114 		fprintf(dlgFile, "zzerraction(void)\n");
115 		fprintf(dlgFile, "#else\n");
116 		fprintf(dlgFile, "zzerraction()\n");
117 		fprintf(dlgFile, "#endif\n");
118 		fprintf(dlgFile, "{\n");
119 		fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);
120 		fprintf(dlgFile, "\tzzadvance();\n");
121 		fprintf(dlgFile, "\tzzskip();\n");
122 		fprintf(dlgFile, "}\n");
123 	}
124 	fprintf(dlgFile, ">>\n\n");
125 
126 	/* dump all actions */
127 
128 /* MR1									                                    */
129 /* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class     */
130 /* MR1	 	   	  via <<%%lexmember ....>> & <<%%lexprefix ...>>            */
131 /* MR1				                					    */
132           if (LexActions != NULL) {
133             for (p = LexActions->next; p!=NULL; p=p->next)
134 		{
135 /* MR1 */	fprintf(dlgFile, "<<%%%%lexaction\n");
136 			dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
137 			fprintf(dlgFile, ">>\n\n");
138 		}
139 	  };
140 
141 /* MR1 */ if (GenCC) {
142 /* MR1 */   fprintf(dlgFile,"<<%%%%parserclass %s>>\n\n",CurrentClassName);
143 /* MR1 */ };
144 
145 /* MR1 */ if (LexPrefixActions != NULL) {
146 /* MR1 */   for (p = LexPrefixActions->next; p!=NULL; p=p->next)
147 /* MR1 */       {
148 /* MR1 */               fprintf(dlgFile, "<<%%%%lexprefix\n");
149 /* MR1 */               dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
150 /* MR1 */               fprintf(dlgFile, ">>\n\n");
151 /* MR1 */       }
152 /* MR1 */ };
153 
154 /* MR1 */ if (LexMemberActions != NULL) {
155 /* MR1 */   for (p = LexMemberActions->next; p!=NULL; p=p->next)
156 /* MR1 */       {
157 /* MR1 */               fprintf(dlgFile, "<<%%%%lexmember\n");
158 /* MR1 */               dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
159 /* MR1 */               fprintf(dlgFile, ">>\n\n");
160 /* MR1 */       }
161 /* MR1 */ };
162 
163 	/* dump all regular expression rules/actions (skip sentinel node) */
164 	if ( ExprOrder == NULL ) {
165 		warnNoFL("no regular expressions found in grammar");
166 	}
167 	else dumpLexClasses(dlgFile);
168 	fprintf(dlgFile, "%%%%\n");
169 	fclose( dlgFile );
170 }
171 
172 /* For each lexical class, scan ExprOrder looking for expressions
173  * in that lexical class.  Print out only those that match.
174  * Each element of the ExprOrder list has both an expr and an lclass
175  * field.
176  */
177 void
178 #ifdef __USE_PROTOS
dumpLexClasses(FILE * dlgFile)179 dumpLexClasses( FILE *dlgFile )
180 #else
181 dumpLexClasses( dlgFile )
182 FILE *dlgFile;
183 #endif
184 {
185 	int i;
186 	TermEntry *t;
187 	ListNode *p;
188 	Expr *q;
189 
190 	for (i=0; i<NumLexClasses; i++)
191 	{
192 		fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);
193 		for (p=ExprOrder->next; p!=NULL; p=p->next)
194 		{
195 			q = (Expr *) p->elem;
196 			if ( q->lclass != i ) continue;
197 			lexmode(i);
198 			t = (TermEntry *) hash_get(Texpr, q->expr);
199 			require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
200 			if ( t->token == EpToken ) continue;
201 			fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));
202 			/* replace " killed by StripQuotes() */
203 			q->expr[ strlen(q->expr) ] = '"';
204 			if ( !GenCC ) {
205 				if ( TokenString(t->token) != NULL )
206 					fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));
207 				else
208 					fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);
209 			}
210 			if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
211 			if ( GenCC ) {
212 				if ( TokenString(t->token) != NULL )
213 					fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));
214 				else
215 					fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token);
216 			}
217 			fprintf(dlgFile, "\t>>\n\n");
218 		}
219 	}
220 }
221 
222 /* Strip the leading path (if any) from a filename */
223 char *
224 #ifdef __USE_PROTOS
StripPath(char * fileName)225 StripPath( char *fileName )
226 #else
227 StripPath( fileName )
228 char *fileName;
229 #endif
230 {
231 	char *p;
232 	static char dirSym[2] = DirectorySymbol;
233 
234 	if(NULL != (p = strrchr(fileName, dirSym[0])))
235 		p++;
236 	else
237 		p = fileName;
238 
239 	return(p);
240 }
241 
242 /* Generate a list of #defines && list of struct definitions for
243  * aggregate retv's */
244 void
245 #ifdef __USE_PROTOS
genDefFile(void)246 genDefFile( void )
247 #else
248 genDefFile( )
249 #endif
250 {
251 	int i;
252 
253 	/* If C++ mode and #tokdef used, then don't need anything in here since
254 	 * C++ puts all definitions in the class file name.
255 	 */
256 	if ( GenCC && UserTokenDefsFile ) return;
257     if ( MR_Inhibit_Tokens_h_Gen) return;
258 
259 	DefFile = fopen(OutMetaName(DefFileName), "w");
260 	require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
261 #ifdef SPECIAL_FOPEN
262 	special_fopen_actions(OutMetaName(DefFileName));	             /* MR1 */
263 #endif
264 	fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName)));
265 	fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName)));
266 
267 	fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);
268 	fprintf(DefFile, " *\n");
269 	fprintf(DefFile, " * Generated from:");
270 	for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
271 	fprintf(DefFile, "\n");
272 	fprintf(DefFile, " *\n");
273 	fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
274 	fprintf(DefFile, " * Purdue University Electrical Engineering\n");
275 	fprintf(DefFile, " * ANTLR Version %s\n", Version);
276 	fprintf(DefFile, " */\n");
277 
278 	if ( !GenCC && LexGen ) {
279 		fprintf(DefFile,"#define zzEOF_TOKEN %d\n",
280 				TokenInd!=NULL?TokenInd[EofToken]:EofToken);
281 	}
282 
283 	if ( !UserDefdTokens )
284 	{
285 		int first=1;
286 
287 		if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {\n");
288 		for (i=1; i<TokenNum; i++)
289 		{
290 			/* Don't do EpToken or expr w/o labels */
291 			if ( TokenString(i)!=NULL && i != EpToken )
292 			{
293 				TermEntry *p;
294 
295 				if ( WarningLevel>1 )
296 				{
297 					int j;
298 					/* look in all lexclasses for the reg expr */
299 
300 /* MR10  Derek Pappas                                                */
301 /* MR10     A #tokclass doesn't have associated regular expressiones */
302 /* MR10        so don't warn user about it's omission                */
303 
304                     p = (TermEntry *) hash_get(Tname, TokenString(i));
305 
306                     if (p != NULL && ! p->classname) {
307     					for (j=0; j<NumLexClasses; j++)
308     					{
309     						lexmode(j);
310     						if ( ExprString(i)!=NULL ) break;
311     					}
312     					if ( j>=NumLexClasses )
313     					{
314     						warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
315     					}
316                     };
317 				}
318 				require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
319 						"token not in sym tab when it should be");
320 				if ( !p->classname )
321 				{
322 					if ( GenCC ) {
323 						if ( !first ) fprintf(DefFile, ",\n");
324 						first = 0;
325 						fprintf(DefFile, "\t%s=%d", TokenString(i), i);
326 					}
327 					else
328 						fprintf(DefFile, "#define %s %d\n", TokenString(i), i);
329 				}
330 			}
331 		}
332 /* MR1									                                    */
333 /* MR1  10-Apr-97 133MR1	Prevent use of varying sizes of integer	    */
334 /* MR1				for the enum ANTLRTokenType                             */
335 /* MR1								           */
336 		if ( GenCC ) {				                                 /* MR1 */
337  		 	 if ( !first ) fprintf(DefFile, ",\n");                  /* MR14 */
338 		     fprintf(DefFile, "\tDLGminToken=0");                 /* MR1 */
339 		     fprintf(DefFile, ",\n\tDLGmaxToken=9999};\n");          /* MR1 */
340                 };						                             /* MR1 */
341 	}
342 
343 	if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
344 
345 	fprintf(DefFile, "\n#endif\n");
346 }
347 
348 void
349 #ifdef __USE_PROTOS
GenRemapFile(void)350 GenRemapFile( void )
351 #else
352 GenRemapFile( )
353 #endif
354 {
355 	if ( strcmp(ParserName, DefaultParserName)!=0 )
356 	{
357 		FILE *f;
358 		int i;
359 
360 		f = fopen(OutMetaName(RemapFileName), "w");
361 		require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
362 #ifdef SPECIAL_FOPEN
363 		special_fopen_actions(OutMetaName(RemapFileName));           /* MR1 */
364 #endif
365 		fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);
366 		fprintf(f, " *\n");
367 		fprintf(f, " * Generated from:");
368 		for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
369 		fprintf(f, "\n");
370 		fprintf(f, " *\n");
371 		fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
372 		fprintf(f, " * Purdue University Electrical Engineering\n");
373 		fprintf(f, " * ANTLR Version %s\n", Version);
374 		fprintf(f, " */\n");
375 
376 		GenRuleFuncRedefs(f, SynDiag);
377 		GenPredefinedSymbolRedefs(f);
378 		if ( GenAST ) GenASTSymbolRedefs(f);
379 		GenSetRedefs(f);
380 
381 		fclose(f);
382 	}
383 }
384 
385 /* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
386 void
387 #ifdef __USE_PROTOS
GenRuleFuncRedefs(FILE * f,Junction * p)388 GenRuleFuncRedefs( FILE *f, Junction *p )
389 #else
390 GenRuleFuncRedefs( f, p )
391 FILE *f;
392 Junction *p;
393 #endif
394 {
395 	fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");
396 	while ( p!=NULL )
397 	{
398 		fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);
399 		p = (Junction *)p->p2;
400 	}
401 }
402 
403 /* Generate a bunch of #defines that rename all standard symbols to be
404  * "ParserName_symbol".  The list of standard symbols to change is in
405  * globals.c.
406  */
407 void
408 #ifdef __USE_PROTOS
GenPredefinedSymbolRedefs(FILE * f)409 GenPredefinedSymbolRedefs( FILE *f )
410 #else
411 GenPredefinedSymbolRedefs( f )
412 FILE *f;
413 #endif
414 {
415 	char **p;
416 
417 	fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");
418 	for (p = &StandardSymbols[0]; *p!=NULL; p++)
419 	{
420 		fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
421 	}
422 }
423 
424 /* Generate a bunch of #defines that rename all AST symbols to be
425  * "ParserName_symbol".  The list of AST symbols to change is in
426  * globals.c.
427  */
428 void
429 #ifdef __USE_PROTOS
GenASTSymbolRedefs(FILE * f)430 GenASTSymbolRedefs( FILE *f )
431 #else
432 GenASTSymbolRedefs( f )
433 FILE *f;
434 #endif
435 {
436 	char **p;
437 
438 	fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");
439 	for (p = &ASTSymbols[0]; *p!=NULL; p++)
440 	{
441 		fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
442 	}
443 }
444 
445 /* redefine all sets generated by ANTLR; WARNING:  'zzerr', 'setwd' must match
446  * use in bits.c (DumpSetWd() etc...)
447  */
448 void
449 #ifdef __USE_PROTOS
GenSetRedefs(FILE * f)450 GenSetRedefs( FILE *f )
451 #else
452 GenSetRedefs( f )
453 FILE *f;
454 #endif
455 {
456 	int i;
457 
458 	for (i=1; i<=wordnum; i++)
459 	{
460 		fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);
461 	}
462 	for (i=1; i<=esetnum; i++)
463 	{
464 		fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);
465 	}
466 }
467 
468 /* Find all return types/parameters that require structs and def
469  * all rules with ret types.
470  *
471  * This is for the declaration, not the definition.
472  */
473 void
474 #ifdef __USE_PROTOS
GenRulePrototypes(FILE * f,Junction * p)475 GenRulePrototypes( FILE *f, Junction *p )
476 #else
477 GenRulePrototypes( f, p )
478 FILE *f;
479 Junction *p;
480 #endif
481 {
482 	int i;
483 
484 	i = 1;
485 	while ( p!=NULL )
486 	{
487 		if ( p->ret != NULL )
488 		{
489 /* MR23 */	if ( hasMultipleOperands(p->ret) )
490 			{
491 				DumpRetValStruct(f, p->ret, i);
492 			}
493 			fprintf(f, "\n#ifdef __USE_PROTOS\n");
494 /* MR23 */	if ( hasMultipleOperands(p->ret) )
495 			{
496 				fprintf(f, "extern struct _rv%d", i);
497 			}
498 			else
499 			{
500 				fprintf(f, "extern ");
501 				DumpType(p->ret, f);
502 			}
503 			fprintf(f, " %s%s(", RulePrefix, p->rname);
504 			DumpANSIFunctionArgDef(f,p,1 /* emit initializers ? */);
505 			fprintf(f, ";\n");
506 			fprintf(f, "#else\n");
507 /* MR23 */	if ( hasMultipleOperands(p->ret) )
508 			{
509 				fprintf(f, "extern struct _rv%d", i);
510 			}
511 			else
512 			{
513 				fprintf(f, "extern ");
514 				DumpType(p->ret, f);
515 			}
516 			fprintf(f, " %s%s();\n", RulePrefix, p->rname);
517 			fprintf(f, "#endif\n");
518 		}
519 		else
520 		{
521 			fprintf(f, "\n#ifdef __USE_PROTOS\n");
522 			fprintf(f, "void %s%s(", RulePrefix, p->rname);
523 			DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );
524 			fprintf(f, ";\n");
525 #ifdef OLD
526 			if ( p->pdecl != NULL || GenAST )
527 			{
528 				if ( GenAST ) {
529 					fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
530 				}
531 				if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
532 			}
533 			else fprintf(f, "void");
534 			fprintf(f, ");\n");
535 #endif
536 			fprintf(f, "#else\n");
537 			fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);
538 			fprintf(f, "#endif\n");
539 		}
540 		i++;
541 		p = (Junction *)p->p2;
542 	}
543 }
544 
545 /* Define all rules in the class.h file; generate any required
546  * struct definitions first, however.
547  */
548 void
549 #ifdef __USE_PROTOS
GenRuleMemberDeclarationsForCC(FILE * f,Junction * q)550 GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
551 #else
552 GenRuleMemberDeclarationsForCC( f, q )
553 FILE *f;
554 Junction *q;
555 #endif
556 {
557 	Junction *p = q;
558 	int i;
559 
560 	fprintf(f, "private:\n");
561 
562 	/* Dump dflt handler declaration */
563 	fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");
564 
565 	fprintf(f, "public:\n");
566 
567 	/* Dump return value structs */
568 	i = 1;
569 	while ( p!=NULL )
570 	{
571 		if ( p->ret != NULL )
572 		{
573 /* MR23 */	if ( hasMultipleOperands(p->ret) )
574 			{
575 				DumpRetValStruct(f, p->ret, i);
576 			}
577 		}
578 		i++;
579 		p = (Junction *)p->p2;
580 	}
581 
582 	/* Dump member func defs && CONSTRUCTOR */
583 	fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);
584 /*
585 	fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n",
586 			   CurrentClassName);
587 */
588 
589 	i = 1;
590 	p = q;
591 	while ( p!=NULL )
592 	{
593 		if ( p->ret != NULL )
594 		{
595 /* MR23 */	if ( hasMultipleOperands(p->ret) )
596 			{
597 				fprintf(f, "\tstruct _rv%d", i);
598 			}
599 			else
600 			{
601 				fprintf(f, "\t");
602 				DumpType(p->ret, f);
603 			}
604 			fprintf(f, " %s%s(",RulePrefix,p->rname);
605 			DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );
606 			fprintf(f, ";\n");
607 #ifdef OLD
608 			if ( p->pdecl != NULL || GenAST )
609 			{
610 				if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
611 				if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
612 			}
613 			fprintf(f, ");\n");
614 #endif
615 		}
616 		else
617 		{
618 			fprintf(f, "\tvoid %s%s(",RulePrefix,p->rname);
619 			DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */);
620 			fprintf(f, ";\n");
621 #ifdef OLD
622 			if ( p->pdecl != NULL || GenAST )
623 			{
624 				if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
625 				if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
626 			}
627 			fprintf(f, ");\n");
628 #endif
629 		}
630 		i++;
631 		p = (Junction *)p->p2;
632 	}
633 }
634 
635 /* Given a list of ANSI-style parameter declarations, print out a
636  * comma-separated list of the symbols (w/o types).
637  * Basically, we look for a comma, then work backwards until start of
638  * the symbol name.  Then print it out until 1st non-alnum char.  Now,
639  * move on to next parameter.
640  *
641  */
642 
643 /* MR5 	Jan Mikkelsen 26-May-97 - added initalComma parameter              */
644 
645 void
646 #ifdef __USE_PROTOS
DumpListOfParmNames(char * pdecl,FILE * output,int initialComma)647 DumpListOfParmNames(char *pdecl, FILE *output, int initialComma)    /* MR5 */
648 #else
649 DumpListOfParmNames(pdecl, output, initialComma)		            /* MR5 */
650 char *pdecl;	             		 			  	                /* MR5 */
651 FILE *output;							                            /* MR5 */
652 int initialComma;			                                        /* MR5 */
653 #endif
654 {
655 	int firstTime = 1, done = 0;
656 	require(output!=NULL, "DumpListOfParmNames: NULL parm");
657 
658 	if ( pdecl == NULL ) return;
659 	while ( !done )
660 	{
661 		if ( !firstTime || initialComma ) putc(',', output);        /* MR5 */
662 		done = DumpNextNameInDef(&pdecl, output);
663 		firstTime = 0;
664 	}
665 }
666 
667 /* given a list of parameters or return values, dump the next
668  * name to output.  Return 1 if last one just printed, 0 if more to go.
669  */
670 
671 /* MR23 Total rewrite */
672 
673 int
674 #ifdef __USE_PROTOS
DumpNextNameInDef(char ** q,FILE * output)675 DumpNextNameInDef( char **q, FILE *output )
676 #else
677 DumpNextNameInDef( q, output )
678 char **q;
679 FILE *output;
680 #endif
681 {
682 	char *p;
683 	char *t;
684 	char *pDataType;
685 	char *pSymbol;
686 	char *pEqualSign;
687 	char *pValue;
688 	char *pSeparator;
689 	int nest = 0;
690 
691 	p = endFormal(*q,
692 			      &pDataType,
693 				  &pSymbol,
694 				  &pEqualSign,
695 				  &pValue,
696 				  &pSeparator,
697 				  &nest);
698 
699     /* MR26 Handle rule arguments such as: IIR_Bool (IIR_Decl::*contstraint)()
700        For this we need to strip off anything which follows the symbol.
701      */
702 
703 /* MR26 */  t = pSymbol;
704 /* MR26 */	if (t != NULL) {
705 /* MR26 */		for (t = pSymbol; *t != 0; t++) {
706 /* MR26 */			if (! (isalpha(*t) || isdigit(*t) || *t == '_' || *t == '$')) break;
707 /* MR26 */		}
708 /* MR26 */	}
709 /* MR26 */	fprintf(output,strBetween(pSymbol, t, pSeparator));
710 
711     *q = p;
712     return (*pSeparator  == 0);
713 }
714 
715 /* Given a list of ANSI-style parameter declarations, dump K&R-style
716  * declarations, one per line for each parameter.  Basically, convert
717  * comma to semi-colon, newline.
718  */
719 void
720 #ifdef __USE_PROTOS
DumpOldStyleParms(char * pdecl,FILE * output)721 DumpOldStyleParms( char *pdecl, FILE *output )
722 #else
723 DumpOldStyleParms( pdecl, output )
724 char *pdecl;
725 FILE *output;
726 #endif
727 {
728 	require(output!=NULL, "DumpOldStyleParms: NULL parm");
729 
730 	if ( pdecl == NULL ) return;
731 	while ( *pdecl != '\0' )
732 	{
733 		if ( *pdecl == ',' )
734 		{
735 			pdecl++;
736 			putc(';', output); putc('\n', output);
737 			while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
738 		}
739 		else {putc(*pdecl, output); pdecl++;}
740 	}
741 	putc(';', output);
742 	putc('\n', output);
743 }
744 
745 /* Take in a type definition (type + symbol) and print out type only */
746 /* MR23 Total rewrite */
747 
748 void
749 #ifdef __USE_PROTOS
DumpType(char * s,FILE * f)750 DumpType( char *s, FILE *f )
751 #else
752 DumpType( s, f )
753 char *s;
754 FILE *f;
755 #endif
756 {
757 	char *p;
758 	char *pDataType;
759 	char *pSymbol;
760 	char *pEqualSign;
761 	char *pValue;
762 	char *pSeparator;
763 	int nest = 0;
764 
765 	require(s!=NULL, "DumpType: invalid type string");
766 
767 	p = endFormal(s,
768 			      &pDataType,
769 				  &pSymbol,
770 				  &pEqualSign,
771 				  &pValue,
772 				  &pSeparator,
773 				  &nest);
774 	fprintf(f,strBetween(pDataType, pSymbol, pSeparator));
775 }
776 
777 /* check to see if string e is a word in string s */
778 int
779 #ifdef __USE_PROTOS
strmember(char * s,char * e)780 strmember( char *s, char *e )
781 #else
782 strmember( s, e )
783 char *s;
784 char *e;
785 #endif
786 {
787     register char *p;
788     require(s!=NULL&&e!=NULL, "strmember: NULL string");
789 
790     if ( *e=='\0' ) return 1;   /* empty string is always member */
791     do {
792 	while ( *s!='\0' && !isalnum(*s) && *s!='_' )
793 	++s;
794 	p = e;
795 	while ( *p!='\0' && *p==*s ) {p++; s++;}
796 	if ( *p=='\0' ) {
797 	    if ( *s=='\0' ) return 1;
798 	    if ( !isalnum (*s) && *s != '_' ) return 1;
799 	}
800 	while ( isalnum(*s) || *s == '_' )
801 	++s;
802     } while ( *s!='\0' );
803     return 0;
804 }
805 
806 #if 0
807 
808 /* MR23 Replaced by hasMultipleOperands() */
809 
810 int
811 #ifdef __USE_PROTOS
812 HasComma( char *s )
813 #else
814 HasComma( s )
815 char *s;
816 #endif
817 {
818 	while (*s!='\0')
819 		if ( *s++ == ',' ) return 1;
820 	return 0;
821 }
822 #endif
823 
824 
825 /* MR23 Total rewrite */
826 
827 void
828 #ifdef __USE_PROTOS
DumpRetValStruct(FILE * f,char * ret,int i)829 DumpRetValStruct( FILE *f, char *ret, int i )
830 #else
831 DumpRetValStruct( f, ret, i )
832 FILE *f;
833 char *ret;
834 int i;
835 #endif
836 {
837 	char *p = ret;
838 	char *pDataType;
839 	char *pSymbol;
840 	char *pEqualSign;
841 	char *pValue;
842 	char *pSeparator;
843     int nest = 0;
844 
845 	fprintf(f, "\nstruct _rv%d {\n", i);
846 	while (*p != 0 && nest == 0) {
847 		p = endFormal(p,
848 			          &pDataType,
849 					  &pSymbol,
850 					  &pEqualSign,
851 					  &pValue,
852 					  &pSeparator,
853 					  &nest);
854 		fprintf(f,"\t");
855 		fprintf(f,strBetween(pDataType, pSymbol, pSeparator));
856 		fprintf(f," ");
857 		fprintf(f,strBetween(pSymbol, pEqualSign, pSeparator));
858 		fprintf(f,";\n");
859     }
860 	fprintf(f,"};\n");
861 }
862 
863 /* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
864 char *
865 #ifdef __USE_PROTOS
StripQuotes(char * s)866 StripQuotes( char *s )
867 #else
868 StripQuotes( s )
869 char *s;
870 #endif
871 {
872 	if ( *s == '"' )
873 	{
874 		s[ strlen(s)-1 ] = '\0';    /* remove last quote */
875 		return( s+1 );				/* return address past initial quote */
876 	}
877 	return( s );
878 }
879