1 package antlr; 2 3 9 10 import antlr.collections.impl.BitSet; 11 import antlr.collections.impl.Vector; 12 13 21 public class LLkAnalyzer implements LLkGrammarAnalyzer { 22 public boolean DEBUG_ANALYZER = false; 24 private AlternativeBlock currentBlock; 25 protected Tool tool = null; 26 protected Grammar grammar = null; 27 protected boolean lexicalAnalysis = false; 29 CharFormatter charFormatter = new JavaCharFormatter(); 31 32 33 public LLkAnalyzer(Tool tool_) { 34 tool = tool_; 35 } 36 37 40 protected boolean altUsesWildcardDefault(Alternative alt) { 41 AlternativeElement head = alt.head; 42 if (head instanceof TreeElement && 44 ((TreeElement)head).root instanceof WildcardElement) { 45 return true; 46 } 47 if (head instanceof WildcardElement && head.next instanceof BlockEndElement) { 48 return true; 49 } 50 return false; 51 } 52 53 56 public boolean deterministic(AlternativeBlock blk) { 57 58 int k = 1; if (DEBUG_ANALYZER) System.out.println("deterministic(" + blk + ")"); 60 boolean det = true; 61 int nalts = blk.alternatives.size(); 62 AlternativeBlock saveCurrentBlock = currentBlock; 63 Alternative wildcardAlt = null; 64 currentBlock = blk; 65 66 67 if (blk.greedy == false && !(blk instanceof OneOrMoreBlock) && !(blk instanceof ZeroOrMoreBlock)) { 68 tool.warning("Being nongreedy only makes sense for (...)+ and (...)*", grammar.getFilename(), blk.getLine(), blk.getColumn()); 69 } 70 71 if (nalts == 1) { 75 AlternativeElement e = blk.getAlternativeAt(0).head; 76 currentBlock.alti = 0; 77 blk.getAlternativeAt(0).cache[1] = e.look(1); 78 blk.getAlternativeAt(0).lookaheadDepth = 1; currentBlock = saveCurrentBlock; 80 return true; } 82 83 outer: 84 for (int i = 0; i < nalts - 1; i++) { 85 currentBlock.alti = i; 86 currentBlock.analysisAlt = i; currentBlock.altj = i + 1; inner: 90 for (int j = i + 1; j < nalts; j++) { 92 currentBlock.altj = j; 93 if (DEBUG_ANALYZER) System.out.println("comparing " + i + " against alt " + j); 94 currentBlock.analysisAlt = j; k = 1; 97 Lookahead[] r = new Lookahead[grammar.maxk + 1]; 100 boolean haveAmbiguity; 101 do { 102 haveAmbiguity = false; 103 if (DEBUG_ANALYZER) System.out.println("checking depth " + k + "<=" + grammar.maxk); 104 Lookahead p,q; 105 p = getAltLookahead(blk, i, k); 106 q = getAltLookahead(blk, j, k); 107 108 if (DEBUG_ANALYZER) System.out.println("p is " + p.toString(",", charFormatter, grammar)); 111 if (DEBUG_ANALYZER) System.out.println("q is " + q.toString(",", charFormatter, grammar)); 112 r[k] = p.intersection(q); 114 if (DEBUG_ANALYZER) System.out.println("intersection at depth " + k + " is " + r[k].toString()); 115 if (!r[k].nil()) { 116 haveAmbiguity = true; 117 k++; 118 } 119 } while (haveAmbiguity && k <= grammar.maxk); 121 122 Alternative ai = blk.getAlternativeAt(i); 123 Alternative aj = blk.getAlternativeAt(j); 124 if (haveAmbiguity) { 125 det = false; 126 ai.lookaheadDepth = NONDETERMINISTIC; 127 aj.lookaheadDepth = NONDETERMINISTIC; 128 129 135 if (ai.synPred != null) { 136 if (DEBUG_ANALYZER) { 137 System.out.println("alt " + i + " has a syn pred"); 138 } 139 } 145 146 150 else if (ai.semPred != null) { 151 if (DEBUG_ANALYZER) { 152 System.out.println("alt " + i + " has a sem pred"); 153 } 154 } 155 156 160 else if (altUsesWildcardDefault(aj)) { 161 wildcardAlt = aj; 164 } 165 166 170 else if (!blk.warnWhenFollowAmbig && 171 (ai.head instanceof BlockEndElement || 172 aj.head instanceof BlockEndElement)) { 173 } 176 177 180 else if (!blk.generateAmbigWarnings) { 181 } 182 183 184 else if (blk.greedySet && blk.greedy && 185 ((ai.head instanceof BlockEndElement && 186 !(aj.head instanceof BlockEndElement)) || 187 (aj.head instanceof BlockEndElement && 188 !(ai.head instanceof BlockEndElement)))) { 189 } 191 192 193 194 else { 195 tool.errorHandler.warnAltAmbiguity( 196 grammar, 197 blk, lexicalAnalysis, grammar.maxk, r, i, j ); 204 } 205 } 206 else { 207 ai.lookaheadDepth = Math.max(ai.lookaheadDepth, k); 209 aj.lookaheadDepth = Math.max(aj.lookaheadDepth, k); 210 } 211 } 212 } 213 214 216 222 223 currentBlock = saveCurrentBlock; 224 return det; 225 } 226 227 230 public boolean deterministic(OneOrMoreBlock blk) { 231 if (DEBUG_ANALYZER) System.out.println("deterministic(...)+(" + blk + ")"); 232 AlternativeBlock saveCurrentBlock = currentBlock; 233 currentBlock = blk; 234 boolean blkOk = deterministic((AlternativeBlock)blk); 235 boolean det = deterministicImpliedPath(blk); 238 currentBlock = saveCurrentBlock; 239 return det && blkOk; 240 } 241 242 245 public boolean deterministic(ZeroOrMoreBlock blk) { 246 if (DEBUG_ANALYZER) System.out.println("deterministic(...)*(" + blk + ")"); 247 AlternativeBlock saveCurrentBlock = currentBlock; 248 currentBlock = blk; 249 boolean blkOk = deterministic((AlternativeBlock)blk); 250 boolean det = deterministicImpliedPath(blk); 253 currentBlock = saveCurrentBlock; 254 return det && blkOk; 255 } 256 257 260 public boolean deterministicImpliedPath(BlockWithImpliedExitPath blk) { 261 262 int k; 263 boolean det = true; 264 Vector alts = blk.getAlternatives(); 265 int nalts = alts.size(); 266 currentBlock.altj = -1; 268 if (DEBUG_ANALYZER) System.out.println("deterministicImpliedPath"); 269 for (int i = 0; i < nalts; i++) { Alternative alt = blk.getAlternativeAt(i); 271 272 if (alt.head instanceof BlockEndElement) { 273 tool.warning("empty alternative makes no sense in (...)* or (...)+", grammar.getFilename(), blk.getLine(), blk.getColumn()); 274 } 275 276 k = 1; Lookahead[] r = new Lookahead[grammar.maxk + 1]; 280 boolean haveAmbiguity; 281 do { 282 haveAmbiguity = false; 283 if (DEBUG_ANALYZER) System.out.println("checking depth " + k + "<=" + grammar.maxk); 284 Lookahead p; 285 Lookahead follow = blk.next.look(k); 286 blk.exitCache[k] = follow; 287 currentBlock.alti = i; 288 p = getAltLookahead(blk, i, k); 289 290 if (DEBUG_ANALYZER) System.out.println("follow is " + follow.toString(",", charFormatter, grammar)); 291 if (DEBUG_ANALYZER) System.out.println("p is " + p.toString(",", charFormatter, grammar)); 292 r[k] = follow.intersection(p); 294 if (DEBUG_ANALYZER) System.out.println("intersection at depth " + k + " is " + r[k]); 295 if (!r[k].nil()) { 296 haveAmbiguity = true; 297 k++; 298 } 299 } while (haveAmbiguity && k <= grammar.maxk); 301 302 if (haveAmbiguity) { 303 det = false; 304 alt.lookaheadDepth = NONDETERMINISTIC; 305 blk.exitLookaheadDepth = NONDETERMINISTIC; 306 Alternative ambigAlt = blk.getAlternativeAt(currentBlock.alti); 307 308 311 if (!blk.warnWhenFollowAmbig) { 312 } 313 314 317 else if (!blk.generateAmbigWarnings) { 318 } 319 320 321 else if (blk.greedy == true && blk.greedySet && 322 !(ambigAlt.head instanceof BlockEndElement)) { 323 if (DEBUG_ANALYZER) System.out.println("greedy loop"); 324 } 325 326 330 else if (blk.greedy == false && 331 !(ambigAlt.head instanceof BlockEndElement)) { 332 if (DEBUG_ANALYZER) System.out.println("nongreedy loop"); 333 if (!lookaheadEquivForApproxAndFullAnalysis(blk.exitCache, grammar.maxk)) { 338 tool.warning(new String []{ 339 "nongreedy block may exit incorrectly due", 340 "\tto limitations of linear approximate lookahead (first k-1 sets", 341 "\tin lookahead not singleton)."}, 342 grammar.getFilename(), blk.getLine(), blk.getColumn()); 343 } 344 } 345 346 else { 348 tool.errorHandler.warnAltExitAmbiguity( 349 grammar, 350 blk, lexicalAnalysis, grammar.maxk, r, i ); 356 } 357 } 358 else { 359 alt.lookaheadDepth = Math.max(alt.lookaheadDepth, k); 360 blk.exitLookaheadDepth = Math.max(blk.exitLookaheadDepth, k); 361 } 362 } 363 return det; 364 } 365 366 369 public Lookahead FOLLOW(int k, RuleEndElement end) { 370 RuleBlock rb = (RuleBlock)end.block; 372 String rule; 374 if (lexicalAnalysis) { 375 rule = CodeGenerator.encodeLexerRuleName(rb.getRuleName()); 376 } 377 else { 378 rule = rb.getRuleName(); 379 } 380 381 if (DEBUG_ANALYZER) System.out.println("FOLLOW(" + k + "," + rule + ")"); 382 383 if (end.lock[k]) { 385 if (DEBUG_ANALYZER) System.out.println("FOLLOW cycle to " + rule); 386 return new Lookahead(rule); 387 } 388 389 if (end.cache[k] != null) { 391 if (DEBUG_ANALYZER) { 392 System.out.println("cache entry FOLLOW(" + k + ") for " + rule + ": " + end.cache[k].toString(",", charFormatter, grammar)); 393 } 394 if (end.cache[k].cycle == null) { 396 return (Lookahead)end.cache[k].clone(); 397 } 398 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(end.cache[k].cycle); 400 RuleEndElement re = rs.getBlock().endNode; 401 if (re.cache[k] == null) { 404 return (Lookahead)end.cache[k].clone(); 406 } 407 else { 408 end.cache[k] = re.cache[k]; 414 return (Lookahead)re.cache[k].clone(); 416 } 417 } 418 419 end.lock[k] = true; 421 Lookahead p = new Lookahead(); 422 423 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rule); 424 425 for (int i = 0; i < rs.numReferences(); i++) { 427 RuleRefElement rr = rs.getReference(i); 428 if (DEBUG_ANALYZER) System.out.println("next[" + rule + "] is " + rr.next.toString()); 429 Lookahead q = rr.next.look(k); 430 if (DEBUG_ANALYZER) System.out.println("FIRST of next[" + rule + "] ptr is " + q.toString()); 431 435 if (q.cycle != null && q.cycle.equals(rule)) { 436 q.cycle = null; } 438 p.combineWith(q); 440 if (DEBUG_ANALYZER) System.out.println("combined FOLLOW[" + rule + "] is " + p.toString()); 441 } 442 443 end.lock[k] = false; 445 if (p.fset.nil() && p.cycle == null) { 448 if (grammar instanceof TreeWalkerGrammar) { 449 p.fset.add(Token.NULL_TREE_LOOKAHEAD); 452 } 453 else if (grammar instanceof LexerGrammar) { 454 p.setEpsilon(); 461 } 462 else { 463 p.fset.add(Token.EOF_TYPE); 464 } 465 } 466 467 if (DEBUG_ANALYZER) { 469 System.out.println("saving FOLLOW(" + k + ") for " + rule + ": " + p.toString(",", charFormatter, grammar)); 470 } 471 end.cache[k] = (Lookahead)p.clone(); 472 473 return p; 474 } 475 476 private Lookahead getAltLookahead(AlternativeBlock blk, int alt, int k) { 477 Lookahead p; 478 Alternative a = blk.getAlternativeAt(alt); 479 AlternativeElement e = a.head; 480 if (a.cache[k] == null) { 482 p = e.look(k); 483 a.cache[k] = p; 484 } 485 else { 486 p = a.cache[k]; 487 } 488 return p; 489 } 490 491 492 public Lookahead look(int k, ActionElement action) { 493 if (DEBUG_ANALYZER) System.out.println("lookAction(" + k + "," + action + ")"); 494 return action.next.look(k); 495 } 496 497 498 public Lookahead look(int k, AlternativeBlock blk) { 499 if (DEBUG_ANALYZER) System.out.println("lookAltBlk(" + k + "," + blk + ")"); 500 AlternativeBlock saveCurrentBlock = currentBlock; 501 currentBlock = blk; 502 Lookahead p = new Lookahead(); 503 for (int i = 0; i < blk.alternatives.size(); i++) { 504 if (DEBUG_ANALYZER) System.out.println("alt " + i + " of " + blk); 505 currentBlock.analysisAlt = i; 507 Alternative alt = blk.getAlternativeAt(i); 508 AlternativeElement elem = alt.head; 509 if (DEBUG_ANALYZER) { 510 if (alt.head == alt.tail) { 511 System.out.println("alt " + i + " is empty"); 512 } 513 } 514 Lookahead q = elem.look(k); 515 p.combineWith(q); 516 } 517 if (k == 1 && blk.not && subruleCanBeInverted(blk, lexicalAnalysis)) { 518 if (lexicalAnalysis) { 520 BitSet b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone(); 521 int[] elems = p.fset.toArray(); 522 for (int j = 0; j < elems.length; j++) { 523 b.remove(elems[j]); 524 } 525 p.fset = b; 526 } 527 else { 528 p.fset.notInPlace(Token.MIN_USER_TYPE, grammar.tokenManager.maxTokenType()); 529 } 530 } 531 currentBlock = saveCurrentBlock; 532 return p; 533 } 534 535 547 public Lookahead look(int k, BlockEndElement end) { 548 if (DEBUG_ANALYZER) System.out.println("lookBlockEnd(" + k + ", " + end.block + "); lock is " + end.lock[k]); 549 if (end.lock[k]) { 550 return new Lookahead(); 555 } 556 557 Lookahead p; 558 559 560 if (end.block instanceof ZeroOrMoreBlock || 561 end.block instanceof OneOrMoreBlock) { 562 end.lock[k] = true; 566 p = look(k, end.block); 567 end.lock[k] = false; 568 } 569 else { 570 p = new Lookahead(); 571 } 572 573 578 if (end.block instanceof TreeElement) { 579 p.combineWith(Lookahead.of(Token.NULL_TREE_LOOKAHEAD)); 580 } 581 582 589 else if (end.block instanceof SynPredBlock) { 590 p.setEpsilon(); 591 } 592 593 else { 595 Lookahead q = end.block.next.look(k); 596 p.combineWith(q); 597 } 598 599 return p; 600 } 601 602 621 public Lookahead look(int k, CharLiteralElement atom) { 622 if (DEBUG_ANALYZER) System.out.println("lookCharLiteral(" + k + "," + atom + ")"); 623 if (k > 1) { 625 return atom.next.look(k - 1); 626 } 627 if (lexicalAnalysis) { 628 if (atom.not) { 629 BitSet b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone(); 630 if (DEBUG_ANALYZER) System.out.println("charVocab is " + b.toString()); 631 removeCompetingPredictionSets(b, atom); 633 if (DEBUG_ANALYZER) System.out.println("charVocab after removal of prior alt lookahead " + b.toString()); 634 b.clear(atom.getType()); 636 return new Lookahead(b); 637 } 638 else { 639 return Lookahead.of(atom.getType()); 640 } 641 } 642 else { 643 tool.panic("Character literal reference found in parser"); 645 return Lookahead.of(atom.getType()); 647 } 648 } 649 650 public Lookahead look(int k, CharRangeElement r) { 651 if (DEBUG_ANALYZER) System.out.println("lookCharRange(" + k + "," + r + ")"); 652 if (k > 1) { 654 return r.next.look(k - 1); 655 } 656 BitSet p = BitSet.of(r.begin); 657 for (int i = r.begin + 1; i <= r.end; i++) { 658 p.add(i); 659 } 660 return new Lookahead(p); 661 } 662 663 public Lookahead look(int k, GrammarAtom atom) { 664 if (DEBUG_ANALYZER) System.out.println("look(" + k + "," + atom + "[" + atom.getType() + "])"); 665 666 if (lexicalAnalysis) { 667 tool.panic("token reference found in lexer"); 669 } 670 if (k > 1) { 672 return atom.next.look(k - 1); 673 } 674 Lookahead l = Lookahead.of(atom.getType()); 675 if (atom.not) { 676 int maxToken = grammar.tokenManager.maxTokenType(); 678 l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken); 679 removeCompetingPredictionSets(l.fset, atom); 681 } 682 return l; 683 } 684 685 689 public Lookahead look(int k, OneOrMoreBlock blk) { 690 if (DEBUG_ANALYZER) System.out.println("look+" + k + "," + blk + ")"); 691 Lookahead p = look(k, (AlternativeBlock)blk); 692 return p; 693 } 694 695 700 public Lookahead look(int k, RuleBlock blk) { 701 if (DEBUG_ANALYZER) System.out.println("lookRuleBlk(" + k + "," + blk + ")"); 702 Lookahead p = look(k, (AlternativeBlock)blk); 703 return p; 704 } 705 706 732 public Lookahead look(int k, RuleEndElement end) { 733 if (DEBUG_ANALYZER) 734 System.out.println("lookRuleBlockEnd(" + k + "); noFOLLOW=" + 735 end.noFOLLOW + "; lock is " + end.lock[k]); 736 if ( end.noFOLLOW) { 737 Lookahead p = new Lookahead(); 738 p.setEpsilon(); 739 p.epsilonDepth = BitSet.of(k); 740 return p; 741 } 742 Lookahead p = FOLLOW(k, end); 743 return p; 744 } 745 746 762 public Lookahead look(int k, RuleRefElement rr) { 763 if (DEBUG_ANALYZER) System.out.println("lookRuleRef(" + k + "," + rr + ")"); 764 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule); 765 if (rs == null || !rs.defined) { 766 tool.error("no definition of rule " + rr.targetRule, grammar.getFilename(), rr.getLine(), rr.getColumn()); 767 return new Lookahead(); 768 } 769 RuleBlock rb = rs.getBlock(); 770 RuleEndElement end = rb.endNode; 771 boolean saveEnd = end.noFOLLOW; 772 end.noFOLLOW = true; 773 Lookahead p = look(k, rr.targetRule); 775 if (DEBUG_ANALYZER) System.out.println("back from rule ref to " + rr.targetRule); 776 end.noFOLLOW = saveEnd; 778 779 if (p.cycle != null) { 781 tool.error("infinite recursion to rule " + p.cycle + " from rule " + 782 rr.enclosingRuleName, grammar.getFilename(), rr.getLine(), rr.getColumn()); 783 } 784 785 if (p.containsEpsilon()) { 787 if (DEBUG_ANALYZER) 788 System.out.println("rule ref to " + 789 rr.targetRule + " has eps, depth: " + p.epsilonDepth); 790 791 p.resetEpsilon(); 793 795 int[] depths = p.epsilonDepth.toArray(); 797 p.epsilonDepth = null; for (int i = 0; i < depths.length; i++) { 799 int rk = k - (k - depths[i]); 800 Lookahead q = rr.next.look(rk); p.combineWith(q); 802 } 803 } 806 807 return p; 808 } 809 810 public Lookahead look(int k, StringLiteralElement atom) { 811 if (DEBUG_ANALYZER) System.out.println("lookStringLiteral(" + k + "," + atom + ")"); 812 if (lexicalAnalysis) { 813 if (k > atom.processedAtomText.length()) { 815 return atom.next.look(k - atom.processedAtomText.length()); 816 } 817 else { 818 return Lookahead.of(atom.processedAtomText.charAt(k - 1)); 820 } 821 } 822 else { 823 if (k > 1) { 825 return atom.next.look(k - 1); 826 } 827 Lookahead l = Lookahead.of(atom.getType()); 828 if (atom.not) { 829 int maxToken = grammar.tokenManager.maxTokenType(); 831 l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken); 832 } 833 return l; 834 } 835 } 836 837 843 public Lookahead look(int k, SynPredBlock blk) { 844 if (DEBUG_ANALYZER) System.out.println("look=>(" + k + "," + blk + ")"); 845 return blk.next.look(k); 846 } 847 848 public Lookahead look(int k, TokenRangeElement r) { 849 if (DEBUG_ANALYZER) System.out.println("lookTokenRange(" + k + "," + r + ")"); 850 if (k > 1) { 852 return r.next.look(k - 1); 853 } 854 BitSet p = BitSet.of(r.begin); 855 for (int i = r.begin + 1; i <= r.end; i++) { 856 p.add(i); 857 } 858 return new Lookahead(p); 859 } 860 861 public Lookahead look(int k, TreeElement t) { 862 if (DEBUG_ANALYZER) 863 System.out.println("look(" + k + "," + t.root + "[" + t.root.getType() + "])"); 864 if (k > 1) { 865 return t.next.look(k - 1); 866 } 867 Lookahead l = null; 868 if (t.root instanceof WildcardElement) { 869 l = t.root.look(1); } 871 else { 872 l = Lookahead.of(t.root.getType()); 873 if (t.root.not) { 874 int maxToken = grammar.tokenManager.maxTokenType(); 876 l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken); 877 } 878 } 879 return l; 880 } 881 882 public Lookahead look(int k, WildcardElement wc) { 883 if (DEBUG_ANALYZER) System.out.println("look(" + k + "," + wc + ")"); 884 885 if (k > 1) { 887 return wc.next.look(k - 1); 888 } 889 890 BitSet b; 891 if (lexicalAnalysis) { 892 b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone(); 894 } 895 else { 896 b = new BitSet(1); 897 int maxToken = grammar.tokenManager.maxTokenType(); 899 b.notInPlace(Token.MIN_USER_TYPE, maxToken); 900 if (DEBUG_ANALYZER) System.out.println("look(" + k + "," + wc + ") after not: " + b); 901 } 902 903 906 return new Lookahead(b); 907 } 908 909 912 public Lookahead look(int k, ZeroOrMoreBlock blk) { 913 if (DEBUG_ANALYZER) System.out.println("look*(" + k + "," + blk + ")"); 914 Lookahead p = look(k, (AlternativeBlock)blk); 915 Lookahead q = blk.next.look(k); 916 p.combineWith(q); 917 return p; 918 } 919 920 929 public Lookahead look(int k, String rule) { 930 if (DEBUG_ANALYZER) System.out.println("lookRuleName(" + k + "," + rule + ")"); 931 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rule); 932 RuleBlock rb = rs.getBlock(); 933 934 if (rb.lock[k]) { 935 if (DEBUG_ANALYZER) 936 System.out.println("infinite recursion to rule " + rb.getRuleName()); 937 return new Lookahead(rule); 938 } 939 940 if (rb.cache[k] != null) { 942 if (DEBUG_ANALYZER) { 943 System.out.println("found depth " + k + " result in FIRST " + rule + " cache: " + 944 rb.cache[k].toString(",", charFormatter, grammar)); 945 } 946 return (Lookahead)rb.cache[k].clone(); 947 } 948 949 rb.lock[k] = true; 950 Lookahead p = look(k, (RuleBlock)rb); 951 rb.lock[k] = false; 952 953 rb.cache[k] = (Lookahead)p.clone(); 955 if (DEBUG_ANALYZER) { 956 System.out.println("saving depth " + k + " result in FIRST " + rule + " cache: " + 957 rb.cache[k].toString(",", charFormatter, grammar)); 958 } 959 return p; 960 } 961 962 965 public static boolean lookaheadEquivForApproxAndFullAnalysis(Lookahead[] bset, int k) { 966 for (int i = 1; i <= k - 1; i++) { 968 BitSet look = bset[i].fset; 969 if (look.degree() > 1) { 970 return false; 971 } 972 } 973 return true; 974 } 975 976 983 private void removeCompetingPredictionSets(BitSet b, AlternativeElement el) { 984 GrammarElement head = currentBlock.getAlternativeAt(currentBlock.analysisAlt).head; 987 if (head instanceof TreeElement) { 989 if (((TreeElement)head).root != el) { 990 return; 991 } 992 } 993 else if (el != head) { 994 return; 995 } 996 for (int i = 0; i < currentBlock.analysisAlt; i++) { 997 AlternativeElement e = currentBlock.getAlternativeAt(i).head; 998 b.subtractInPlace(e.look(1).fset); 999 } 1000 } 1001 1002 1009 private void removeCompetingPredictionSetsFromWildcard(Lookahead[] look, AlternativeElement el, int k) { 1010 for (int d = 1; d <= k; d++) { 1011 for (int i = 0; i < currentBlock.analysisAlt; i++) { 1012 AlternativeElement e = currentBlock.getAlternativeAt(i).head; 1013 look[d].fset.subtractInPlace(e.look(d).fset); 1014 } 1015 } 1016 } 1017 1018 1019 private void reset() { 1020 grammar = null; 1021 DEBUG_ANALYZER = false; 1022 currentBlock = null; 1023 lexicalAnalysis = false; 1024 } 1025 1026 1027 public void setGrammar(Grammar g) { 1028 if (grammar != null) { 1029 reset(); 1030 } 1031 grammar = g; 1032 1033 lexicalAnalysis = (grammar instanceof LexerGrammar); 1035 DEBUG_ANALYZER = grammar.analyzerDebug; 1036 } 1037 1038 public boolean subruleCanBeInverted(AlternativeBlock blk, boolean forLexer) { 1039 if ( 1040 blk instanceof ZeroOrMoreBlock || 1041 blk instanceof OneOrMoreBlock || 1042 blk instanceof SynPredBlock 1043 ) { 1044 return false; 1045 } 1046 if (blk.alternatives.size() == 0) { 1048 return false; 1049 } 1050 for (int i = 0; i < blk.alternatives.size(); i++) { 1053 Alternative alt = blk.getAlternativeAt(i); 1054 if (alt.synPred != null || alt.semPred != null || alt.exceptionSpec != null) { 1056 return false; 1057 } 1058 AlternativeElement elt = alt.head; 1060 if ( 1061 !( 1062 elt instanceof CharLiteralElement || 1063 elt instanceof TokenRefElement || 1064 elt instanceof CharRangeElement || 1065 elt instanceof TokenRangeElement || 1066 (elt instanceof StringLiteralElement && !forLexer) 1067 ) || 1068 !(elt.next instanceof BlockEndElement) || 1069 elt.getAutoGenType() != GrammarElement.AUTO_GEN_NONE 1070 ) { 1071 return false; 1072 } 1073 } 1074 return true; 1075 } 1076} 1077 | Popular Tags |