1/* 2 * antlr.g -- PCCTS Version 1.xx ANTLR 3 * 4 * Parse an antlr input grammar and build a syntax-diagram. 5 * 6 * Written in itself (needs at least 1.06 to work) 7 * 8 * SOFTWARE RIGHTS 9 * 10 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool 11 * Set (PCCTS) -- PCCTS is in the public domain. An individual or 12 * company may do whatever they wish with source code distributed with 13 * PCCTS or the code generated by PCCTS, including the incorporation of 14 * PCCTS, or its output, into commerical software. 15 * 16 * We encourage users to develop software with PCCTS. However, we do ask 17 * that credit is given to us for developing PCCTS. By "credit", 18 * we mean that if you incorporate our source code into one of your 19 * programs (commercial product, research project, or otherwise) that you 20 * acknowledge this fact somewhere in the documentation, research report, 21 * etc... If you like PCCTS and have developed a nice tool with the 22 * output, please mention that you developed it using PCCTS. In 23 * addition, we ask that this header remain intact in our source code. 24 * As long as these guidelines are kept, we expect to continue enhancing 25 * this system and expect to make other tools available as they are 26 * completed. 27 * 28 * ANTLR 1.33 29 * Terence Parr 30 * Parr Research Corporation 31 * with Purdue University and AHPCRC, University of Minnesota 32 * 1989-1995 33 */ 34 35/* MR1 */ 36/* MR1 10-Apr-97 MR1 Replace #if logic with #include "pcctscfg.h" */ 37/* MR1 */ 38 39#header << 40 #include "pcctscfg.h" 41 #include "set.h" 42 #include <ctype.h> 43 #include "syn.h" 44 #include "hash.h" 45 #include "generic.h" 46 #define zzcr_attr(attr,tok,t) 47 >> 48 49<< 50 51/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */ 52#if defined(__TURBOC__) 53#pragma warn -aus /* unused assignment of 'xxx' */ 54#endif 55 56 57#ifdef __USE_PROTOS 58static void chkToken(char *, char *, char *, int); 59#else 60static void chkToken(); 61#endif 62 63#ifdef __USE_PROTOS 64static int isDLGmaxToken(char *Token); /* MR3 */ 65#else 66static int isDLGmaxToken(); /* MR3 */ 67#endif 68 69static int class_nest_level = 0; 70 71/* MR20 G. Hobbelt extern definitions moved to antlr.h */ 72 73>> 74 75#lexaction << 76/* maintained, but not used for now */ 77set AST_nodes_refd_in_actions = set_init; 78int inAlt = 0; 79set attribsRefdFromAction = set_init; /* MR20 */ 80int UsedOldStyleAttrib = 0; 81int UsedNewStyleLabel = 0; 82#ifdef __USE_PROTOS 83char *inline_set(char *); 84#else 85char *inline_set(); 86#endif 87 88/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ 89/* MR1 in DLG action */ 90 91int tokenActionActive=0; /* MR1 */ 92 93>> 94 95#lexclass STRINGS 96#token QuotedTerm "\"" << zzmode(START); >> 97#token "\n|\r|\r\n" << 98 zzline++; 99 warn("eoln found in string"); 100 zzskip(); 101 >> 102#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> 103#token "\\~[]" << zzmore(); >> 104#token "~[\n\r\"\\]+" << zzmore(); >> 105 106#lexclass ACTION_STRINGS 107#token "\"" << zzmode(ACTIONS); zzmore(); >> 108#token "\n|\r|\r\n" << 109 zzline++; 110 warn("eoln found in string (in user action)"); 111 zzskip(); 112 >> 113#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> 114#token "\\~[]" << zzmore(); >> 115#token "~[\n\r\"\\]+" << zzmore(); >> 116 117#lexclass ACTION_CHARS 118#token "'" << zzmode(ACTIONS); zzmore(); >> 119#token "\n|\r|\r\n" << 120 zzline++; 121 warn("eoln found in char literal (in user action)"); 122 zzskip(); 123 >> 124#token "\\~[]" << zzmore(); >> 125#token "~[\n\r'\\]+" << zzmore(); >> 126 127#lexclass ACTION_COMMENTS 128#token "\*/" << zzmode(ACTIONS); zzmore(); >> 129#token "\*" << zzmore(); >> 130#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> 131#token "~[\n\r\*]+" << zzmore(); >> 132 133#lexclass TOK_DEF_COMMENTS 134#token "\*/" << zzmode(PARSE_ENUM_FILE); 135 zzmore(); >> 136#token "\*" << zzmore(); >> 137#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> 138#token "~[\n\r\*]+" << zzmore(); >> 139 140#lexclass TOK_DEF_CPP_COMMENTS 141#token "\n|\r|\r\n" << zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >> 142#token "~[\n\r]+" << zzskip(); >> 143 144#lexclass ACTION_CPP_COMMENTS 145#token "\n|\r|\r\n" << zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >> 146#token "~[\n\r]+" << zzmore(); >> 147 148#lexclass CPP_COMMENTS 149#token "\n|\r|\r\n" << zzline++; zzmode(START); zzskip(); DAWDLE; >> 150#token "~[\n\r]+" << zzskip(); >> 151 152#lexclass COMMENTS 153#token "\*/" << zzmode(START); zzskip(); >> 154#token "\*" << zzskip(); >> 155#token "\n|\r|\r\n" << zzline++; zzskip(); DAWDLE; >> 156#token "~[\n\r\*]+" << zzskip(); >> 157 158/* 159 * This lexical class accepts actions of type [..] and <<..>> 160 * 161 * It translates the following special items for C: 162 * 163 * $j --> "zzaArg(current zztasp, j)" 164 * $i.j --> "zzaArg(zztaspi, j)" 165 * $i.nondigit> "zzaArg(current zztasp, i).nondigit" 166 * $$ --> "zzaRet" 167 * $alnum --> "alnum" (used to ref parameters) 168 * $rule --> "zzaRet" 169 * $retval --> "_retv.retval" if > 1 return values else "_retv" 170 * $[token, text] --> "zzconstr_attr(token, text)" 171 * $[] --> "zzempty_attr()" 172 * 173 * It translates the following special items for C++: 174 * (attributes are now stored with 'Token' and $i's are only 175 * pointers to the Tokens. Rules don't have attributes now.) 176 * 177 * $j --> "_tbj" where b is the block level 178 * $i.j --> "_tij" 179 * $j->nondigit> "_tbj->nondigit" 180 * $$ --> "$$" 181 * $alnum --> "alnum" (used to ref parameters) 182 * $rule --> "$rule" 183 * $retval --> "_retv.retval" if > 1 return values else "_retv" 184 * $[token, text] --> invalid 185 * $[] --> invalid 186 * 187 * And, for trees: 188 * 189 * #0 --> "(*_root)" 190 * #i --> "zzastArg(i)" 191 * #[args] --> "zzmk_ast(zzastnew(), args)" 192 * #[] --> "zzastnew()" 193 * #( root, child1, ..., childn ) 194 * --> "zztmake(root, child1, ...., childn, NULL)" 195 * #() --> "NULL" 196 * 197 * For C++, ... 198 * 199 * #0 --> "(*_root)" 200 * #i --> "_astbi" where b is the block level 201 * #alnum --> "alnum_ast" (used to ref #label) 202 * #[args] --> "new AST(args)" 203 * #[] --> "new AST" 204 * #( root, child1, ..., childn ) 205 * --> "AST::tmake(root, child1, ...., childn, NULL)" 206 * #() --> "NULL" 207 * 208 * To escape, 209 * 210 * \] --> ] 211 * \) --> ) 212 * \$ --> $ 213 * \# --> # 214 * 215 * A stack is used to nest action terminators because they can be nested 216 * like crazy: << #[$[..],..] >> 217 */ 218#lexclass ACTIONS 219#token Action "\>\>" << /* these do not nest */ 220 zzmode(START); 221 NLATEXT[0] = ' '; 222 NLATEXT[1] = ' '; 223 zzbegexpr[0] = ' '; 224 zzbegexpr[1] = ' '; 225 if ( zzbufovf ) { 226 err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); 227 } 228 229/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ 230/* MR1 in DLG action */ 231/* MR1 Doesn't matter what kind of action it is - reset*/ 232 233 tokenActionActive=0; /* MR1 */ 234 >> 235#token Pred "\>\>?" << /* these do not nest */ 236 zzmode(START); 237 NLATEXT[0] = ' '; 238 NLATEXT[1] = ' '; 239 zzbegexpr[0] = '\0'; 240 if ( zzbufovf ) { 241 err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); 242 }; 243#ifdef __cplusplus__ 244/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); 245#else 246#ifdef __STDC__ 247/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); 248#else 249#ifdef __USE_PROTOS 250/* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); 251#else 252/* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); 253#endif 254#endif 255#endif 256 >> 257#token PassAction "\]" << if ( topint() == ']' ) { 258 popint(); 259 if ( istackempty() ) /* terminate action */ 260 { 261 zzmode(START); 262 NLATEXT[0] = ' '; 263 zzbegexpr[0] = ' '; 264 if ( zzbufovf ) { 265 err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); 266 } 267 } 268 else { 269 /* terminate $[..] and #[..] */ 270 if ( GenCC ) zzreplstr("))"); 271 else zzreplstr(")"); 272 zzmore(); 273 } 274 } 275 else if ( topint() == '|' ) { /* end of simple [...] */ 276 popint(); 277 zzmore(); 278 } 279 else zzmore(); 280 >> 281#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)" 282 << 283 zzmore(); 284 zzreplstr(inline_set(zzbegexpr+ 285 strlen("consumeUntil("))); 286 >> 287#token "consumeUntil\( ~[\)]+ \)" 288 << zzmore(); >> 289#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> 290#token "\>" << zzmore(); >> 291#token "$" << zzmore(); >> 292#token "$$" << if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} 293 else err("$$ use invalid in C++ mode"); >> 294 295#token "$\[\]" << if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} 296 else err("$[] use invalid in C++ mode"); >> 297#token "$\[" << 298 pushint(']'); 299 if ( !GenCC ) zzreplstr("zzconstr_attr("); 300 else err("$[..] use invalid in C++ mode"); 301 zzmore(); 302 >> 303#token "$[0-9]+" <<{ 304 static char buf[100]; 305 numericActionLabel=1; /* MR10 */ 306 if ( strlen(zzbegexpr)>(size_t)85 ) 307 fatal("$i attrib ref too big"); 308 set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); 309 if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", 310 BlkLevel-1,zzbegexpr+1); 311 else sprintf(buf,"_t%d%s", 312 BlkLevel-1,zzbegexpr+1); 313 zzreplstr(buf); 314 zzmore(); 315 UsedOldStyleAttrib = 1; 316 if ( UsedNewStyleLabel ) 317 err("cannot mix old-style $i with new-style labels"); 318 } 319 >> 320#token "$[0-9]+." <<{ 321 static char buf[100]; 322 numericActionLabel=1; /* MR10 */ 323 if ( strlen(zzbegexpr)>(size_t)85 ) 324 fatal("$i.field attrib ref too big"); 325 zzbegexpr[strlen(zzbegexpr)-1] = ' '; 326 set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); 327 if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", 328 BlkLevel-1,zzbegexpr+1); 329 else sprintf(buf,"_t%d%s.", 330 BlkLevel-1,zzbegexpr+1); 331 zzreplstr(buf); 332 zzmore(); 333 UsedOldStyleAttrib = 1; 334 if ( UsedNewStyleLabel ) 335 err("cannot mix old-style $i with new-style labels"); 336 } 337 >> 338#token "$[0-9]+.[0-9]+" <<{ 339 static char buf[100]; 340 static char i[20], j[20]; 341 char *p,*q; 342 numericActionLabel=1; /* MR10 */ 343 if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); 344 for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { 345 if ( q == &i[20] ) 346 fatalFL("i of $i.j attrib ref too big", 347 FileStr[CurFile], zzline ); 348 *q++ = *p; 349 } 350 *q = '\0'; 351 for (p++, q= &j[0]; *p!='\0'; p++) { 352 if ( q == &j[20] ) 353 fatalFL("j of $i.j attrib ref too big", 354 FileStr[CurFile], zzline ); 355 *q++ = *p; 356 } 357 *q = '\0'; 358 if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); 359 else sprintf(buf,"_t%s%s",i,j); 360 zzreplstr(buf); 361 zzmore(); 362 UsedOldStyleAttrib = 1; 363 if ( UsedNewStyleLabel ) 364 err("cannot mix old-style $i with new-style labels"); 365 } 366 >> 367#token "$[_a-zA-Z][_a-zA-Z0-9]*" 368 <<{ static char buf[300]; LabelEntry *el; 369 zzbegexpr[0] = ' '; 370 if ( CurRule != NULL && 371 strcmp(CurRule, &zzbegexpr[1])==0 ) { 372 if ( !GenCC ) zzreplstr("zzaRet"); 373 } 374 else if ( CurRetDef != NULL && 375 strmember(CurRetDef, &zzbegexpr[1])) { 376 if ( hasMultipleOperands( CurRetDef ) ) { 377 require (strlen(zzbegexpr)<=(size_t)285, 378 "$retval attrib ref too big"); 379 sprintf(buf,"_retv.%s",&zzbegexpr[1]); 380 zzreplstr(buf); 381 } 382 else zzreplstr("_retv"); 383 } 384 else if ( CurParmDef != NULL && 385 strmember(CurParmDef, &zzbegexpr[1])) { 386 ; 387 } 388 else if ( Elabel==NULL ) { 389 { err("$-variables in actions outside of rules are not allowed"); } 390 } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { 391/* MR10 */ 392/* MR10 */ /* element labels might exist without an elem when */ 393/* MR10 */ /* it is a forward reference (to a rule) */ 394/* MR10 */ 395/* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) 396/* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } 397/* MR10 */ 398/* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { 399/* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); 400/* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")"); 401/* MR10 */ }; 402/* MR10 */ 403/* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ 404/* MR10 */ /* element labels contain pointer to the owners node */ 405/* MR10 */ 406/* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { 407/* MR10 */ list_add(&CurActionLabels,el); 408/* MR10 */ }; 409 } 410 else 411 warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); 412 } 413 zzmore(); 414 >> 415#token "#0" << zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >> 416#token "#\[\]" << if ( GenCC ) { 417 if (NewAST) zzreplstr("(newAST)"); 418 else zzreplstr("(new AST)");} 419 else {zzreplstr("zzastnew()");} zzmore(); 420 chkGTFlag(); 421 >> 422#token "#\(\)" << zzreplstr("NULL"); zzmore(); chkGTFlag(); >> 423#token "#[0-9]+" <<{ 424 static char buf[100]; 425 if ( strlen(zzbegexpr)>(size_t)85 ) 426 fatal("#i AST ref too big"); 427 if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); 428 else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); 429 zzreplstr(buf); 430 zzmore(); 431 set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); 432 chkGTFlag(); 433 } 434 >> 435 436/* MR14 Arpad Beszedes 26-May-98 437 Add support for #line directives when antlr source is pre-processed 438 #lexclass ACTIONS 439*/ 440 441#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)" 442 << 443 zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); 444 getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); 445 >> 446 447#token "#line ~[\n\r]* (\n|\r|\r\n)" 448 << 449 zzline++; zzmore(); 450 >> 451 452/* MR14 end of a block to support #line in antlr source code */ 453 454#token "#[_a-zA-Z][_a-zA-Z0-9]*" 455 << 456 if ( !(strcmp(zzbegexpr, "#ifdef")==0 || 457 strcmp(zzbegexpr, "#if")==0 || 458 strcmp(zzbegexpr, "#else")==0 || 459 strcmp(zzbegexpr, "#endif")==0 || 460 strcmp(zzbegexpr, "#ifndef")==0 || 461 strcmp(zzbegexpr, "#define")==0 || 462 strcmp(zzbegexpr, "#pragma")==0 || 463 strcmp(zzbegexpr, "#undef")==0 || 464 strcmp(zzbegexpr, "#import")==0 || 465 strcmp(zzbegexpr, "#line")==0 || 466 strcmp(zzbegexpr, "#include")==0 || 467 strcmp(zzbegexpr, "#error")==0) ) 468 { 469 static char buf[100]; 470 sprintf(buf, "%s_ast", zzbegexpr+1); 471/* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); 472 zzreplstr(buf); 473 chkGTFlag(); 474 } 475 zzmore(); 476 >> 477#token "#\[" << 478 pushint(']'); 479 if ( GenCC ) { 480 if (NewAST) zzreplstr("(newAST("); 481 else zzreplstr("(new AST("); } 482 else zzreplstr("zzmk_ast(zzastnew(),"); 483 zzmore(); 484 chkGTFlag(); 485 >> 486#token "#\(" << 487 pushint('}'); 488 if ( GenCC ) { 489 if (tmakeInParser) { 490 zzreplstr("tmake("); 491 } 492 else { 493 zzreplstr("ASTBase::tmake("); 494 } 495 } 496 else { 497 zzreplstr("zztmake("); 498 } 499 zzmore(); 500 chkGTFlag(); 501 >> 502#token "#" << zzmore(); >> 503#token "\)" << 504 if ( istackempty() ) 505 zzmore(); 506 else if ( topint()==')' ) { 507 popint(); 508 } 509 else if ( topint()=='}' ) { 510 popint(); 511 /* terminate #(..) */ 512 zzreplstr(", NULL)"); 513 } 514 zzmore(); 515 >> 516#token "\[" << 517 pushint('|'); /* look for '|' to terminate simple [...] */ 518 zzmore(); 519 >> 520#token "\(" << 521 pushint(')'); 522 zzmore(); 523 >> 524 525#token "\\\]" << zzreplstr("]"); zzmore(); >> 526#token "\\\)" << zzreplstr(")"); zzmore(); >> 527 528/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ 529/* MR1 in DLG action */ 530 531#token "\\>" << if (! tokenActionActive) zzreplstr(">"); /* MR1 */ 532 zzmore(); /* MR1 */ 533 >> /* MR1 */ 534 535 536#token "'" << zzmode(ACTION_CHARS); zzmore();>> 537#token "\"" << zzmode(ACTION_STRINGS); zzmore();>> 538#token "\\$" << zzreplstr("$"); zzmore(); >> 539#token "\\#" << zzreplstr("#"); zzmore(); >> 540#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> 541#token "\\~[\]\)>$#]" << zzmore(); >> /* escaped char, always ignore */ 542#token "/" << zzmore(); >> 543#token "/\*" << zzmode(ACTION_COMMENTS); zzmore(); >> 544#token "\*/" << warn("Missing /*; found dangling */ in action"); zzmore(); >> 545#token "//" << zzmode(ACTION_CPP_COMMENTS); zzmore(); >> 546#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >> 547 548#lexclass START 549#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ 550#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */ 551#token "\[" << zzmode(ACTIONS); zzmore(); 552 istackreset(); 553 pushint(']'); >> 554#token "\<\<" << action_file=CurFile; action_line=zzline; 555 zzmode(ACTIONS); zzmore(); 556 list_free(&CurActionLabels,0); /* MR10 */ 557 numericActionLabel=0; /* MR10 */ 558 istackreset(); 559 pushint('>'); >> 560#token "\"" << zzmode(STRINGS); zzmore(); >> 561#token "/\*" << zzmode(COMMENTS); zzskip(); >> 562#token "\*/" << warn("Missing /*; found dangling */"); zzskip(); >> 563#token "//" << zzmode(CPP_COMMENTS); zzskip(); >> 564 565/* MR14 Arpad Beszedes 26-May-98 566 Add support for #line directives when antlr source is pre-processed 567 #lexclass START 568*/ 569 570#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)" 571 << 572 zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); 573 getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); 574 >> 575 576#token "#line ~[\n\r]* (\n|\r|\r\n)" 577 << 578 zzline++; zzmore(); 579 >> 580 581/* MR14 end of a block to support #line in antlr source code */ 582 583/* */ 584/* 8-Apr-97 Regularize escape sequence for ">>" */ 585/* appearing in string literals */ 586/* */ 587 588#token "\>\>" << warn("Missing <<; found dangling \>\>"); zzskip(); >> /* MR1 */ 589#token WildCard "." 590#token "\@" <<FoundException = 1; /* MR6 */ 591 FoundAtOperator = 1;>> /* MR6 */ 592#token Eof "@" 593 << /* L o o k F o r A n o t h e r F i l e */ 594 { 595 FILE *new_input; 596 new_input = NextFile(); 597 if ( new_input == NULL ) { NLA=Eof; return; } 598 fclose( input ); 599 input = new_input; 600 zzrdstream( input ); 601 zzskip(); /* Skip the Eof (@) char i.e continue */ 602 } 603 >> 604 605#token LABEL 606 607#errclass "grammar-element" { element } 608#errclass "meta-symbol" { "\}" "!" ";" "\|" "\~" "^" "\)" } 609 610#token Pragma "{\\}#pragma" /* MR21 */ 611#token FirstSetSymbol "{\\}#FirstSetSymbol" /* MR21 */ 612/* 613 * Get a grammar -- Build a list of rules like: 614 * 615 * o-->Rule1--o 616 * | 617 * o-->Rule2--o 618 * | 619 * ... 620 * | 621 * o-->RuleN--o 622 */ 623 624/* rule grammar */ 625 626grammar : <<Graph g;>> 627 ( "{\\}#header" Action /* MR13 */ 628 << 629 if ( HdrAction==NULL ) { 630 HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 631 require(HdrAction!=NULL, "rule grammar: cannot allocate header action"); 632 strcpy(HdrAction, LATEXT(1)); 633 } 634 else warn("additional #header statement ignored"); 635 >> 636 | "{\\}#first" Action 637 << 638 if ( FirstAction==NULL ) { 639 FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 640 require(FirstAction!=NULL, "rule grammar: cannot allocate #first action"); 641 strcpy(FirstAction, LATEXT(1)); 642 } else { 643 warn("additional #first statement ignored"); 644 }; 645 >> 646 647 | "{\\}#parser" QuotedTerm 648 << 649 if ( GenCC ) { 650 warn("#parser meta-op incompatible with -CC; ignored"); 651 } 652 else { 653 if ( strcmp(ParserName,"zzparser")==0 ) { 654 ParserName=StripQuotes(mystrdup(LATEXT(1))); 655 if ( RulePrefix[0]!='\0' ) 656 { 657 warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored"); 658 RulePrefix[0]='\0'; 659 } 660 } 661 else warn("additional #parser statement ignored"); 662 } 663 >> 664 | "{\\}#tokdefs" QuotedTerm 665 <<{ 666 char *fname; 667 zzantlr_state st; FILE *f; struct zzdlg_state dst; 668 UserTokenDefsFile = mystrdup(LATEXT(1)); 669 zzsave_antlr_state(&st); 670 zzsave_dlg_state(&dst); 671 fname = mystrdup(LATEXT(1)); 672 f = fopen(StripQuotes(fname), "r"); 673 if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));} 674 else { 675 ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE); 676 UserDefdTokens = 1; 677 } 678 zzrestore_antlr_state(&st); 679 zzrestore_dlg_state(&dst); 680 }>> 681 )* 682 ( Action 683 <<{ 684 UserAction *ua = newUserAction(LATEXT(1)); 685 ua->file = action_file; ua->line = action_line; 686 if ( class_nest_level>0 ) list_add(&class_before_actions, ua); 687 else list_add(&BeforeActions, ua); 688 }>> 689 | laction 690 | lmember /* MR1 */ 691 | lprefix /* MR1 */ 692 | aLexclass 693 | token 694 | error 695 | tclass 696 | aPred /* MR11 */ 697 | default_exception_handler 698 | class_def 699 | "\}" 700 << 701 if ( class_nest_level==0 ) 702 warn("missing class definition for trailing '}'"); 703 class_nest_level--; 704 >> 705 )* 706 707 rule <<g=$3; SynDiag = (Junction *) $3.left;>> 708 ( rule 709 710 <<if ( $1.left!=NULL ) { 711 g.right = NULL; 712 713/* MR21a */ /* Avoid use of a malformed graph when CannotContinue */ 714/* MR21a */ /* is already set */ 715/* MR21a */ 716/* MR21a */ if (! (CannotContinue && g.left == NULL)) { 717/* MR21a */ g = Or(g, $1); 718/* MR21a */ } 719/* MR21a */ } 720 >> 721 722 | aLexclass 723 | token 724 | error 725 | tclass 726 | aPred /* MR11 */ 727 | class_def 728 | "\}" 729 << 730 if ( class_nest_level==0 ) 731 warn("missing class definition for trailing '}'"); 732 class_nest_level--; 733 >> 734 )* 735 ( Action 736 <<{ 737 UserAction *ua = newUserAction(LATEXT(1)); 738 ua->file = action_file; ua->line = action_line; 739 if ( class_nest_level>0 ) list_add(&class_after_actions, ua); 740 else list_add(&AfterActions, ua); 741 }>> 742 | laction 743 | lmember /* MR1 */ 744 | lprefix /* MR1 */ 745 | error 746 | tclass 747 | class_def 748 | aPred /* MR11 */ 749 | "\}" 750 << 751 if ( class_nest_level==0 ) 752 warn("missing class definition for trailing '}'"); 753 class_nest_level--; 754 >> 755 )* 756 Eof 757 ; 758 <<CannotContinue=TRUE;>> 759 760/* rule class_def */ 761 762class_def 763 : <<int go=1; char name[MaxRuleName+1];>> 764 "class" 765 ( NonTerminal <<if(go) strncpy(name,LATEXT(1),MaxRuleName);>> 766 | TokenTerm <<if(go) strncpy(name,LATEXT(1),MaxRuleName);>> 767 ) 768 << 769 if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0 770 && GenCC ) { 771 err("only one grammar class allowed in this release"); 772 go = 0; 773 } 774 else strcpy(CurrentClassName, name); 775 >> 776 <<if ( !GenCC ) { err("class meta-op used without C++ option"); }>> 777 778/* MR10 */ (~ "\{" 779/* MR10 */ <<if (ClassDeclStuff == NULL) { 780/* MR10 */ ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char)); 781/* MR10 */ }; 782/* MR10 */ strncat(ClassDeclStuff," ",MaxClassDeclStuff); 783/* MR10 */ strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff); 784/* MR22 */ do { 785/* MR22 */ if (0 == strcmp(LATEXT(1),"public")) break; 786/* MR22 */ if (0 == strcmp(LATEXT(1),"private")) break; 787/* MR22 */ if (0 == strcmp(LATEXT(1),"protected")) break; 788/* MR22 */ if (0 == strcmp(LATEXT(1),"virtual")) break; 789/* MR22 */ if (0 == strcmp(LATEXT(1),",")) break; 790/* MR22 */ if (0 == strcmp(LATEXT(1),":")) break; 791/* MR22 */ if (BaseClassName != NULL) break; 792/* MR22 */ BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char)); 793/* MR22 */ require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name"); 794/* MR22 */ strcpy(BaseClassName,LATEXT(1)); 795/* MR22 */ } while (0); 796/* MR10 */ >> 797/* MR10 */ )* 798 799 "\{" 800 << 801 no_classes_found = 0; 802 if ( class_nest_level>=1 ) {warn("cannot have nested classes");} 803 else class_nest_level++; 804 >> 805 ; 806 <<CannotContinue=TRUE;>> 807 808/* 809 * Build -o-->o-R-o-->o- where -o-R-o- is the block from rule 'block'. 810 * Construct the RuleBlk front and EndRule node on the end of the 811 * block. This is used to add FOLLOW pointers to the rule end. Add the 812 * new rule name to the Rname hash table and sets its rulenum. 813 * Store the parameter definitions if any are found. 814 * 815 * Note that locks are required on the RuleBlk and EndRule nodes to thwart 816 * infinite recursion. 817 * 818 * Return the left graph pointer == NULL to indicate error/dupl rule def. 819 */ 820 821/* rule rule */ 822 823rule : << 824 825 ExceptionGroup *eg; 826 RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e; 827 set toksrefd, rulesrefd; 828 char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL; 829 CurExGroups = NULL; 830 CurElementLabels = NULL; 831 CurAstLabelsInActions = NULL; /* MR27 */ 832 /* We want a new element label hash table for each rule */ 833 if ( Elabel!=NULL ) killHashTable(Elabel); 834 Elabel = newHashTable(); 835 attribsRefdFromAction = empty; 836 >> 837 NonTerminal 838 <<q=NULL; 839 if ( hash_get(Rname, LATEXT(1))!=NULL ) { 840 err(eMsg1("duplicate rule definition: '%s'",LATEXT(1))); 841 CannotContinue=TRUE; 842 } 843 else 844 { 845 q = (RuleEntry *)hash_add(Rname, 846 LATEXT(1), 847 (Entry *)newRuleEntry(LATEXT(1))); 848 CurRule = q->str; 849 } 850 CurRuleNode = q; 851 f = CurFile; l = zzline; 852 NumRules++; 853 >> 854 { "!" <<if ( q!=NULL ) q->noAST = TRUE;>> } 855 { <<;>> 856 {"\<"} 857 PassAction 858 << pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 859 require(pdecl!=NULL, "rule rule: cannot allocate param decl"); 860 strcpy(pdecl, LATEXT(1)); 861 CurParmDef = pdecl; 862 >> 863 } 864 { "\>" 865 PassAction 866 << ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 867 require(ret!=NULL, "rule rule: cannot allocate ret type"); 868 strcpy(ret, LATEXT(1)); 869 CurRetDef = ret; 870 >> 871 } 872 { QuotedTerm <<if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1));>> } 873 << 874 if ( GenEClasseForRules && q!=NULL ) { 875 e = newECnode; 876 require(e!=NULL, "cannot allocate error class node"); 877 if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);} 878 else a = q->egroup; 879 if ( Tnum( a ) == 0 ) 880 { 881 e->tok = addTname( a ); 882 list_add(&eclasses, (char *)e); 883 if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); 884 /* refers to itself */ 885 list_add(&(e->elist), mystrdup(q->str)); 886 } 887 else { 888 warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a)); 889 if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); 890 free((char *)e); 891 } 892 } 893 >> 894 <<BlkLevel++; 895 if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); 896/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; 897/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; 898 >> 899 900 ":" <<inAlt=1;>> 901 block[&toksrefd, &rulesrefd] 902 <<r = makeBlk($7,0, NULL /* pFirstSetSymbol */ ); 903 CurRuleBlk = (Junction *)r.left; 904 CurRuleBlk->blockid = CurBlockID; 905 CurRuleBlk->jtype = RuleBlk; 906 if ( q!=NULL ) CurRuleBlk->rname = q->str; 907 CurRuleBlk->file = f; 908 CurRuleBlk->line = l; 909 CurRuleBlk->pdecl = pdecl; 910 CurRuleBlk->ret = ret; 911 CurRuleBlk->lock = makelocks(); 912 CurRuleBlk->pred_lock = makelocks(); 913 CurRuleBlk->tokrefs = toksrefd; 914 CurRuleBlk->rulerefs = rulesrefd; 915 p = newJunction(); /* add EndRule Node */ 916 ((Junction *)r.right)->p1 = (Node *)p; 917 r.right = (Node *) p; 918 p->jtype = EndRule; 919 p->lock = makelocks(); 920 p->pred_lock = makelocks(); 921 CurRuleBlk->end = p; 922 if ( q!=NULL ) q->rulenum = NumRules; 923 $7 = r; 924 >> 925 << 926 /* MR23 */ CurBlockID_array[BlkLevel] = (-1); 927 /* MR23 */ CurAltNum_array[BlkLevel] = (-1); 928 --BlkLevel; 929 >> 930 <<altFixup();leFixup();egFixup();>> /* MR7 */ 931 ";" <<inAlt=0;>> 932 { Action 933 << a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 934 require(a!=NULL, "rule rule: cannot allocate error action"); 935 strcpy(a, LATEXT(1)); 936 CurRuleBlk->erraction = a; 937 >> 938 } 939 ( exception_group > [eg] 940 <<if ( eg!=NULL ) { 941 list_add(&CurExGroups, (void *)eg); 942 if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1; 943 } 944 >> 945 )* 946 <<if ( q==NULL ) $0.left = NULL; else $0 = $7;>> 947 <<CurRuleBlk->exceptions = CurExGroups;>> 948 <<CurRuleBlk->el_labels = CurElementLabels;>> 949 <<CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions;>> /* MR27 */ 950 <<CurRuleNode = NULL;>> /* MR27 Moved */ 951 ; 952 <<CannotContinue=TRUE;>> 953 954/* 955 * pragma : "{\\}#pragma" "dup\-labeled\-tokens" 956 * <<Pragma_DupLabeledTokens=1;>> 957 * ; 958 */ 959 960/* rule laction */ 961 962laction : <<char *a;>> 963 964 "{\\}#lexaction" 965 Action 966 << 967 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 968 require(a!=NULL, "rule laction: cannot allocate action"); 969 strcpy(a, LATEXT(1)); 970 list_add(&LexActions, a); 971 >> 972 ; 973 <<CannotContinue=TRUE;>> 974 975/* MR1 */ 976/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ 977/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */ 978/* MR1 */ 979 980/* rule lmember */ 981 982lmember: <<char *a;>> /* MR1 */ 983 984/* MR1 */ "{\\}#lexmember" 985/* MR1 */ Action 986/* MR1 */ << 987/* MR1 */ if (! GenCC) { 988/* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header"); 989/* MR1 */ } else { 990/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 991/* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action"); 992/* MR1 */ strcpy(a, LATEXT(1)); 993/* MR1 */ list_add(&LexMemberActions, a); 994/* MR1 */ }; 995/* MR1 */ >> 996/* MR1 */ ; 997/* MR1 */ <<CannotContinue=TRUE;>> 998 999/* rule lprefix */ 1000 1001lprefix: <<char *a;>> /* MR1 */ 1002 1003/* MR1 */ "{\\}#lexprefix" 1004/* MR1 */ Action 1005/* MR1 */ << 1006/* MR1 */ if (! GenCC) { 1007/* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header"); 1008/* MR1 */ } else { 1009/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 1010/* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action"); 1011/* MR1 */ strcpy(a, LATEXT(1)); 1012/* MR1 */ list_add(&LexPrefixActions, a); 1013/* MR1 */ }; 1014/* MR1 */ >> 1015/* MR1 */ ; 1016/* MR1 */ <<CannotContinue=TRUE;>> 1017 1018/* 1019 * #pred upper <<isupper()>>? predicate literal 1020 * #pred lower <<islower()>>? predicate literal 1021 * #pred up_or_low upper || lower predicate expression 1022 * concealed interdependence 1023 * #pred up_or_low_2 <<isletter()>>? A || B predicate literal equals predicate expr 1024 * analyze using lower||upper 1025 * generate using isLetter() 1026 */ 1027 1028/* rule aPref */ 1029 1030aPred: <<PredEntry *predEntry=NULL; 1031 char *name=NULL; 1032 Predicate *predExpr=NULL; 1033 char *predLiteral=NULL; 1034 int save_file; 1035 int save_line; 1036 int predExprPresent=0; 1037 >> 1038 1039 "{\\}#pred" 1040 1041 << 1042 MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */ 1043 >> 1044 1045 /* used to allow NonTerminal but it caused problems 1046 when a rule name immediately followed a #pred statement */ 1047 1048 TokenTerm <<name=mystrdup(LATEXT(1));>> 1049 1050 << 1051 /* don't free - referenced in predicates */ 1052 1053 CurPredName=(char *)calloc(1,strlen(name) + 10); 1054 strcat(CurPredName,"#pred "); 1055 strcat(CurPredName,name); 1056 1057 predEntry=(PredEntry *) hash_get(Pname,name); 1058 if (predEntry != NULL) { 1059 warnFL(eMsg1("#pred %s previously defined - ignored",name), 1060 FileStr[action_file],action_line); 1061 name=NULL; 1062 }; 1063 >> 1064 1065 ( 1066 1067 Pred <<predLiteral=mystrdup(LATEXT(1)); 1068 save_line=action_line; 1069 save_file=action_file; 1070 >> 1071 1072 { 1073 predOrExpr>[predExpr] <<predExprPresent=1;>> 1074 } 1075 1076 <<if (predLiteral != NULL && name != NULL) { 1077 1078 /* 1079 * predExpr may be NULL due to syntax errors 1080 * or simply omitted by the user 1081 */ 1082 1083 predEntry=newPredEntry(name); 1084 predEntry->file=save_file; 1085 predEntry->line=save_line; 1086 predExpr=MR_predFlatten(predExpr); 1087 predEntry->predLiteral=predLiteral; 1088 if (! predExprPresent || predExpr == NULL) { 1089 predExpr=new_pred(); 1090 predExpr->expr=predLiteral; 1091 predExpr->source=newActionNode(); 1092 predExpr->source->action=predExpr->expr; 1093 predExpr->source->rname=CurPredName; 1094 predExpr->source->line=action_line; 1095 predExpr->source->file=action_file; 1096 predExpr->source->is_predicate=1; 1097 predExpr->k=predicateLookaheadDepth(predExpr->source); 1098 }; 1099 predEntry->pred=predExpr; 1100 hash_add(Pname,name,(Entry *)predEntry); 1101 predExpr=NULL; 1102 }; 1103 predicate_free(predExpr); 1104 >> 1105 1106 | 1107 <<save_line=zzline; save_file=CurFile;>> 1108 1109 predOrExpr>[predExpr] 1110 1111 <<if (predExpr != NULL && name != NULL) { 1112 predEntry=newPredEntry(name); 1113 predEntry->file=CurFile; 1114 predEntry->line=zzline; 1115 predExpr=MR_predFlatten(predExpr); 1116 predEntry->pred=predExpr; 1117 hash_add(Pname,name,(Entry *)predEntry); 1118 predExpr=NULL; 1119 }; 1120 predicate_free(predExpr); 1121 >> 1122 ) 1123 {";"} 1124; 1125 1126/* fail */ 1127 1128<<predicate_free(predExpr); 1129>> 1130 1131/* rule predOrExpr */ 1132 1133predOrExpr>[Predicate *result] : 1134 <<Predicate *ORnode; 1135 Predicate *predExpr; 1136 Predicate **tail=NULL; 1137 >> 1138 predAndExpr>[predExpr] 1139 << 1140 ORnode=new_pred(); 1141 ORnode->expr=PRED_OR_LIST; 1142 if (predExpr != NULL) { 1143 ORnode->down=predExpr; 1144 tail=&predExpr->right; 1145 }; 1146 >> 1147 ( "\|\|" predAndExpr>[predExpr] 1148 << 1149 if (predExpr != NULL) { 1150 *tail=predExpr; 1151 tail=&predExpr->right; 1152 }; 1153 >> 1154 )* 1155 << 1156 $result=ORnode; 1157 ORnode=NULL; 1158 >> 1159; 1160 1161/* fail */ 1162 1163<<predicate_free(ORnode);>> 1164 1165/* rule predAndExpr */ 1166 1167predAndExpr>[Predicate *result] : 1168 <<Predicate *ANDnode; 1169 Predicate *predExpr; 1170 Predicate **tail=NULL; 1171 >> 1172 predPrimary>[predExpr] 1173 << 1174 ANDnode=new_pred(); 1175 ANDnode->expr=PRED_AND_LIST; 1176 if (predExpr != NULL) { 1177 ANDnode->down=predExpr; 1178 tail=&predExpr->right; 1179 }; 1180 >> 1181 ( "&&" predPrimary>[predExpr] 1182 << 1183 if (predExpr != NULL) { 1184 *tail=predExpr; 1185 tail=&predExpr->right; 1186 }; 1187 >> 1188 )* 1189 << 1190 $result=ANDnode; 1191 ANDnode=NULL; 1192 >> 1193; 1194 1195/* fail */ 1196 1197<<predicate_free(ANDnode);>> 1198 1199 1200/* rule predPrimary */ 1201 1202predPrimary>[Predicate *result] : 1203 << 1204 char *name=NULL; 1205 PredEntry *predEntry=NULL; 1206 Predicate *predExpr=NULL; 1207 >> 1208 1209 TokenTerm <<name=mystrdup(LATEXT(1));>> 1210 1211 << 1212 predEntry=(PredEntry *) hash_get(Pname,name); 1213 if (predEntry == NULL) { 1214 warnFL(eMsg1("no previously defined #pred with name \"%s\"",name), 1215 FileStr[CurFile],zzline); 1216 name=NULL; 1217 $result=NULL; 1218 } else { 1219 predExpr=predicate_dup(predEntry->pred); 1220 predExpr->predEntry=predEntry; 1221 $result=predExpr; 1222 }; 1223 >> 1224 1225 | "\(" predOrExpr>[predExpr] "\)" 1226 << 1227 $result=predExpr; 1228 >> 1229 1230 | "!" predPrimary>[predExpr] 1231 << 1232 predExpr->inverted=!predExpr->inverted; 1233 $result=predExpr; 1234 >> 1235; 1236 1237/* fail */ << 1238 predicate_free(predExpr); 1239 >> 1240 1241/* rule aLexclass */ 1242 1243aLexclass: "{\\}#lexclass" TokenTerm <<lexclass(mystrdup(LATEXT(1)));>> 1244 ; 1245 <<CannotContinue=TRUE;>> 1246 1247/* rule error */ 1248 1249error : <<char *t=NULL; ECnode *e; int go=1; TermEntry *p;>> 1250 "{\\}#errclass" 1251 (<<;>> TokenTerm <<t=mystrdup(LATEXT(1));>> 1252 | QuotedTerm <<t=mystrdup(LATEXT(1));>> 1253 ) 1254 <<e = newECnode; 1255 require(e!=NULL, "cannot allocate error class node"); 1256 e->lexclass = CurrentLexClass; 1257 if ( Tnum( (t=StripQuotes(t)) ) == 0 ) 1258 { 1259 if ( hash_get(Texpr, t) != NULL ) 1260 warn(eMsg1("errclass name conflicts with regular expression '%s'",t)); 1261 e->tok = addTname( t ); 1262 set_orel(e->tok, &imag_tokens); 1263 require((p=(TermEntry *)hash_get(Tname, t)) != NULL, 1264 "hash table mechanism is broken"); 1265 p->classname = 1; /* entry is errclass name, not token */ 1266 list_add(&eclasses, (char *)e); 1267 } 1268 else 1269 { 1270 warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t)); 1271 free( (char *)e ); 1272 go=0; 1273 } 1274 >> 1275 "\{" 1276 ( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>> 1277 | TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>> 1278 | QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>> 1279 ) 1280 <<if ( go ) list_add(&(e->elist), t);>> 1281 ( 1282 ( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>> 1283 | TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>> 1284 | QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>> 1285 ) 1286 <<if ( go ) list_add(&(e->elist), t);>> 1287 )* 1288 "\}" 1289 ; 1290 <<CannotContinue=TRUE;>> 1291 1292/* rule tclass */ 1293 1294tclass : <<char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm;>> 1295 <<char *akaString=NULL; int save_file; int save_line;>> 1296 <<char *totext=NULL; >> 1297 "{\\}#tokclass" TokenTerm <<t=mystrdup(LATEXT(1));>> 1298 <<e = newTCnode; 1299 require(e!=NULL, "cannot allocate token class node"); 1300 e->lexclass = CurrentLexClass; 1301 if ( Tnum( t ) == 0 ) 1302 { 1303 e->tok = addTname( t ); 1304 set_orel(e->tok, &imag_tokens); 1305 set_orel(e->tok, &tokclasses); 1306 require((p=(TermEntry *)hash_get(Tname, t)) != NULL, 1307 "hash table mechanism is broken"); 1308 p->classname = 1; /* entry is class name, not token */ 1309 p->tclass = e; /* save ptr to this tclass def */ 1310 list_add(&tclasses, (char *)e); 1311 } 1312 else 1313 { 1314 warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t)); 1315 free( (char *)e ); 1316 go=0; 1317 } 1318 >> 1319/* MR23 */ { 1320/* MR23 */ "\(" 1321/* MR23 */ QuotedTerm 1322/* MR23 */ <<akaString=mystrdup(StripQuotes(LATEXT(1))); 1323/* MR11 */ save_file=CurFile;save_line=zzline; 1324/* MR23 */ >> 1325/* MR23 */ "\)" 1326/* MR23 */ } 1327/* MR23 */ 1328/* MR23 */ 1329/* MR23 */ << 1330/* MR23 */ if (p!= NULL && akaString != NULL) { 1331/* MR23 */ if (p->akaString != NULL) { 1332/* MR23 */ if (strcmp(p->akaString,akaString) != 0) { 1333/* MR23 */ warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement", 1334/* MR23 */ t,p->akaString), 1335/* MR23 */ FileStr[save_file],save_line); 1336/* MR23 */ }; 1337/* MR23 */ } else { 1338/* MR23 */ p->akaString=akaString; 1339/* MR23 */ }; 1340/* MR23 */ }; 1341/* MR23 */ >> 1342 1343 "\{" 1344 ( 1345 ( TokenTerm 1346 <<if ( go ) { 1347 term = (TermEntry *) hash_get(Tname, LATEXT(1)); 1348 if ( term==NULL && UserDefdTokens ) { 1349 err("implicit token definition not allowed with #tokdefs"); 1350 go = 0; 1351 } 1352 else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));} 1353 }>> 1354 1355 { 1356 ".." 1357 TokenTerm 1358 1359 <<if ( go ) { 1360 toterm = (TermEntry *) hash_get(Tname, LATEXT(1)); 1361 if ( toterm==NULL && UserDefdTokens ) { 1362 err("implicit token definition not allowed with #tokdefs"); 1363 go = 0; 1364 } else { 1365 totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1)); 1366 } 1367 } 1368 >> 1369 } 1370 1371 | QuotedTerm 1372 <<if ( go ) { 1373 term = (TermEntry *) hash_get(Texpr, LATEXT(1)); 1374 if ( term==NULL && UserDefdTokens ) { 1375 err("implicit token definition not allowed with #tokdefs"); 1376 go = 0; 1377 } 1378 else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));} 1379 }>> 1380 ) 1381 <<if ( go ) { 1382 if (totext == NULL) { 1383 list_add(&(e->tlist), t); 1384 } else { 1385 list_add(&(e->tlist),".."); 1386 list_add(&(e->tlist),t); 1387 list_add(&(e->tlist),totext); 1388 } 1389 totext=NULL; 1390 } 1391 >> 1392 )+ // MR15 Manfred Kogler - forbid empty #tokclass sets (was "+") 1393 "\}" 1394 ; 1395 <<CannotContinue=TRUE;>> 1396 1397/* rule token */ 1398 1399token : <<char *t=NULL, *e=NULL, *a=NULL; int tnum=0;>> 1400 <<char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0;>> /* MR11 */ 1401 "{\\}#token" 1402 1403/* MR1 10-Apr-97 MR1 Allow shift right operator in DLG actions */ 1404/* MR1 Danger when parser feedback to lexer */ 1405/* MR1 */ 1406 1407 <<tokenActionActive=1;>> /* MR1 */ 1408 { TokenTerm <<t=mystrdup(LATEXT(1));>> 1409 1410/* MR11 */ { 1411/* MR11 */ "\(" 1412/* MR11 */ QuotedTerm 1413/* MR11 */ <<akaString=mystrdup(StripQuotes(LATEXT(1))); 1414/* MR11 */ save_file=CurFile;save_line=zzline; 1415/* MR11 */ >> 1416/* MR11 */ "\)" 1417/* MR11 */ } 1418 1419 { "=" "[0-9]+" /* define the token type number */ 1420 <<tnum = atoi(LATEXT(1));>> 1421 } 1422 } 1423 { QuotedTerm <<e=mystrdup(LATEXT(1));>> } 1424 { Action 1425 << 1426 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 1427 require(a!=NULL, "rule token: cannot allocate action"); 1428 strcpy(a, LATEXT(1)); 1429 >> 1430 } 1431 1432 { ";" } /* MR11 */ 1433 1434 <<chkToken(t, e, a, tnum);>> 1435 1436 <<if (t != NULL) { 1437 te=(TermEntry *)hash_get(Tname,t); 1438 if (te != NULL && akaString != NULL) { 1439 if (te->akaString != NULL) { 1440 if (strcmp(te->akaString,akaString) != 0) { 1441 warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement", 1442 t,te->akaString), 1443 FileStr[save_file],save_line); 1444 }; 1445 } else { 1446 te->akaString=akaString; 1447 }; 1448 }; 1449 }; 1450 >> 1451 ; 1452 <<CannotContinue=TRUE;>> 1453 1454/* rule block */ 1455 1456block[set *toksrefd, set *rulesrefd] 1457 : << 1458 Graph g, b; 1459 set saveblah; 1460 int saveinalt = inAlt; 1461 ExceptionGroup *eg; 1462 *$toksrefd = empty; 1463 *$rulesrefd = empty; 1464 set_clr(AST_nodes_refd_in_actions); 1465 CurBlockID++; 1466/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; 1467 CurAltNum = 1; 1468/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; 1469 saveblah = attribsRefdFromAction; 1470 attribsRefdFromAction = empty; 1471 >> 1472 1473 alt[toksrefd,rulesrefd] <<b = g = $1;>> 1474 1475 << 1476 if ( ((Junction *)g.left)->p1->ntype == nAction ) 1477 { 1478 ActionNode *actionNode=(ActionNode *) 1479 ( ( (Junction *)g.left) ->p1); 1480 if (!actionNode->is_predicate ) 1481 { 1482 actionNode->init_action = TRUE; 1483/* MR12c */ if (actionNode->noHoist) { 1484/* MR12c */ errFL("<<nohoist>> appears as init-action - use <<>> <<nohoist>>", 1485/* MR12c */ FileStr[actionNode->file],actionNode->line); 1486/* MR12c */ }; 1487 } 1488 } 1489 ((Junction *)g.left)->blockid = CurBlockID; 1490 >> 1491 1492 ( exception_group > [eg] 1493 << 1494 if ( eg!=NULL ) { 1495/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ 1496/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ 1497 list_add(&CurExGroups, (void *)eg); 1498 } 1499 >> 1500 )* 1501 <<CurAltNum++; 1502/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; 1503 >> 1504 1505 ( "\|" <<inAlt=1;>> 1506 alt[toksrefd,rulesrefd] <<g = Or(g, $2);>> 1507 << 1508 ((Junction *)g.left)->blockid = CurBlockID; 1509 >> 1510 1511 ( exception_group > [eg] 1512 << 1513 if ( eg!=NULL ) { 1514/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ 1515/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ 1516 list_add(&CurExGroups, (void *)eg); 1517 } 1518 >> 1519 )* 1520 1521 <<CurAltNum++; 1522/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; 1523 >> 1524 1525 )* 1526 <<$0 = b;>> 1527 <<attribsRefdFromAction = saveblah; inAlt = saveinalt;>> 1528 ; 1529 <<CannotContinue=TRUE;>> 1530 1531/* rule alt */ 1532 1533alt[set *toksrefd, set *rulesrefd] 1534 : <<int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif; 1535 int first_on_line = 1, use_def_MT_handler = 0; 1536 g.left=NULL; g.right=NULL; 1537 1538 CurAltStart = NULL; 1539 elems = empty; 1540 inAlt = 1; 1541 >> 1542 { "\@" /* handle MismatchedToken signals with default handler */ 1543 <<use_def_MT_handler = 1;>> 1544 } 1545 1546 ( <<;>> /* MR9 Removed unreferenced variable "tok" */ 1547 { <<old_not=0;>> "\~" <<old_not=1;>> } 1548 element[old_not, first_on_line, use_def_MT_handler] > [node] 1549 <<if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0;>> 1550 << 1551 if ( $2.left!=NULL ) { 1552 g = Cat(g, $2); 1553 n++; 1554 if ( node!=NULL ) { 1555 if ( node->ntype!=nAction ) e_num++; 1556 /* record record number of all rule and token refs */ 1557 if ( node->ntype==nToken ) { 1558 TokNode *tk = (TokNode *)((Junction *)$2.left)->p1; 1559 tk->elnum = e_num; 1560 set_orel(e_num, &elems); 1561 } 1562 else if ( node->ntype==nRuleRef ) { 1563 RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1; 1564 rn->elnum = e_num; 1565 set_orel(e_num, $rulesrefd); 1566 } 1567 } 1568 } 1569 >> 1570 )* 1571 <<if ( n == 0 ) g = emptyAlt(); 1572 $0 = g; 1573 /* We want to reduce number of LT(i) calls and the number of 1574 * local attribute variables in C++ mode (for moment, later we'll 1575 * do for C also). However, if trees are being built, they 1576 * require most of the attrib variables to create the tree nodes 1577 * with; therefore, we gen a token ptr for each token ref in C++ 1578 */ 1579 if ( GenCC && !GenAST ) 1580 { 1581 /* This now free's the temp set -ATG 5/6/95 */ 1582 set temp; 1583 temp = set_and(elems, attribsRefdFromAction); 1584 set_orin($toksrefd, temp); 1585 set_free(temp); 1586 } 1587 else set_orin($toksrefd, elems); 1588 if ( GenCC ) { 1589 dif = set_dif(attribsRefdFromAction, elems); 1590 if ( set_deg(dif)>0 ) 1591 err("one or more $i in action(s) refer to non-token elements"); 1592 set_free(dif); 1593 } 1594 set_free(elems); 1595 set_free(attribsRefdFromAction); 1596 inAlt = 0; 1597 >> 1598 ; 1599 <<CannotContinue=TRUE;>> 1600 1601/* rule element_label */ 1602 1603element_label > [LabelEntry *label] 1604 : <<TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab;>> 1605 LABEL <<lab = mystrdup(LATEXT(1));>> 1606 << 1607 UsedNewStyleLabel = 1; 1608 if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i"); 1609 t = (TermEntry *) hash_get(Tname, lab); 1610 if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab); 1611 if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab); 1612 if ( t!=NULL ) { 1613 err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab)); 1614 $label = NULL; 1615 } 1616 else if ( r!=NULL ) { 1617 err(eMsg1("label definition clashes with rule definition: '%s'", lab)); 1618 $label = NULL; 1619 } 1620 else { 1621 /* we don't clash with anybody else */ 1622 l = (LabelEntry *) hash_get(Elabel, lab); 1623 if ( l==NULL ) { /* ok to add new element label */ 1624 l = (LabelEntry *)hash_add(Elabel, 1625 lab, 1626 (Entry *)newLabelEntry(lab)); 1627 /* add to list of element labels for this rule */ 1628 list_add(&CurElementLabels, (void *)lab); 1629/* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */ 1630 $label = l; 1631 } 1632 else { 1633 err(eMsg1("label definitions must be unique per rule: '%s'", lab)); 1634 $label = NULL; 1635 } 1636 } 1637 >> 1638 ":" 1639 ; 1640 1641/* rule element */ 1642 1643element[int old_not, int first_on_line, int use_def_MT_handler] > [Node *node] 1644 : << 1645 Attrib blk; 1646 Predicate *pred = NULL; 1647 int local_use_def_MT_handler=0; 1648 ActionNode *act; 1649 RuleRefNode *rr; 1650 set toksrefd, rulesrefd; 1651 TermEntry *term; 1652 TokNode *p=NULL; RuleRefNode *q; int approx=0; 1653 LabelEntry *label=NULL; 1654 int predMsgDone=0; 1655 int semDepth=0; 1656 int ampersandStyle; 1657 int height; /* MR11 */ 1658 int equal_height; /* MR11 */ 1659 1660 char* pFirstSetSymbol = NULL; /* MR21 */ 1661 1662 $node = NULL; 1663 >> 1664 {element_label>[label]} 1665 ( TokenTerm 1666 << 1667 term = (TermEntry *) hash_get(Tname, LATEXT(1)); 1668 if ( term==NULL && UserDefdTokens ) { 1669 err("implicit token definition not allowed with #tokdefs"); 1670 $$.left = $$.right = NULL; 1671 } 1672 else { 1673 $$ = buildToken(LATEXT(1)); 1674 p=((TokNode *)((Junction *)$$.left)->p1); 1675 term = (TermEntry *) hash_get(Tname, LATEXT(1)); 1676 require( term!= NULL, "hash table mechanism is broken"); 1677 p->tclass = term->tclass; 1678 p->complement = $old_not; 1679 if ( label!=NULL ) { 1680 p->el_label = label->str; 1681 label->elem = (Node *)p; 1682 } 1683 } 1684 >> 1685 { ".." 1686 ( QuotedTerm 1687 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>> 1688 | TokenTerm 1689 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>> 1690 ) 1691 } 1692 << 1693 if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) ) 1694 list_add(&MetaTokenNodes, (void *)p); 1695 >> 1696 ( "^" <<if ( p!=NULL ) p->astnode=ASTroot;>> 1697 | <<if ( p!=NULL ) p->astnode=ASTchild;>> 1698 | "!" <<if ( p!=NULL ) p->astnode=ASTexclude;>> 1699 ) 1700 { "\@" <<local_use_def_MT_handler = 1;>> } 1701 << 1702 if ( p!=NULL && $first_on_line ) { 1703 CurAltStart = (Junction *)$$.left; 1704 altAdd(CurAltStart); /* MR7 */ 1705 p->altstart = CurAltStart; 1706 } 1707 if ( p!=NULL ) 1708 p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; 1709 $node = (Node *)p; 1710 >> 1711 | QuotedTerm 1712 << 1713 term = (TermEntry *) hash_get(Texpr, LATEXT(1)); 1714 if ( term==NULL && UserDefdTokens ) { 1715 err("implicit token definition not allowed with #tokdefs"); 1716 $$.left = $$.right = NULL; 1717 } 1718 else { 1719 $$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1); 1720 p->complement = $old_not; 1721 if ( label!=NULL ) { 1722 p->el_label = label->str; 1723 label->elem = (Node *)p; 1724 } 1725 } 1726 >> 1727 { ".." 1728 ( QuotedTerm 1729 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>> 1730 | TokenTerm 1731 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>> 1732 ) 1733 } 1734 ( "^" <<if ( p!=NULL ) p->astnode=ASTroot;>> 1735 | <<if ( p!=NULL ) p->astnode=ASTchild;>> 1736 | "!" <<if ( p!=NULL ) p->astnode=ASTexclude;>> 1737 ) 1738 { "\@" <<local_use_def_MT_handler = 1;>> } 1739 << 1740 if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) ) 1741 list_add(&MetaTokenNodes, (void *)p); 1742 >> 1743 << 1744 if ( $first_on_line ) { 1745 CurAltStart = (Junction *)$$.left; 1746 altAdd(CurAltStart); /* MR7 */ 1747 p->altstart = CurAltStart; 1748 } 1749 if ( p!=NULL ) 1750 p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; 1751 $node = (Node *)p; 1752 >> 1753 1754 | <<if ( $old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')");>> 1755 "." 1756 <<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>> 1757 ( "^" <<p->astnode=ASTroot;>> 1758 | <<p->astnode=ASTchild;>> 1759 | "!" <<p->astnode=ASTexclude;>> 1760 ) 1761 <<list_add(&MetaTokenNodes, (void *)p);>> 1762 << 1763 if ( $first_on_line ) { 1764 CurAltStart = (Junction *)$$.left; 1765 altAdd(CurAltStart); /* MR7 */ 1766 p->altstart = CurAltStart; 1767 if ( label!=NULL ) { 1768 p->el_label = label->str; 1769 label->elem = (Node *)p; 1770 } 1771 } 1772 $node = (Node *)p; 1773 >> 1774 1775 | <<if ( $old_not ) warn("~ NONTERMINAL is an undefined operation");>> 1776 NonTerminal 1777 <<$$ = buildRuleRef(LATEXT(1));>> 1778 { "!" <<q = (RuleRefNode *) ((Junction *)$$.left)->p1; 1779 q->astnode=ASTexclude;>> 1780 } 1781 { {"\<"} 1782 PassAction <<addParm(((Junction *)$$.left)->p1, LATEXT(1));>> 1783 } 1784 <<rr=(RuleRefNode *) ((Junction *)$$.left)->p1;>> 1785 { <<char *a;>> 1786 "\>" 1787 PassAction 1788 << 1789 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 1790 require(a!=NULL, "rule element: cannot allocate assignment"); 1791 strcpy(a, LATEXT(1)); 1792 rr->assign = a; 1793 >> 1794 } 1795 << 1796 if ( label!=NULL ) { 1797 rr->el_label = label->str; 1798 label->elem = (Node *)rr; 1799 } 1800 if ( $first_on_line ) { 1801 CurAltStart = (Junction *)$$.left; 1802 altAdd(CurAltStart); /* MR7 */ 1803 ((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart; 1804 } 1805 $node = (Node *)rr; 1806 >> 1807 ) 1808 1809 | <<if ( $old_not ) warn("~ ACTION is an undefined operation");>> 1810 Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>> 1811 <<if ( $first_on_line ) { /* MR7 */ 1812 CurAltStart = (Junction *)$0.left; /* MR7 */ 1813 altAdd(CurAltStart); /* MR7 */ 1814 };>> /* MR7 */ 1815 <<$node = (Node *) ((Junction *)$0.left)->p1;>> 1816 1817 | <<if ( $old_not ) warn("~ SEMANTIC-PREDICATE is an undefined operation");>> 1818 Pred <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>> 1819 <<act = (ActionNode *) ((Junction *)$0.left)->p1;>> 1820 <<if (numericActionLabel) { /* MR10 */ 1821 list_add(&NumericPredLabels,act); /* MR10 */ 1822 numericActionLabel=0; /* MR10 */ 1823 }; /* MR10 */ 1824 >> 1825 { <<char *a;>> 1826 PassAction 1827 << 1828 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 1829 require(a!=NULL, "rule element: cannot allocate predicate fail action"); 1830 strcpy(a, LATEXT(1)); 1831 act->pred_fail = a; 1832 >> 1833 } 1834 <<if ( $first_on_line ) { /* MR7 */ 1835 CurAltStart = (Junction *)$0.left; /* MR7 */ 1836 altAdd(CurAltStart); /* MR7 */ 1837 };>> /* MR7 */ 1838 <<$node = (Node *)act;>> 1839 1840 | <<if ( $old_not ) warn("~ BLOCK is an undefined operation");>> 1841 <<BlkLevel++; 1842 if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); 1843/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; 1844/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; 1845 >> 1846 { Pragma 1847 ( "approx" <<approx=LL_k;>> 1848 | "LL\(1\)" <<approx = 1;>> /* MR20 */ 1849 | "LL\(2\)" <<approx = 2;>> /* MR20 */ 1850 ) 1851 } 1852 1853/* MR21 */ { FirstSetSymbol 1854/* MR21 */ "\(" 1855/* MR21 */ ( NonTerminal 1856/* MR21 */ << 1857/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, 1858/* MR21 */ sizeof(char)); 1859/* MR21 */ require(pFirstSetSymbol!=NULL, 1860/* MR21 */ "cannot allocate first set name"); 1861/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); 1862/* MR21 */ >> 1863/* MR21 */ | TokenTerm 1864/* MR21 */ << 1865/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, 1866/* MR21 */ sizeof(char)); 1867/* MR21 */ require(pFirstSetSymbol!=NULL, 1868/* MR21 */ "cannot allocate first set name"); 1869/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); 1870/* MR21 */ >> 1871/* MR21 */ ) 1872/* MR21 */ "\)" 1873/* MR21 */ } 1874 1875 ( 1876 1877 "\(" block[&toksrefd,&rulesrefd] "\)" 1878 <<blk = $$ = $2; 1879 /* MR23 */ CurBlockID_array[BlkLevel] = (-1); 1880 /* MR23 */ CurAltNum_array[BlkLevel] = (-1); 1881 --BlkLevel; 1882 >> 1883 1884 ( "\*" <<$$ = makeLoop($$,approx,pFirstSetSymbol);>> 1885 | "\+" <<$$ = makePlus($$,approx,pFirstSetSymbol);>> 1886 | "?" 1887 ( 1888 ( "=>" <<ampersandStyle=0;>> 1889 | "&&" <<ampersandStyle=1;>> /* MR10 (g)? && <<p>>? */ 1890 ) 1891 Pred /* generalized predicate */ 1892 /* first make into a predicate */ 1893 <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>> 1894 <<act = (ActionNode *) ((Junction *)$$.left)->p1;>> 1895 <<semDepth=predicateLookaheadDepth(act);>> /* MR10 */ 1896 <<if (numericActionLabel) { /* MR10 */ 1897 list_add(&NumericPredLabels,act); /* MR10 */ 1898 numericActionLabel=0; /* MR10 */ 1899 }; /* MR10 */ 1900 >> 1901 { <<char *a;>> 1902 PassAction 1903 << 1904 a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char)); 1905 require(a!=NULL, "rule element: cannot allocate predicate fail action"); 1906 strcpy(a, LATEXT(1)); 1907 act->pred_fail = a; 1908 >> 1909 } 1910 <<if ($first_on_line) { /* MR7 */ 1911 CurAltStart=(Junction *)$$.left; /* MR7 */ 1912 altAdd(CurAltStart); /* MR7 */ 1913 };>> 1914 <<$node = (Node *)act;>> 1915 1916 /* for now, just snag context */ 1917 << 1918 pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */ 1919 if ( pred==NULL) { /* MR10 */ 1920 if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */ 1921 predMsgDone=1; /* MR10 */ 1922 } else { /* MR10 */ 1923 act->guardNodes=(Junction *)blk.left; /* MR11 */ 1924 pred->expr = act->action; 1925 pred->source = act; 1926/* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */ 1927/* MR13 */ if (pred->tcontext != NULL) { 1928/* MR13 */ height=MR_max_height_of_tree(pred->tcontext); 1929/* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height); 1930/* MR13 */ if (! equal_height) { 1931/* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height", 1932/* MR13 */ FileStr[act->file],act->line); 1933/* MR13 */ }; 1934/* MR13 */ } 1935/* MR10 */ if (ampersandStyle) { 1936/* MR10 */ act->ampersandPred = pred; 1937/* MR11 */ if (! HoistPredicateContext) { 1938/* MR11 */ errFL("without \"-prc on\" (guard)? && <<pred>>? ... doesn't make sense", 1939/* MR11 */ FileStr[act->file],act->line); 1940/* MR11 */ }; 1941/* MR10 */ } else { 1942/* MR10 */ act->guardpred = pred; 1943/* MR10 */ }; 1944/* MR10 */ if (pred->k != semDepth) { 1945/* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)", 1946/* MR10 */ pred->k,semDepth)); 1947/* MR10 */ }; 1948 } 1949 >> 1950 | <<$$ = makeBlk($$,approx,pFirstSetSymbol); 1951 FoundGuessBlk = 1; 1952 ((Junction *) ((Junction *)$$.left)->p1)->guess=1; 1953 if ( !$first_on_line ) { 1954 err("(...)? predicate must be first element of production"); 1955 } 1956 >> 1957 ) 1958 | <<$$ = makeBlk($$,approx,pFirstSetSymbol);>> 1959 ) 1960 << 1961 if ( pred==NULL && !predMsgDone) { /* MR10 */ 1962 ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; 1963 ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; 1964 ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; 1965 if ( $first_on_line ) { /* MR7 */ 1966 CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1); /* MR7 */ 1967 altAdd(CurAltStart); /* MR7 */ 1968 }; /* MR7 */ 1969 $node = (Node *) ((Junction *)$$.left)->p1; 1970 } 1971 >> 1972 1973 | "\{" block[&toksrefd,&rulesrefd] 1974 <<$$ = makeOpt($2,approx,pFirstSetSymbol); 1975 /* MR23 */ CurBlockID_array[BlkLevel] = (-1); 1976 /* MR23 */ CurAltNum_array[BlkLevel] = (-1); 1977 --BlkLevel; 1978 >> 1979 "\}" 1980 << 1981 ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; 1982 ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; 1983 ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; 1984 >> 1985 <<if ( $first_on_line ) { /* MR7 */ 1986 CurAltStart = (Junction *) ((Junction *)((Junction *)$$.left)->p1); /* MR7 */ 1987 altAdd(CurAltStart); /* MR7 */ 1988 }; 1989 >> 1990 <<$node = (Node *) ((Junction *)$$.left)->p1;>> 1991 1992 ) 1993 1994/* Error catching alternatives */ 1995 | "\*" <<warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE;>> 1996 | "\+" <<warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE;>> 1997 | "\>" <<warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE;>> 1998 | PassAction <<warn("[...] out of context 'rule > [...]'"); 1999 CannotContinue=TRUE;>> 2000 ; 2001 <<CannotContinue=TRUE;>> 2002 2003/* rule default_exception_handler */ 2004 2005default_exception_handler 2006 : exception_group > [DefaultExGroup] 2007 ; 2008 2009/* rule exception_group */ 2010 2011exception_group > [ExceptionGroup *eg] 2012 : <<ExceptionHandler *h; LabelEntry *label=NULL; /* MR6 */ 2013 FoundException = 1; FoundExceptionGroup = 1;>> /* MR6 */ 2014 2015 "exception" <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>> 2016 { <<char *p;>> 2017 PassAction /* did they attach a label? */ 2018 << 2019 p = LATEXT(1)+1; 2020 p[strlen(p)-1] = '\0'; /* kill trailing space */ 2021 label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1); 2022 if ( label==NULL ) 2023 { 2024 err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1)); 2025 } 2026 >> 2027 } 2028 ( exception_handler > [h] 2029 <<list_add(&($eg->handlers), (void *)h);>> 2030 )* 2031 { "default" ":" Action 2032 <<{ 2033 ExceptionHandler *eh = (ExceptionHandler *) 2034 calloc(1, sizeof(ExceptionHandler)); 2035 char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 2036 require(eh!=NULL, "exception: cannot allocate handler"); 2037 require(a!=NULL, "exception: cannot allocate action"); 2038 strcpy(a, LATEXT(1)); 2039 eh->action = a; 2040 eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char)); 2041 require(eh->signalname!=NULL, "exception: cannot allocate sig name"); 2042 strcpy(eh->signalname, "default"); 2043 list_add(&($eg->handlers), (void *)eh); 2044 }>> 2045 } 2046 2047 << 2048 if ( label!=NULL ) { 2049 /* Record ex group in sym tab for this label */ 2050 if ( label->ex_group!=NULL ) { 2051 err(eMsg1("duplicate exception handler for label '%s'",label->str)); 2052 } else { 2053 label->ex_group = $eg; 2054 /* Label the exception group itself */ 2055 $eg->label = label->str; 2056 /* Make the labelled element pt to the exception also */ 2057/* MR6 */ if (label->elem == NULL) { 2058/* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str)); 2059/* MR6 */ } else { 2060 switch ( label->elem->ntype ) { 2061 case nRuleRef : 2062 { 2063 RuleRefNode *r = (RuleRefNode *)label->elem; 2064 r->ex_group = $eg; 2065 break; 2066 } 2067 case nToken : 2068 { 2069 TokNode *t = (TokNode *)label->elem; 2070 t->ex_group = $eg; 2071 break; 2072 } 2073 } /* end switch */ 2074/* MR6 */ }; /* end test on label->elem */ 2075 } /* end test on label->ex_group */ 2076 2077 } /* end test on exception label */ 2078 2079/* MR7 */ 2080/* MR7 */ if (BlkLevel == 1 && label == NULL) { 2081/* MR7 */ $eg->forRule=1; 2082/* MR7 */ } else if (label == NULL) { 2083/* MR7 */ $eg->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]); 2084/* MR7 */ egAdd($eg); 2085/* MR7 */ } else { 2086/* MR7 */ $eg->labelEntry=label; 2087/* MR7 */ }; 2088/* MR7 */ 2089/* MR7 */ /* You may want to remove this exc from the rule list */ 2090/* MR7 */ /* and handle at the labeled element site. */ 2091/* MR7 */ 2092/* MR7 */ if (label != NULL) { 2093/* MR7 */ $eg = NULL; 2094/* MR7 */ }; 2095 2096 >> 2097 ; 2098 <<CannotContinue=TRUE;>> 2099 2100/* rule exception_handler */ 2101 2102exception_handler > [ExceptionHandler *eh] 2103 : <<;>> /* MR9 Removed unreferenced variable "a" */ 2104 "catch" 2105 << 2106 $eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler)); 2107 require($eh!=NULL, "exception: cannot allocate handler"); 2108 >> 2109 ( NonTerminal 2110 << 2111 $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 2112 require($eh->signalname!=NULL, "exception: cannot allocate sig name"); 2113 strcpy($eh->signalname, LATEXT(1)); 2114 >> 2115 | TokenTerm 2116 << 2117 $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 2118 require($eh->signalname!=NULL, "exception: cannot allocate sig name"); 2119 strcpy($eh->signalname, LATEXT(1)); 2120 >> 2121 ) 2122 ":" 2123 { <<$eh->action = NULL;>> 2124 Action 2125 << 2126 $eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); 2127 require($eh->action!=NULL, "exception: cannot allocate action"); 2128 strcpy($eh->action, LATEXT(1)); 2129 >> 2130 } 2131 ; 2132 <<CannotContinue=TRUE;>> 2133 2134#token NonTerminal "[a-z] [A-Za-z0-9_]*" 2135 << 2136 while ( zzchar==' ' || zzchar=='\t' ) { 2137 zzadvance(); 2138 } 2139 if ( zzchar == ':' && inAlt ) NLA = LABEL; 2140 >> 2141#token TokenTerm "[A-Z] [A-Za-z0-9_]*" 2142 << 2143 while ( zzchar==' ' || zzchar=='\t' ) { 2144 zzadvance(); 2145 } 2146 if ( zzchar == ':' && inAlt ) NLA = LABEL; 2147 >> 2148#token "{\\}#[A-Za-z0-9_]*" <<warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); >> 2149 2150#lexclass PARSE_ENUM_FILE 2151 2152#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ 2153#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */ 2154#token "//" << zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >> 2155#token "/\*" << zzmode(TOK_DEF_COMMENTS); zzskip(); >> 2156#token "#ifdef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> 2157#token "#if" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> 2158#token "#ifndef" << ; >> 2159#token "#else" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> 2160#token "#endif" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> 2161#token "#undef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> 2162#token "#import" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> 2163#token "@" << ; >> 2164 2165/* rule enum_file */ 2166 2167enum_file[char *fname] 2168 : { "#ifndef" ID 2169 { "#define" ID /* ignore if it smells like a gate */ 2170 /* First #define after the first #ifndef (if any) is ignored */ 2171 } 2172 } 2173 ( ( enum_def[$fname] )+ 2174 | defines[$fname] 2175 ) 2176 | 2177 ; 2178 2179/* rule defines */ 2180 2181defines[char *fname] 2182 : <<int v; int maxt=(-1); char *t;>> /* MR3 */ 2183 ( 2184 "#define" ID 2185 <<t = mystrdup(LATEXT(1));>> 2186 INT 2187 << 2188 v = atoi(LATEXT(1)); 2189/* fprintf(stderr, "#token %s=%d\n", t, v);*/ 2190 2191 /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ 2192 /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ 2193 /* MR2 Don't let #tokdefs be confused by */ 2194 /* MR2 DLGminToken and DLGmaxToken */ 2195 2196 if ( ! isDLGmaxToken(t)) { /* MR2 */ 2197 TokenNum = v; 2198 if ( v>maxt ) maxt=v; 2199 if ( Tnum( t ) == 0 ) { 2200 addForcedTname( t, v ); 2201 } else { 2202 warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); 2203 }; 2204 }; 2205 >> 2206 )+ 2207 <<TokenNum = maxt + 1;>> 2208 ; 2209 2210/* rule enum_def */ 2211 2212enum_def[char *fname] 2213 : <<int v= 0; int maxt=(-1); char *t;>> /* MR3 */ 2214 "enum" ID 2215 "\{" 2216 ID 2217 <<t = mystrdup(LATEXT(1));>> 2218 ( "=" INT <<v=atoi(LATEXT(1));>> 2219 | <<v++;>> 2220 ) 2221 << 2222/* fprintf(stderr, "#token %s=%d\n", t, v);*/ 2223 TokenNum = v; 2224 if ( v>maxt ) maxt=v; /* MR3 */ 2225 if ( Tnum( t ) == 0 ) addForcedTname( t, v ); 2226 else { 2227 warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); 2228 } 2229 >> 2230 ( "," 2231 2232 /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ 2233 /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ 2234 /* MR2 Don't let #tokdefs be confused by */ 2235 /* MR2 DLGminToken and DLGmaxToken */ 2236 2237 { 2238 <<isDLGmaxToken(LATEXT(1))>>? ID { "=" INT } /* MR2 */ 2239 | ID /* MR2 */ 2240 <<t = mystrdup(LATEXT(1));>> 2241 ( "=" INT <<v=atoi(LATEXT(1));>> 2242 | <<v++;>> 2243 ) 2244 << 2245/* fprintf(stderr, "#token %s=%d\n", t, v);*/ 2246 TokenNum = v; 2247 if ( v>maxt ) maxt=v; /* MR3 */ 2248 if ( Tnum( t ) == 0 ) addForcedTname( t, v ); 2249 else { 2250 warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); 2251 } 2252 >> 2253 } 2254 )* 2255 "\}" 2256 ";" 2257 <<TokenNum = maxt + 1;>> /* MR3 */ 2258 ; 2259 2260#token INT "[0-9]+" 2261#token ID "[a-zA-Z_][_a-zA-Z0-9]*" 2262 2263#lexclass START 2264 2265/* MR14 Arpad Beszedes 26-May-98 2266 Add support for #line directives when antlr source is pre-processed 2267*/ 2268 2269#lexaction 2270<< 2271 2272static char * 2273#ifdef __USE_PROTOS 2274getFileNameFromTheLineInfo(char *toStr, char *fromStr) 2275#else 2276getFileNameFromTheLineInfo(toStr, fromStr) 2277char *toStr, *fromStr; 2278#endif 2279{ 2280 int i, j, k; 2281 2282 if (!fromStr || !toStr) return toStr; 2283 2284 /* find the first " */ 2285 2286 for (i=0; 2287 (i<MaxFileName) && 2288 (fromStr[i] != '\n') && 2289 (fromStr[i] != '\r') && 2290 (fromStr[i] != '\"'); 2291 i++) /* nothing */ ; 2292 2293 if ( (i == MaxFileName) || 2294 (fromStr[i] == '\n') || 2295 (fromStr[i] == '\r') ) { 2296 return toStr; 2297 } 2298 2299 /* find the second " */ 2300 2301 for (j=i+1; 2302 (j<MaxFileName) && 2303 (fromStr[j] != '\n') && 2304 (fromStr[j] != '\r') && 2305 (fromStr[j] != '\"'); 2306 j++) /* nothing */ ; 2307 2308 if ((j == MaxFileName) || 2309 (fromStr[j] == '\n') || 2310 (fromStr[j] == '\r') ) { 2311 return toStr; 2312 } 2313 2314 /* go back until the last / or \ */ 2315 2316 for (k=j-1; 2317 (fromStr[k] != '\"') && 2318 (fromStr[k] != '/') && 2319 (fromStr[k] != '\\'); 2320 k--) /* nothing */ ; 2321 2322 /* copy the string after " / or \ into toStr */ 2323 2324 for (i=k+1; fromStr[i] != '\"'; i++) { 2325 toStr[i-k-1] = fromStr[i]; 2326 } 2327 2328 toStr[i-k-1] = '\0'; 2329 2330 return toStr; 2331} 2332 2333/* MR14 end of a block to support #line in antlr source code */ 2334 2335>> 2336 2337<< 2338 2339/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ 2340/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ 2341/* MR2 Don't let #tokdefs be confused by */ 2342/* MR2 DLGminToken and DLGmaxToken */ 2343 2344/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */ 2345 2346#ifdef __USE_PROTOS 2347static int isDLGmaxToken(char *Token) 2348#else 2349static int isDLGmaxToken(Token) 2350 char * Token; 2351#endif 2352{ 2353 static char checkStr1[] = "DLGmaxToken"; 2354 static char checkStr2[] = "DLGminToken"; 2355 2356 if (strcmp(Token, checkStr1) == 0) 2357 return 1; 2358 else if (strcmp(Token, checkStr2) == 0) 2359 return 1; 2360 else 2361 return 0; 2362} 2363 2364/* semantics of #token */ 2365static void 2366#ifdef __USE_PROTOS 2367chkToken(char *t, char *e, char *a, int tnum) 2368#else 2369chkToken(t,e,a,tnum) 2370char *t, *e, *a; 2371int tnum; 2372#endif 2373{ 2374 TermEntry *p; 2375 2376 /* check to see that they don't try to redefine a token as a token class */ 2377 if ( t!=NULL ) { 2378 p = (TermEntry *) hash_get(Tname, t); 2379 if ( p!=NULL && p->classname ) { 2380 err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t)); 2381 if ( a!=NULL ) free((char *)a); 2382 return; 2383 } 2384 } 2385 2386 if ( t==NULL && e==NULL ) { /* none found */ 2387 err("#token requires at least token name or rexpr"); 2388 } 2389 else if ( t!=NULL && e!=NULL ) { /* both found */ 2390 if ( UserDefdTokens ) { /* if #tokdefs, must not define new */ 2391 p = (TermEntry *) hash_get(Tname, t); 2392 if ( p == NULL) { 2393err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); 2394 return; 2395 }; 2396 } 2397 Tklink(t, e); 2398 if ( a!=NULL ) { 2399 if ( hasAction(e) ) { 2400 err(eMsg1("redefinition of action for %s; ignored",e)); 2401 } 2402 else setHasAction(e, a); 2403 } 2404 } 2405 else if ( t!=NULL ) { /* only one found */ 2406 if ( UserDefdTokens ) { 2407 p = (TermEntry *) hash_get(Tname, t); 2408 if (p == NULL) { 2409err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); 2410 }; 2411 return; 2412 } 2413 if ( Tnum( t ) == 0 ) addTname( t ); 2414 else { 2415 err(eMsg1("redefinition of token %s; ignored",t)); 2416 } 2417 if ( a!=NULL ) { 2418 err(eMsg1("action cannot be attached to a token name (%s); ignored",t)); 2419 free((char *)a); 2420 } 2421 } 2422 else if ( e!=NULL ) { 2423 if ( Tnum( e ) == 0 ) addTexpr( e ); 2424 else { 2425 if ( hasAction(e) ) { 2426 err(eMsg1("redefinition of action for expr %s; ignored",e)); 2427 } 2428 else if ( a==NULL ) { 2429 err(eMsg1("redefinition of expr %s; ignored",e)); 2430 } 2431 } 2432 if ( a!=NULL ) setHasAction(e, a); 2433 } 2434 2435 /* if a token type number was specified, then add the token ID and 'tnum' 2436 * pair to the ForcedTokens list. (only applies if an id was given) 2437 */ 2438 if ( t!=NULL && tnum>0 ) 2439 { 2440 if ( set_el(tnum, reserved_positions) ) 2441 { 2442 err(eMsgd("a token has already been forced to token number %d; ignored", tnum)); 2443 } 2444 else 2445 { 2446 list_add(&ForcedTokens, newForcedToken(t,tnum)); 2447 set_orel(tnum, &reserved_positions); 2448 } 2449 } 2450} 2451>> 2452 2453<< 2454static int 2455#ifdef __USE_PROTOS 2456match_token(char *s, char **nxt) 2457#else 2458match_token(s,nxt) 2459char *s; 2460char **nxt; 2461#endif 2462{ 2463 if ( !(*s>='A' && *s<='Z') ) return 0; 2464 s++; 2465 while ( (*s>='a' && *s<='z') || 2466 (*s>='A' && *s<='Z') || 2467 (*s>='0' && *s<='9') || 2468 *s=='_' ) 2469 { 2470 s++; 2471 } 2472 if ( *s!=' ' && *s!='}' ) return 0; 2473 *nxt = s; 2474 return 1; 2475} 2476 2477static int 2478#ifdef __USE_PROTOS 2479match_rexpr(char *s, char **nxt) 2480#else 2481match_rexpr(s,nxt) 2482char *s; 2483char **nxt; 2484#endif 2485{ 2486 if ( *s!='"' ) return 0; 2487 s++; 2488 while ( *s!='"' ) 2489 { 2490 if ( *s=='\n' || *s=='\r' ) /* MR13 */ 2491 warn("eoln found in regular expression"); 2492 if ( *s=='\\' ) s++; 2493 s++; 2494 } 2495 *nxt = s+1; 2496 return 1; 2497} 2498 2499/* 2500 * Walk a string "{ A .. Z }" where A..Z is a space separated list 2501 * of token references (either labels or reg exprs). Return a 2502 * string "inlineX_set" for some unique integer X. Basically, 2503 * we pretend as if we had seen "#tokclass inlineX { A .. Z }" 2504 * on the input stream outside of an action. 2505 */ 2506char * 2507#ifdef __USE_PROTOS 2508inline_set(char *s) 2509#else 2510inline_set(s) 2511char *s; 2512#endif 2513{ 2514 char *nxt; 2515 fprintf(stderr, "found consumeUntil( {...} )\n"); 2516 while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} 2517 if ( *s!='{' ) 2518 { 2519 err("malformed consumeUntil( {...} ); missing '{'"); 2520 return "bad_set"; 2521 } 2522 s++; 2523 while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} 2524 while ( *s!='}' ) 2525 { 2526 if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s); 2527 else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s); 2528 else { 2529 err("invalid element in consumeUntil( {...} )"); 2530 return "bad_set"; 2531 } 2532 s = nxt; 2533 while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} 2534 } 2535 return "inlineX_set"; 2536} 2537>> 2538 2539<< 2540/* ANTLR-specific syntax error message generator 2541 * (define USER_ZZSYN when compiling so don't get 2 definitions) 2542 */ 2543void 2544#ifdef __USE_PROTOS 2545zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, 2546int k, char *bad_text) 2547#else 2548zzsyn(text, tok, egroup, eset, etok, k, bad_text) 2549char *text, *egroup, *bad_text; 2550int tok; 2551int etok; 2552int k; 2553SetWordType *eset; 2554#endif 2555{ 2556 fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline); 2557 fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); 2558 if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} 2559 if ( k==1 ) fprintf(stderr, " missing"); 2560 else 2561 { 2562 fprintf(stderr, "; \"%s\" not", bad_text); 2563 if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); 2564 } 2565 if ( zzset_deg(eset)>0 ) zzedecode(eset); 2566 else fprintf(stderr, " %s", zztokens[etok]); 2567 if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); 2568 fprintf(stderr, "\n"); 2569} 2570>> 2571 2572#lexaction << 2573#ifdef __USE_PROTOS 2574void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */ 2575#else 2576void mark_label_used_in_sem_pred(le) /* MR10 */ 2577 LabelEntry *le; 2578#endif 2579{ 2580 TokNode *tn; 2581 require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken"); 2582 tn=(TokNode *)le->elem; 2583 require (tn->label != 0,"mark_label_used... TokNode has no label"); 2584 tn->label_used_in_semantic_pred=1; 2585} 2586>> 2587