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 58 static void chkToken(char *, char *, char *, int); 59 #else 60 static void chkToken(); 61 #endif 62 63 #ifdef __USE_PROTOS 64 static int isDLGmaxToken(char *Token); /* MR3 */ 65 #else 66 static int isDLGmaxToken(); /* MR3 */ 67 #endif 68 69 static 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 */ 77 set AST_nodes_refd_in_actions = set_init; 78 int inAlt = 0; 79 set attribsRefdFromAction = set_init; /* MR20 */ 80 int UsedOldStyleAttrib = 0; 81 int UsedNewStyleLabel = 0; 82 #ifdef __USE_PROTOS 83 char *inline_set(char *); 84 #else 85 char *inline_set(); 86 #endif 87 88 /* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ 89 /* MR1 in DLG action */ 90 91 int 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 626 grammar : <<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 762 class_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 823 rule : << 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 962 laction : <<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 982 lmember: <<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 1001 lprefix: <<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 1030 aPred: <<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 1133 predOrExpr>[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 1167 predAndExpr>[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 1202 predPrimary>[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 1243 aLexclass: "{\\}#lexclass" TokenTerm <<lexclass(mystrdup(LATEXT(1)));>> 1244 ; 1245 <<CannotContinue=TRUE;>> 1246 1247 /* rule error */ 1248 1249 error : <<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 1294 tclass : <<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 1399 token : <<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 1456 block[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 1533 alt[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 1603 element_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 1643 element[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 2005 default_exception_handler 2006 : exception_group > [DefaultExGroup] 2007 ; 2008 2009 /* rule exception_group */ 2010 2011 exception_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 2102 exception_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 2167 enum_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 2181 defines[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 (at) 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 2212 enum_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 (at) 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 2272 static char * 2273 #ifdef __USE_PROTOS 2274 getFileNameFromTheLineInfo(char *toStr, char *fromStr) 2275 #else 2276 getFileNameFromTheLineInfo(toStr, fromStr) 2277 char *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 (at) 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 2347 static int isDLGmaxToken(char *Token) 2348 #else 2349 static 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 */ 2365 static void 2366 #ifdef __USE_PROTOS 2367 chkToken(char *t, char *e, char *a, int tnum) 2368 #else 2369 chkToken(t,e,a,tnum) 2370 char *t, *e, *a; 2371 int 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) { 2393 err(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) { 2409 err(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 << 2454 static int 2455 #ifdef __USE_PROTOS 2456 match_token(char *s, char **nxt) 2457 #else 2458 match_token(s,nxt) 2459 char *s; 2460 char **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 2477 static int 2478 #ifdef __USE_PROTOS 2479 match_rexpr(char *s, char **nxt) 2480 #else 2481 match_rexpr(s,nxt) 2482 char *s; 2483 char **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 */ 2506 char * 2507 #ifdef __USE_PROTOS 2508 inline_set(char *s) 2509 #else 2510 inline_set(s) 2511 char *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 */ 2543 void 2544 #ifdef __USE_PROTOS 2545 zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, 2546 int k, char *bad_text) 2547 #else 2548 zzsyn(text, tok, egroup, eset, etok, k, bad_text) 2549 char *text, *egroup, *bad_text; 2550 int tok; 2551 int etok; 2552 int k; 2553 SetWordType *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 2574 void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */ 2575 #else 2576 void 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