1 package persistence.antlr; 2 3 8 9 import persistence.antlr.collections.Stack; 10 import persistence.antlr.collections.impl.LList; 11 import persistence.antlr.collections.impl.Vector; 12 13 public class MakeGrammar extends DefineGrammarSymbols { 14 15 protected Stack blocks = new LList(); protected RuleRefElement lastRuleRef; 17 18 protected RuleEndElement ruleEnd; protected RuleBlock ruleBlock; protected int nested = 0; protected boolean grammarError = false; 22 23 ExceptionSpec currentExceptionSpec = null; 24 25 public MakeGrammar(Tool tool_, String [] args_, LLkAnalyzer analyzer_) { 26 super(tool_, args_, analyzer_); 27 } 28 29 30 public void abortGrammar() { 31 String s = "unknown grammar"; 32 if (grammar != null) { 33 s = grammar.getClassName(); 34 } 35 tool.error("aborting grammar '" + s + "' due to errors"); 36 super.abortGrammar(); 37 } 38 39 protected void addElementToCurrentAlt(AlternativeElement e) { 40 e.enclosingRuleName = ruleBlock.ruleName; 41 context().addAlternativeElement(e); 42 } 43 44 public void beginAlt(boolean doAutoGen_) { 45 super.beginAlt(doAutoGen_); 46 Alternative alt = new Alternative(); 47 alt.setAutoGen(doAutoGen_); 48 context().block.addAlternative(alt); 49 } 50 51 public void beginChildList() { 52 super.beginChildList(); 53 context().block.addAlternative(new Alternative()); 54 } 55 56 57 public void beginExceptionGroup() { 58 super.beginExceptionGroup(); 59 if (!(context().block instanceof RuleBlock)) { 60 tool.panic("beginExceptionGroup called outside of rule block"); 61 } 62 } 63 64 65 public void beginExceptionSpec(Token label) { 66 if (label != null) { 68 label.setText(StringUtils.stripFront(StringUtils.stripBack(label.getText(), " \n\r\t"), " \n\r\t")); 69 } 70 super.beginExceptionSpec(label); 71 currentExceptionSpec = new ExceptionSpec(label); 74 } 75 76 public void beginSubRule(Token label, Token start, boolean not) { 77 super.beginSubRule(label, start, not); 78 blocks.push(new BlockContext()); 82 context().block = new AlternativeBlock(grammar, start, not); 83 context().altNum = 0; nested++; 85 context().blockEnd = new BlockEndElement(grammar); 88 context().blockEnd.block = context().block; 90 labelElement(context().block, label); 91 } 92 93 public void beginTree(Token tok) throws SemanticException { 94 if (!(grammar instanceof TreeWalkerGrammar)) { 95 tool.error("Trees only allowed in TreeParser", grammar.getFilename(), tok.getLine(), tok.getColumn()); 96 throw new SemanticException("Trees only allowed in TreeParser"); 97 } 98 super.beginTree(tok); 99 blocks.push(new TreeBlockContext()); 100 context().block = new TreeElement(grammar, tok); 101 context().altNum = 0; } 103 104 public BlockContext context() { 105 if (blocks.height() == 0) { 106 return null; 107 } 108 else { 109 return (BlockContext)blocks.top(); 110 } 111 } 112 113 120 public static RuleBlock createNextTokenRule(Grammar g, Vector lexRules, String rname) { 121 RuleBlock rb = new RuleBlock(g, rname); 123 rb.setDefaultErrorHandler(g.getDefaultErrorHandler()); 124 RuleEndElement ruleEnd = new RuleEndElement(g); 125 rb.setEndElement(ruleEnd); 126 ruleEnd.block = rb; 127 for (int i = 0; i < lexRules.size(); i++) { 129 RuleSymbol r = (RuleSymbol)lexRules.elementAt(i); 130 if (!r.isDefined()) { 131 g.antlrTool.error("Lexer rule " + r.id.substring(1) + " is not defined"); 132 } 133 else { 134 if (r.access.equals("public")) { 135 Alternative alt = new Alternative(); RuleBlock targetRuleBlock = r.getBlock(); 137 Vector targetRuleAlts = targetRuleBlock.getAlternatives(); 138 if ( targetRuleAlts!=null && targetRuleAlts.size()==1 ) { 141 Alternative onlyAlt = (Alternative)targetRuleAlts.elementAt(0); 142 if ( onlyAlt.semPred!=null ) { 143 alt.semPred = onlyAlt.semPred; 145 } 148 } 149 150 RuleRefElement rr = 154 new RuleRefElement(g, 155 new CommonToken(ANTLRTokenTypes.RULE_REF, r.getId()), 156 GrammarElement.AUTO_GEN_NONE); 157 rr.setLabel("theRetToken"); 158 rr.enclosingRuleName = "nextToken"; 159 rr.next = ruleEnd; 160 alt.addElement(rr); alt.setAutoGen(true); rb.addAlternative(alt); r.addReference(rr); } 165 } 166 } 167 168 rb.setAutoGen(true); rb.prepareForAnalysis(); 170 return rb; 172 } 173 174 175 private AlternativeBlock createOptionalRuleRef(String rule, Token start) { 176 AlternativeBlock blk = new AlternativeBlock(grammar, start, false); 178 179 String mrule = CodeGenerator.encodeLexerRuleName(rule); if (!grammar.isDefined(mrule)) { 182 grammar.define(new RuleSymbol(mrule)); 183 } 184 185 Token t = new CommonToken(ANTLRTokenTypes.TOKEN_REF, rule); 188 t.setLine(start.getLine()); 189 t.setLine(start.getColumn()); 190 RuleRefElement rref = 191 new RuleRefElement(grammar, t, GrammarElement.AUTO_GEN_NONE); 192 193 rref.enclosingRuleName = ruleBlock.ruleName; 194 195 BlockEndElement end = new BlockEndElement(grammar); 197 end.block = blk; 199 Alternative alt = new Alternative(rref); 201 alt.addElement(end); 203 blk.addAlternative(alt); 205 206 Alternative optAlt = new Alternative(); 208 optAlt.addElement(end); 210 blk.addAlternative(optAlt); 211 212 blk.prepareForAnalysis(); 213 return blk; 214 } 215 216 public void defineRuleName(Token r, 217 String access, 218 boolean ruleAutoGen, 219 String docComment) 220 throws SemanticException { 221 if (r.type == ANTLRTokenTypes.TOKEN_REF) { 223 if (!(grammar instanceof LexerGrammar)) { 224 tool.error("Lexical rule " + r.getText() + 225 " defined outside of lexer", 226 grammar.getFilename(), r.getLine(), r.getColumn()); 227 r.setText(r.getText().toLowerCase()); 228 } 229 } 230 else { 231 if (grammar instanceof LexerGrammar) { 232 tool.error("Lexical rule names must be upper case, '" + r.getText() + 233 "' is not", 234 grammar.getFilename(), r.getLine(), r.getColumn()); 235 r.setText(r.getText().toUpperCase()); 236 } 237 } 238 239 super.defineRuleName(r, access, ruleAutoGen, docComment); 240 String id = r.getText(); 241 if (r.type == ANTLRTokenTypes.TOKEN_REF) { id = CodeGenerator.encodeLexerRuleName(id); 244 } 245 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(id); 246 RuleBlock rb = new RuleBlock(grammar, r.getText(), r.getLine(), ruleAutoGen); 247 248 rb.setDefaultErrorHandler(grammar.getDefaultErrorHandler()); 250 251 ruleBlock = rb; 252 blocks.push(new BlockContext()); context().block = rb; 254 rs.setBlock(rb); 255 ruleEnd = new RuleEndElement(grammar); 256 rb.setEndElement(ruleEnd); 257 nested = 0; 258 } 259 260 public void endAlt() { 261 super.endAlt(); 262 if (nested == 0) { addElementToCurrentAlt(ruleEnd); 264 } 265 else { 266 addElementToCurrentAlt(context().blockEnd); 267 } 268 context().altNum++; 269 } 270 271 public void endChildList() { 272 super.endChildList(); 273 BlockEndElement be = new BlockEndElement(grammar); 278 be.block = context().block; 279 addElementToCurrentAlt(be); 280 } 281 282 public void endExceptionGroup() { 283 super.endExceptionGroup(); 284 } 285 286 public void endExceptionSpec() { 287 super.endExceptionSpec(); 288 if (currentExceptionSpec == null) { 289 tool.panic("exception processing internal error -- no active exception spec"); 290 } 291 if (context().block instanceof RuleBlock) { 292 ((RuleBlock)context().block).addExceptionSpec(currentExceptionSpec); 294 } 295 else { 296 if (context().currentAlt().exceptionSpec != null) { 298 tool.error("Alternative already has an exception specification", grammar.getFilename(), context().block.getLine(), context().block.getColumn()); 299 } 300 else { 301 context().currentAlt().exceptionSpec = currentExceptionSpec; 302 } 303 } 304 currentExceptionSpec = null; 305 } 306 307 308 public void endGrammar() { 309 if (grammarError) { 310 abortGrammar(); 311 } 312 else { 313 super.endGrammar(); 314 } 315 } 316 317 public void endRule(String rule) { 318 super.endRule(rule); 319 BlockContext ctx = (BlockContext)blocks.pop(); ruleEnd.block = ctx.block; 322 ruleEnd.block.prepareForAnalysis(); 323 } 325 326 public void endSubRule() { 327 super.endSubRule(); 328 nested--; 329 BlockContext ctx = (BlockContext)blocks.pop(); 331 AlternativeBlock block = ctx.block; 332 333 if ( 336 block.not && 337 !(block instanceof SynPredBlock) && 338 !(block instanceof ZeroOrMoreBlock) && 339 !(block instanceof OneOrMoreBlock) 340 ) { 341 if (!analyzer.subruleCanBeInverted(block, grammar instanceof LexerGrammar)) { 342 String newline = System.getProperty("line.separator"); 343 tool.error( 344 "This subrule cannot be inverted. Only subrules of the form:" + newline + 345 " (T1|T2|T3...) or" + newline + 346 " ('c1'|'c2'|'c3'...)" + newline + 347 "may be inverted (ranges are also allowed).", 348 grammar.getFilename(), 349 block.getLine(), block.getColumn() 350 ); 351 } 352 } 353 354 if (block instanceof SynPredBlock) { 356 SynPredBlock synpred = (SynPredBlock)block; 359 context().block.hasASynPred = true; 360 context().currentAlt().synPred = synpred; 361 grammar.hasSyntacticPredicate = true; 362 synpred.removeTrackingOfRuleRefs(grammar); 363 } 364 else { 365 addElementToCurrentAlt(block); 366 } 367 ctx.blockEnd.block.prepareForAnalysis(); 368 } 369 370 public void endTree() { 371 super.endTree(); 372 BlockContext ctx = (BlockContext)blocks.pop(); 373 addElementToCurrentAlt(ctx.block); } 375 376 377 public void hasError() { 378 grammarError = true; 379 } 380 381 private void labelElement(AlternativeElement el, Token label) { 382 if (label != null) { 383 for (int i = 0; i < ruleBlock.labeledElements.size(); i++) { 385 AlternativeElement altEl = (AlternativeElement)ruleBlock.labeledElements.elementAt(i); 386 String l = altEl.getLabel(); 387 if (l != null && l.equals(label.getText())) { 388 tool.error("Label '" + label.getText() + "' has already been defined", grammar.getFilename(), label.getLine(), label.getColumn()); 389 return; 390 } 391 } 392 el.setLabel(label.getText()); 394 ruleBlock.labeledElements.appendElement(el); 395 } 396 } 397 398 public void noAutoGenSubRule() { 399 context().block.setAutoGen(false); 400 } 401 402 public void oneOrMoreSubRule() { 403 if (context().block.not) { 404 tool.error("'~' cannot be applied to (...)* subrule", grammar.getFilename(), context().block.getLine(), context().block.getColumn()); 405 } 406 OneOrMoreBlock b = new OneOrMoreBlock(grammar); 410 setBlock(b, context().block); 411 BlockContext old = (BlockContext)blocks.pop(); blocks.push(new BlockContext()); 413 context().block = b; 414 context().blockEnd = old.blockEnd; 415 context().blockEnd.block = b; 416 } 417 418 public void optionalSubRule() { 419 if (context().block.not) { 420 tool.error("'~' cannot be applied to (...)? subrule", grammar.getFilename(), context().block.getLine(), context().block.getColumn()); 421 } 422 beginAlt(false); 425 endAlt(); 426 } 427 428 public void refAction(Token action) { 429 super.refAction(action); 430 context().block.hasAnAction = true; 431 addElementToCurrentAlt(new ActionElement(grammar, action)); 432 } 433 434 public void setUserExceptions(String thr) { 435 ((RuleBlock)context().block).throwsSpec = thr; 436 } 437 438 public void refArgAction(Token action) { 440 ((RuleBlock)context().block).argAction = action.getText(); 441 } 442 443 public void refCharLiteral(Token lit, Token label, boolean inverted, int autoGenType, boolean lastInRule) { 444 if (!(grammar instanceof LexerGrammar)) { 445 tool.error("Character literal only valid in lexer", grammar.getFilename(), lit.getLine(), lit.getColumn()); 446 return; 447 } 448 super.refCharLiteral(lit, label, inverted, autoGenType, lastInRule); 449 CharLiteralElement cl = new CharLiteralElement((LexerGrammar)grammar, lit, inverted, autoGenType); 450 451 if ( 453 !((LexerGrammar)grammar).caseSensitive && cl.getType() < 128 && 454 Character.toLowerCase((char)cl.getType()) != (char)cl.getType() 455 ) { 456 tool.warning("Character literal must be lowercase when caseSensitive=false", grammar.getFilename(), lit.getLine(), lit.getColumn()); 457 } 458 459 addElementToCurrentAlt(cl); 460 labelElement(cl, label); 461 462 String ignore = ruleBlock.getIgnoreRule(); 464 if (!lastInRule && ignore != null) { 465 addElementToCurrentAlt(createOptionalRuleRef(ignore, lit)); 466 } 467 } 468 469 public void refCharRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) { 470 if (!(grammar instanceof LexerGrammar)) { 471 tool.error("Character range only valid in lexer", grammar.getFilename(), t1.getLine(), t1.getColumn()); 472 return; 473 } 474 int rangeMin = ANTLRLexer.tokenTypeForCharLiteral(t1.getText()); 475 int rangeMax = ANTLRLexer.tokenTypeForCharLiteral(t2.getText()); 476 if (rangeMax < rangeMin) { 477 tool.error("Malformed range.", grammar.getFilename(), t1.getLine(), t1.getColumn()); 478 return; 479 } 480 481 if (!((LexerGrammar)grammar).caseSensitive) { 483 if (rangeMin < 128 && Character.toLowerCase((char)rangeMin) != (char)rangeMin) { 484 tool.warning("Character literal must be lowercase when caseSensitive=false", grammar.getFilename(), t1.getLine(), t1.getColumn()); 485 } 486 if (rangeMax < 128 && Character.toLowerCase((char)rangeMax) != (char)rangeMax) { 487 tool.warning("Character literal must be lowercase when caseSensitive=false", grammar.getFilename(), t2.getLine(), t2.getColumn()); 488 } 489 } 490 491 super.refCharRange(t1, t2, label, autoGenType, lastInRule); 492 CharRangeElement cr = new CharRangeElement((LexerGrammar)grammar, t1, t2, autoGenType); 493 addElementToCurrentAlt(cr); 494 labelElement(cr, label); 495 496 String ignore = ruleBlock.getIgnoreRule(); 498 if (!lastInRule && ignore != null) { 499 addElementToCurrentAlt(createOptionalRuleRef(ignore, t1)); 500 } 501 } 502 503 public void refTokensSpecElementOption(Token tok, 504 Token option, 505 Token value) { 506 510 TokenSymbol ts = (TokenSymbol) 511 grammar.tokenManager.getTokenSymbol(tok.getText()); 512 if (ts == null) { 513 tool.panic("cannot find " + tok.getText() + "in tokens {...}"); 514 } 515 if (option.getText().equals("AST")) { 516 ts.setASTNodeType(value.getText()); 517 } 518 else { 519 grammar.antlrTool.error("invalid tokens {...} element option:" + 520 option.getText(), 521 grammar.getFilename(), 522 option.getLine(), option.getColumn()); 523 } 524 } 525 526 public void refElementOption(Token option, Token value) { 527 531 AlternativeElement e = context().currentElement(); 532 if (e instanceof StringLiteralElement || 533 e instanceof TokenRefElement || 534 e instanceof WildcardElement) { 535 ((GrammarAtom)e).setOption(option, value); 536 } 537 else { 538 tool.error("cannot use element option (" + option.getText() + 539 ") for this kind of element", 540 grammar.getFilename(), option.getLine(), option.getColumn()); 541 } 542 } 543 544 545 public void refExceptionHandler(Token exTypeAndName, Token action) { 546 super.refExceptionHandler(exTypeAndName, action); 547 if (currentExceptionSpec == null) { 548 tool.panic("exception handler processing internal error"); 549 } 550 currentExceptionSpec.addHandler(new ExceptionHandler(exTypeAndName, action)); 551 } 552 553 public void refInitAction(Token action) { 554 super.refAction(action); 555 context().block.setInitAction(action.getText()); 556 } 557 558 public void refMemberAction(Token act) { 559 grammar.classMemberAction = act; 560 } 561 562 public void refPreambleAction(Token act) { 563 super.refPreambleAction(act); 564 } 565 566 public void refReturnAction(Token returnAction) { 568 if (grammar instanceof LexerGrammar) { 569 String name = CodeGenerator.encodeLexerRuleName(((RuleBlock)context().block).getRuleName()); 570 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(name); 571 if (rs.access.equals("public")) { 572 tool.warning("public Lexical rules cannot specify return type", grammar.getFilename(), returnAction.getLine(), returnAction.getColumn()); 573 return; 574 } 575 } 576 ((RuleBlock)context().block).returnAction = returnAction.getText(); 577 } 578 579 public void refRule(Token idAssign, 580 Token r, 581 Token label, 582 Token args, 583 int autoGenType) { 584 if (grammar instanceof LexerGrammar) { 586 if (r.type != ANTLRTokenTypes.TOKEN_REF) { 588 tool.error("Parser rule " + r.getText() + " referenced in lexer"); 589 return; 590 } 591 if (autoGenType == GrammarElement.AUTO_GEN_CARET) { 592 tool.error("AST specification ^ not allowed in lexer", grammar.getFilename(), r.getLine(), r.getColumn()); 593 } 594 } 595 596 super.refRule(idAssign, r, label, args, autoGenType); 597 lastRuleRef = new RuleRefElement(grammar, r, autoGenType); 598 if (args != null) { 599 lastRuleRef.setArgs(args.getText()); 600 } 601 if (idAssign != null) { 602 lastRuleRef.setIdAssign(idAssign.getText()); 603 } 604 addElementToCurrentAlt(lastRuleRef); 605 606 String id = r.getText(); 607 if (r.type == ANTLRTokenTypes.TOKEN_REF) { id = CodeGenerator.encodeLexerRuleName(id); 610 } 611 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(id); 613 rs.addReference(lastRuleRef); 614 labelElement(lastRuleRef, label); 615 } 616 617 public void refSemPred(Token pred) { 618 super.refSemPred(pred); 620 if (context().currentAlt().atStart()) { 622 context().currentAlt().semPred = pred.getText(); 623 } 624 else { 625 ActionElement a = new ActionElement(grammar, pred); 626 a.isSemPred = true; 627 addElementToCurrentAlt(a); 628 } 629 } 631 632 public void refStringLiteral(Token lit, Token label, int autoGenType, boolean lastInRule) { 633 super.refStringLiteral(lit, label, autoGenType, lastInRule); 634 if (grammar instanceof TreeWalkerGrammar && autoGenType == GrammarElement.AUTO_GEN_CARET) { 635 tool.error("^ not allowed in here for tree-walker", grammar.getFilename(), lit.getLine(), lit.getColumn()); 636 } 637 StringLiteralElement sl = new StringLiteralElement(grammar, lit, autoGenType); 638 639 if (grammar instanceof LexerGrammar && !((LexerGrammar)grammar).caseSensitive) { 641 for (int i = 1; i < lit.getText().length() - 1; i++) { 642 char c = lit.getText().charAt(i); 643 if (c < 128 && Character.toLowerCase(c) != c) { 644 tool.warning("Characters of string literal must be lowercase when caseSensitive=false", grammar.getFilename(), lit.getLine(), lit.getColumn()); 645 break; 646 } 647 } 648 } 649 650 addElementToCurrentAlt(sl); 651 labelElement(sl, label); 652 653 String ignore = ruleBlock.getIgnoreRule(); 655 if (!lastInRule && ignore != null) { 656 addElementToCurrentAlt(createOptionalRuleRef(ignore, lit)); 657 } 658 } 659 660 public void refToken(Token idAssign, Token t, Token label, Token args, 661 boolean inverted, int autoGenType, boolean lastInRule) { 662 if (grammar instanceof LexerGrammar) { 663 if (autoGenType == GrammarElement.AUTO_GEN_CARET) { 665 tool.error("AST specification ^ not allowed in lexer", grammar.getFilename(), t.getLine(), t.getColumn()); 666 } 667 if (inverted) { 668 tool.error("~TOKEN is not allowed in lexer", grammar.getFilename(), t.getLine(), t.getColumn()); 669 } 670 refRule(idAssign, t, label, args, autoGenType); 671 672 String ignore = ruleBlock.getIgnoreRule(); 674 if (!lastInRule && ignore != null) { 675 addElementToCurrentAlt(createOptionalRuleRef(ignore, t)); 676 } 677 } 678 else { 679 if (idAssign != null) { 681 tool.error("Assignment from token reference only allowed in lexer", grammar.getFilename(), idAssign.getLine(), idAssign.getColumn()); 682 } 683 if (args != null) { 684 tool.error("Token reference arguments only allowed in lexer", grammar.getFilename(), args.getLine(), args.getColumn()); 685 } 686 super.refToken(idAssign, t, label, args, inverted, autoGenType, lastInRule); 687 TokenRefElement te = new TokenRefElement(grammar, t, inverted, autoGenType); 688 addElementToCurrentAlt(te); 689 labelElement(te, label); 690 } 691 } 692 693 public void refTokenRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) { 694 if (grammar instanceof LexerGrammar) { 695 tool.error("Token range not allowed in lexer", grammar.getFilename(), t1.getLine(), t1.getColumn()); 696 return; 697 } 698 super.refTokenRange(t1, t2, label, autoGenType, lastInRule); 699 TokenRangeElement tr = new TokenRangeElement(grammar, t1, t2, autoGenType); 700 if (tr.end < tr.begin) { 701 tool.error("Malformed range.", grammar.getFilename(), t1.getLine(), t1.getColumn()); 702 return; 703 } 704 addElementToCurrentAlt(tr); 705 labelElement(tr, label); 706 } 707 708 public void refTreeSpecifier(Token treeSpec) { 709 context().currentAlt().treeSpecifier = treeSpec; 710 } 711 712 public void refWildcard(Token t, Token label, int autoGenType) { 713 super.refWildcard(t, label, autoGenType); 714 WildcardElement wc = new WildcardElement(grammar, t, autoGenType); 715 addElementToCurrentAlt(wc); 716 labelElement(wc, label); 717 } 718 719 720 public void reset() { 721 super.reset(); 722 blocks = new LList(); 723 lastRuleRef = null; 724 ruleEnd = null; 725 ruleBlock = null; 726 nested = 0; 727 currentExceptionSpec = null; 728 grammarError = false; 729 } 730 731 public void setArgOfRuleRef(Token argAction) { 732 super.setArgOfRuleRef(argAction); 733 lastRuleRef.setArgs(argAction.getText()); 734 } 735 736 public static void setBlock(AlternativeBlock b, AlternativeBlock src) { 737 b.setAlternatives(src.getAlternatives()); 738 b.initAction = src.initAction; 739 b.label = src.label; 741 b.hasASynPred = src.hasASynPred; 742 b.hasAnAction = src.hasAnAction; 743 b.warnWhenFollowAmbig = src.warnWhenFollowAmbig; 744 b.generateAmbigWarnings = src.generateAmbigWarnings; 745 b.line = src.line; 746 b.greedy = src.greedy; 747 b.greedySet = src.greedySet; 748 } 749 750 public void setRuleOption(Token key, Token value) { 751 ruleBlock.setOption(key, value); 753 } 754 755 public void setSubruleOption(Token key, Token value) { 756 ((AlternativeBlock)context().block).setOption(key, value); 757 } 758 759 public void synPred() { 760 if (context().block.not) { 761 tool.error("'~' cannot be applied to syntactic predicate", grammar.getFilename(), context().block.getLine(), context().block.getColumn()); 762 } 763 SynPredBlock b = new SynPredBlock(grammar); 767 setBlock(b, context().block); 768 BlockContext old = (BlockContext)blocks.pop(); blocks.push(new BlockContext()); 770 context().block = b; 771 context().blockEnd = old.blockEnd; 772 context().blockEnd.block = b; 773 } 774 775 public void zeroOrMoreSubRule() { 776 if (context().block.not) { 777 tool.error("'~' cannot be applied to (...)+ subrule", grammar.getFilename(), context().block.getLine(), context().block.getColumn()); 778 } 779 ZeroOrMoreBlock b = new ZeroOrMoreBlock(grammar); 783 setBlock(b, context().block); 784 BlockContext old = (BlockContext)blocks.pop(); blocks.push(new BlockContext()); 786 context().block = b; 787 context().blockEnd = old.blockEnd; 788 context().blockEnd.block = b; 789 } 790 } 791 | Popular Tags |