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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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