1 package persistence.antlr; 2 3 8 9 import persistence.antlr.collections.impl.BitSet; 10 import persistence.antlr.collections.impl.Vector; 11 12 20 public class LLkAnalyzer implements LLkGrammarAnalyzer { 21 public boolean DEBUG_ANALYZER = false; 23 private AlternativeBlock currentBlock; 24 protected Tool tool = null; 25 protected Grammar grammar = null; 26 protected boolean lexicalAnalysis = false; 28 CharFormatter charFormatter = new JavaCharFormatter(); 30 31 32 public LLkAnalyzer(Tool tool_) { 33 tool = tool_; 34 } 35 36 39 protected boolean altUsesWildcardDefault(Alternative alt) { 40 AlternativeElement head = alt.head; 41 if (head instanceof TreeElement && 43 ((TreeElement)head).root instanceof WildcardElement) { 44 return true; 45 } 46 if (head instanceof WildcardElement && head.next instanceof BlockEndElement) { 47 return true; 48 } 49 return false; 50 } 51 52 55 public boolean deterministic(AlternativeBlock blk) { 56 57 int k = 1; if (DEBUG_ANALYZER) System.out.println("deterministic(" + blk + ")"); 59 boolean det = true; 60 int nalts = blk.alternatives.size(); 61 AlternativeBlock saveCurrentBlock = currentBlock; 62 Alternative wildcardAlt = null; 63 currentBlock = blk; 64 65 66 if (blk.greedy == false && !(blk instanceof OneOrMoreBlock) && !(blk instanceof ZeroOrMoreBlock)) { 67 tool.warning("Being nongreedy only makes sense for (...)+ and (...)*", grammar.getFilename(), blk.getLine(), blk.getColumn()); 68 } 69 70 if (nalts == 1) { 74 AlternativeElement e = blk.getAlternativeAt(0).head; 75 currentBlock.alti = 0; 76 blk.getAlternativeAt(0).cache[1] = e.look(1); 77 blk.getAlternativeAt(0).lookaheadDepth = 1; currentBlock = saveCurrentBlock; 79 return true; } 81 82 outer: 83 for (int i = 0; i < nalts - 1; i++) { 84 currentBlock.alti = i; 85 currentBlock.analysisAlt = i; currentBlock.altj = i + 1; inner: 89 for (int j = i + 1; j < nalts; j++) { 91 currentBlock.altj = j; 92 if (DEBUG_ANALYZER) System.out.println("comparing " + i + " against alt " + j); 93 currentBlock.analysisAlt = j; k = 1; 96 Lookahead[] r = new Lookahead[grammar.maxk + 1]; 99 boolean haveAmbiguity; 100 do { 101 haveAmbiguity = false; 102 if (DEBUG_ANALYZER) System.out.println("checking depth " + k + "<=" + grammar.maxk); 103 Lookahead p,q; 104 p = getAltLookahead(blk, i, k); 105 q = getAltLookahead(blk, j, k); 106 107 if (DEBUG_ANALYZER) System.out.println("p is " + p.toString(",", charFormatter, grammar)); 110 if (DEBUG_ANALYZER) System.out.println("q is " + q.toString(",", charFormatter, grammar)); 111 r[k] = p.intersection(q); 113 if (DEBUG_ANALYZER) System.out.println("intersection at depth " + k + " is " + r[k].toString()); 114 if (!r[k].nil()) { 115 haveAmbiguity = true; 116 k++; 117 } 118 } while (haveAmbiguity && k <= grammar.maxk); 120 121 Alternative ai = blk.getAlternativeAt(i); 122 Alternative aj = blk.getAlternativeAt(j); 123 if (haveAmbiguity) { 124 det = false; 125 ai.lookaheadDepth = NONDETERMINISTIC; 126 aj.lookaheadDepth = NONDETERMINISTIC; 127 128 134 if (ai.synPred != null) { 135 if (DEBUG_ANALYZER) { 136 System.out.println("alt " + i + " has a syn pred"); 137 } 138 } 144 145 149 else if (ai.semPred != null) { 150 if (DEBUG_ANALYZER) { 151 System.out.println("alt " + i + " has a sem pred"); 152 } 153 } 154 155 159 else if (altUsesWildcardDefault(aj)) { 160 wildcardAlt = aj; 163 } 164 165 169 else if (!blk.warnWhenFollowAmbig && 170 (ai.head instanceof BlockEndElement || 171 aj.head instanceof BlockEndElement)) { 172 } 175 176 179 else if (!blk.generateAmbigWarnings) { 180 } 181 182 183 else if (blk.greedySet && blk.greedy && 184 ((ai.head instanceof BlockEndElement && 185 !(aj.head instanceof BlockEndElement)) || 186 (aj.head instanceof BlockEndElement && 187 !(ai.head instanceof BlockEndElement)))) { 188 } 190 191 192 193 else { 194 tool.errorHandler.warnAltAmbiguity( 195 grammar, 196 blk, lexicalAnalysis, grammar.maxk, r, i, j ); 203 } 204 } 205 else { 206 ai.lookaheadDepth = Math.max(ai.lookaheadDepth, k); 208 aj.lookaheadDepth = Math.max(aj.lookaheadDepth, k); 209 } 210 } 211 } 212 213 215 221 222 currentBlock = saveCurrentBlock; 223 return det; 224 } 225 226 229 public boolean deterministic(OneOrMoreBlock blk) { 230 if (DEBUG_ANALYZER) System.out.println("deterministic(...)+(" + blk + ")"); 231 AlternativeBlock saveCurrentBlock = currentBlock; 232 currentBlock = blk; 233 boolean blkOk = deterministic((AlternativeBlock)blk); 234 boolean det = deterministicImpliedPath(blk); 237 currentBlock = saveCurrentBlock; 238 return det && blkOk; 239 } 240 241 244 public boolean deterministic(ZeroOrMoreBlock blk) { 245 if (DEBUG_ANALYZER) System.out.println("deterministic(...)*(" + blk + ")"); 246 AlternativeBlock saveCurrentBlock = currentBlock; 247 currentBlock = blk; 248 boolean blkOk = deterministic((AlternativeBlock)blk); 249 boolean det = deterministicImpliedPath(blk); 252 currentBlock = saveCurrentBlock; 253 return det && blkOk; 254 } 255 256 259 public boolean deterministicImpliedPath(BlockWithImpliedExitPath blk) { 260 261 int k; 262 boolean det = true; 263 Vector alts = blk.getAlternatives(); 264 int nalts = alts.size(); 265 currentBlock.altj = -1; 267 if (DEBUG_ANALYZER) System.out.println("deterministicImpliedPath"); 268 for (int i = 0; i < nalts; i++) { Alternative alt = blk.getAlternativeAt(i); 270 271 if (alt.head instanceof BlockEndElement) { 272 tool.warning("empty alternative makes no sense in (...)* or (...)+", grammar.getFilename(), blk.getLine(), blk.getColumn()); 273 } 274 275 k = 1; Lookahead[] r = new Lookahead[grammar.maxk + 1]; 279 boolean haveAmbiguity; 280 do { 281 haveAmbiguity = false; 282 if (DEBUG_ANALYZER) System.out.println("checking depth " + k + "<=" + grammar.maxk); 283 Lookahead p; 284 Lookahead follow = blk.next.look(k); 285 blk.exitCache[k] = follow; 286 currentBlock.alti = i; 287 p = getAltLookahead(blk, i, k); 288 289 if (DEBUG_ANALYZER) System.out.println("follow is " + follow.toString(",", charFormatter, grammar)); 290 if (DEBUG_ANALYZER) System.out.println("p is " + p.toString(",", charFormatter, grammar)); 291 r[k] = follow.intersection(p); 293 if (DEBUG_ANALYZER) System.out.println("intersection at depth " + k + " is " + r[k]); 294 if (!r[k].nil()) { 295 haveAmbiguity = true; 296 k++; 297 } 298 } while (haveAmbiguity && k <= grammar.maxk); 300 301 if (haveAmbiguity) { 302 det = false; 303 alt.lookaheadDepth = NONDETERMINISTIC; 304 blk.exitLookaheadDepth = NONDETERMINISTIC; 305 Alternative ambigAlt = blk.getAlternativeAt(currentBlock.alti); 306 307 310 if (!blk.warnWhenFollowAmbig) { 311 } 312 313 316 else if (!blk.generateAmbigWarnings) { 317 } 318 319 320 else if (blk.greedy == true && blk.greedySet && 321 !(ambigAlt.head instanceof BlockEndElement)) { 322 if (DEBUG_ANALYZER) System.out.println("greedy loop"); 323 } 324 325 329 else if (blk.greedy == false && 330 !(ambigAlt.head instanceof BlockEndElement)) { 331 if (DEBUG_ANALYZER) System.out.println("nongreedy loop"); 332 if (!lookaheadEquivForApproxAndFullAnalysis(blk.exitCache, grammar.maxk)) { 337 tool.warning(new String []{ 338 "nongreedy block may exit incorrectly due", 339 "\tto limitations of linear approximate lookahead (first k-1 sets", 340 "\tin lookahead not singleton)."}, 341 grammar.getFilename(), blk.getLine(), blk.getColumn()); 342 } 343 } 344 345 else { 347 tool.errorHandler.warnAltExitAmbiguity( 348 grammar, 349 blk, lexicalAnalysis, grammar.maxk, r, i ); 355 } 356 } 357 else { 358 alt.lookaheadDepth = Math.max(alt.lookaheadDepth, k); 359 blk.exitLookaheadDepth = Math.max(blk.exitLookaheadDepth, k); 360 } 361 } 362 return det; 363 } 364 365 368 public Lookahead FOLLOW(int k, RuleEndElement end) { 369 RuleBlock rb = (RuleBlock)end.block; 371 String rule; 373 if (lexicalAnalysis) { 374 rule = CodeGenerator.encodeLexerRuleName(rb.getRuleName()); 375 } 376 else { 377 rule = rb.getRuleName(); 378 } 379 380 if (DEBUG_ANALYZER) System.out.println("FOLLOW(" + k + "," + rule + ")"); 381 382 if (end.lock[k]) { 384 if (DEBUG_ANALYZER) System.out.println("FOLLOW cycle to " + rule); 385 return new Lookahead(rule); 386 } 387 388 if (end.cache[k] != null) { 390 if (DEBUG_ANALYZER) { 391 System.out.println("cache entry FOLLOW(" + k + ") for " + rule + ": " + end.cache[k].toString(",", charFormatter, grammar)); 392 } 393 if (end.cache[k].cycle == null) { 395 return (Lookahead)end.cache[k].clone(); 396 } 397 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(end.cache[k].cycle); 399 RuleEndElement re = rs.getBlock().endNode; 400 if (re.cache[k] == null) { 403 return (Lookahead)end.cache[k].clone(); 405 } 406 else { 407 if (DEBUG_ANALYZER) { 408 System.out.println("combining FOLLOW(" + k + ") for " + rule + ": from "+end.cache[k].toString(",", charFormatter, grammar) + " with FOLLOW for "+((RuleBlock)re.block).getRuleName()+": "+re.cache[k].toString(",", charFormatter, grammar)); 409 } 410 if ( re.cache[k].cycle==null ) { 412 end.cache[k].combineWith(re.cache[k]); 416 end.cache[k].cycle = null; } 418 else { 419 Lookahead refFOLLOW = FOLLOW(k, re); 424 end.cache[k].combineWith( refFOLLOW ); 425 end.cache[k].cycle = refFOLLOW.cycle; 427 } 428 if (DEBUG_ANALYZER) { 429 System.out.println("saving FOLLOW(" + k + ") for " + rule + ": from "+end.cache[k].toString(",", charFormatter, grammar)); 430 } 431 return (Lookahead)end.cache[k].clone(); 434 } 435 } 436 437 end.lock[k] = true; 439 Lookahead p = new Lookahead(); 440 441 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rule); 442 443 for (int i = 0; i < rs.numReferences(); i++) { 445 RuleRefElement rr = rs.getReference(i); 446 if (DEBUG_ANALYZER) System.out.println("next[" + rule + "] is " + rr.next.toString()); 447 Lookahead q = rr.next.look(k); 448 if (DEBUG_ANALYZER) System.out.println("FIRST of next[" + rule + "] ptr is " + q.toString()); 449 453 if (q.cycle != null && q.cycle.equals(rule)) { 454 q.cycle = null; } 456 p.combineWith(q); 458 if (DEBUG_ANALYZER) System.out.println("combined FOLLOW[" + rule + "] is " + p.toString()); 459 } 460 461 end.lock[k] = false; 463 if (p.fset.nil() && p.cycle == null) { 466 if (grammar instanceof TreeWalkerGrammar) { 467 p.fset.add(Token.NULL_TREE_LOOKAHEAD); 470 } 471 else if (grammar instanceof LexerGrammar) { 472 p.setEpsilon(); 479 } 480 else { 481 p.fset.add(Token.EOF_TYPE); 482 } 483 } 484 485 if (DEBUG_ANALYZER) { 487 System.out.println("saving FOLLOW(" + k + ") for " + rule + ": " + p.toString(",", charFormatter, grammar)); 488 } 489 end.cache[k] = (Lookahead)p.clone(); 490 491 return p; 492 } 493 494 private Lookahead getAltLookahead(AlternativeBlock blk, int alt, int k) { 495 Lookahead p; 496 Alternative a = blk.getAlternativeAt(alt); 497 AlternativeElement e = a.head; 498 if (a.cache[k] == null) { 500 p = e.look(k); 501 a.cache[k] = p; 502 } 503 else { 504 p = a.cache[k]; 505 } 506 return p; 507 } 508 509 510 public Lookahead look(int k, ActionElement action) { 511 if (DEBUG_ANALYZER) System.out.println("lookAction(" + k + "," + action + ")"); 512 return action.next.look(k); 513 } 514 515 516 public Lookahead look(int k, AlternativeBlock blk) { 517 if (DEBUG_ANALYZER) System.out.println("lookAltBlk(" + k + "," + blk + ")"); 518 AlternativeBlock saveCurrentBlock = currentBlock; 519 currentBlock = blk; 520 Lookahead p = new Lookahead(); 521 for (int i = 0; i < blk.alternatives.size(); i++) { 522 if (DEBUG_ANALYZER) System.out.println("alt " + i + " of " + blk); 523 currentBlock.analysisAlt = i; 525 Alternative alt = blk.getAlternativeAt(i); 526 AlternativeElement elem = alt.head; 527 if (DEBUG_ANALYZER) { 528 if (alt.head == alt.tail) { 529 System.out.println("alt " + i + " is empty"); 530 } 531 } 532 Lookahead q = elem.look(k); 533 p.combineWith(q); 534 } 535 if (k == 1 && blk.not && subruleCanBeInverted(blk, lexicalAnalysis)) { 536 if (lexicalAnalysis) { 538 BitSet b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone(); 539 int[] elems = p.fset.toArray(); 540 for (int j = 0; j < elems.length; j++) { 541 b.remove(elems[j]); 542 } 543 p.fset = b; 544 } 545 else { 546 p.fset.notInPlace(Token.MIN_USER_TYPE, grammar.tokenManager.maxTokenType()); 547 } 548 } 549 currentBlock = saveCurrentBlock; 550 return p; 551 } 552 553 565 public Lookahead look(int k, BlockEndElement end) { 566 if (DEBUG_ANALYZER) System.out.println("lookBlockEnd(" + k + ", " + end.block + "); lock is " + end.lock[k]); 567 if (end.lock[k]) { 568 return new Lookahead(); 573 } 574 575 Lookahead p; 576 577 578 if (end.block instanceof ZeroOrMoreBlock || 579 end.block instanceof OneOrMoreBlock) { 580 end.lock[k] = true; 584 p = look(k, end.block); 585 end.lock[k] = false; 586 } 587 else { 588 p = new Lookahead(); 589 } 590 591 596 if (end.block instanceof TreeElement) { 597 p.combineWith(Lookahead.of(Token.NULL_TREE_LOOKAHEAD)); 598 } 599 600 607 else if (end.block instanceof SynPredBlock) { 608 p.setEpsilon(); 609 } 610 611 else { 613 Lookahead q = end.block.next.look(k); 614 p.combineWith(q); 615 } 616 617 return p; 618 } 619 620 639 public Lookahead look(int k, CharLiteralElement atom) { 640 if (DEBUG_ANALYZER) System.out.println("lookCharLiteral(" + k + "," + atom + ")"); 641 if (k > 1) { 643 return atom.next.look(k - 1); 644 } 645 if (lexicalAnalysis) { 646 if (atom.not) { 647 BitSet b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone(); 648 if (DEBUG_ANALYZER) System.out.println("charVocab is " + b.toString()); 649 removeCompetingPredictionSets(b, atom); 651 if (DEBUG_ANALYZER) System.out.println("charVocab after removal of prior alt lookahead " + b.toString()); 652 b.clear(atom.getType()); 654 return new Lookahead(b); 655 } 656 else { 657 return Lookahead.of(atom.getType()); 658 } 659 } 660 else { 661 tool.panic("Character literal reference found in parser"); 663 return Lookahead.of(atom.getType()); 665 } 666 } 667 668 public Lookahead look(int k, CharRangeElement r) { 669 if (DEBUG_ANALYZER) System.out.println("lookCharRange(" + k + "," + r + ")"); 670 if (k > 1) { 672 return r.next.look(k - 1); 673 } 674 BitSet p = BitSet.of(r.begin); 675 for (int i = r.begin + 1; i <= r.end; i++) { 676 p.add(i); 677 } 678 return new Lookahead(p); 679 } 680 681 public Lookahead look(int k, GrammarAtom atom) { 682 if (DEBUG_ANALYZER) System.out.println("look(" + k + "," + atom + "[" + atom.getType() + "])"); 683 684 if (lexicalAnalysis) { 685 tool.panic("token reference found in lexer"); 687 } 688 if (k > 1) { 690 return atom.next.look(k - 1); 691 } 692 Lookahead l = Lookahead.of(atom.getType()); 693 if (atom.not) { 694 int maxToken = grammar.tokenManager.maxTokenType(); 696 l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken); 697 removeCompetingPredictionSets(l.fset, atom); 699 } 700 return l; 701 } 702 703 707 public Lookahead look(int k, OneOrMoreBlock blk) { 708 if (DEBUG_ANALYZER) System.out.println("look+" + k + "," + blk + ")"); 709 Lookahead p = look(k, (AlternativeBlock)blk); 710 return p; 711 } 712 713 718 public Lookahead look(int k, RuleBlock blk) { 719 if (DEBUG_ANALYZER) System.out.println("lookRuleBlk(" + k + "," + blk + ")"); 720 Lookahead p = look(k, (AlternativeBlock)blk); 721 return p; 722 } 723 724 750 public Lookahead look(int k, RuleEndElement end) { 751 if (DEBUG_ANALYZER) 752 System.out.println("lookRuleBlockEnd(" + k + "); noFOLLOW=" + 753 end.noFOLLOW + "; lock is " + end.lock[k]); 754 if ( end.noFOLLOW) { 755 Lookahead p = new Lookahead(); 756 p.setEpsilon(); 757 p.epsilonDepth = BitSet.of(k); 758 return p; 759 } 760 Lookahead p = FOLLOW(k, end); 761 return p; 762 } 763 764 780 public Lookahead look(int k, RuleRefElement rr) { 781 if (DEBUG_ANALYZER) System.out.println("lookRuleRef(" + k + "," + rr + ")"); 782 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule); 783 if (rs == null || !rs.defined) { 784 tool.error("no definition of rule " + rr.targetRule, grammar.getFilename(), rr.getLine(), rr.getColumn()); 785 return new Lookahead(); 786 } 787 RuleBlock rb = rs.getBlock(); 788 RuleEndElement end = rb.endNode; 789 boolean saveEnd = end.noFOLLOW; 790 end.noFOLLOW = true; 791 Lookahead p = look(k, rr.targetRule); 793 if (DEBUG_ANALYZER) System.out.println("back from rule ref to " + rr.targetRule); 794 end.noFOLLOW = saveEnd; 796 797 if (p.cycle != null) { 799 tool.error("infinite recursion to rule " + p.cycle + " from rule " + 800 rr.enclosingRuleName, grammar.getFilename(), rr.getLine(), rr.getColumn()); 801 } 802 803 if (p.containsEpsilon()) { 805 if (DEBUG_ANALYZER) 806 System.out.println("rule ref to " + 807 rr.targetRule + " has eps, depth: " + p.epsilonDepth); 808 809 p.resetEpsilon(); 811 813 int[] depths = p.epsilonDepth.toArray(); 815 p.epsilonDepth = null; for (int i = 0; i < depths.length; i++) { 817 int rk = k - (k - depths[i]); 818 Lookahead q = rr.next.look(rk); p.combineWith(q); 820 } 821 } 824 825 return p; 826 } 827 828 public Lookahead look(int k, StringLiteralElement atom) { 829 if (DEBUG_ANALYZER) System.out.println("lookStringLiteral(" + k + "," + atom + ")"); 830 if (lexicalAnalysis) { 831 if (k > atom.processedAtomText.length()) { 833 return atom.next.look(k - atom.processedAtomText.length()); 834 } 835 else { 836 return Lookahead.of(atom.processedAtomText.charAt(k - 1)); 838 } 839 } 840 else { 841 if (k > 1) { 843 return atom.next.look(k - 1); 844 } 845 Lookahead l = Lookahead.of(atom.getType()); 846 if (atom.not) { 847 int maxToken = grammar.tokenManager.maxTokenType(); 849 l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken); 850 } 851 return l; 852 } 853 } 854 855 861 public Lookahead look(int k, SynPredBlock blk) { 862 if (DEBUG_ANALYZER) System.out.println("look=>(" + k + "," + blk + ")"); 863 return blk.next.look(k); 864 } 865 866 public Lookahead look(int k, TokenRangeElement r) { 867 if (DEBUG_ANALYZER) System.out.println("lookTokenRange(" + k + "," + r + ")"); 868 if (k > 1) { 870 return r.next.look(k - 1); 871 } 872 BitSet p = BitSet.of(r.begin); 873 for (int i = r.begin + 1; i <= r.end; i++) { 874 p.add(i); 875 } 876 return new Lookahead(p); 877 } 878 879 public Lookahead look(int k, TreeElement t) { 880 if (DEBUG_ANALYZER) 881 System.out.println("look(" + k + "," + t.root + "[" + t.root.getType() + "])"); 882 if (k > 1) { 883 return t.next.look(k - 1); 884 } 885 Lookahead l = null; 886 if (t.root instanceof WildcardElement) { 887 l = t.root.look(1); } 889 else { 890 l = Lookahead.of(t.root.getType()); 891 if (t.root.not) { 892 int maxToken = grammar.tokenManager.maxTokenType(); 894 l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken); 895 } 896 } 897 return l; 898 } 899 900 public Lookahead look(int k, WildcardElement wc) { 901 if (DEBUG_ANALYZER) System.out.println("look(" + k + "," + wc + ")"); 902 903 if (k > 1) { 905 return wc.next.look(k - 1); 906 } 907 908 BitSet b; 909 if (lexicalAnalysis) { 910 b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone(); 912 } 913 else { 914 b = new BitSet(1); 915 int maxToken = grammar.tokenManager.maxTokenType(); 917 b.notInPlace(Token.MIN_USER_TYPE, maxToken); 918 if (DEBUG_ANALYZER) System.out.println("look(" + k + "," + wc + ") after not: " + b); 919 } 920 921 924 return new Lookahead(b); 925 } 926 927 930 public Lookahead look(int k, ZeroOrMoreBlock blk) { 931 if (DEBUG_ANALYZER) System.out.println("look*(" + k + "," + blk + ")"); 932 Lookahead p = look(k, (AlternativeBlock)blk); 933 Lookahead q = blk.next.look(k); 934 p.combineWith(q); 935 return p; 936 } 937 938 947 public Lookahead look(int k, String rule) { 948 if (DEBUG_ANALYZER) System.out.println("lookRuleName(" + k + "," + rule + ")"); 949 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rule); 950 RuleBlock rb = rs.getBlock(); 951 952 if (rb.lock[k]) { 953 if (DEBUG_ANALYZER) 954 System.out.println("infinite recursion to rule " + rb.getRuleName()); 955 return new Lookahead(rule); 956 } 957 958 if (rb.cache[k] != null) { 960 if (DEBUG_ANALYZER) { 961 System.out.println("found depth " + k + " result in FIRST " + rule + " cache: " + 962 rb.cache[k].toString(",", charFormatter, grammar)); 963 } 964 return (Lookahead)rb.cache[k].clone(); 965 } 966 967 rb.lock[k] = true; 968 Lookahead p = look(k, (RuleBlock)rb); 969 rb.lock[k] = false; 970 971 rb.cache[k] = (Lookahead)p.clone(); 973 if (DEBUG_ANALYZER) { 974 System.out.println("saving depth " + k + " result in FIRST " + rule + " cache: " + 975 rb.cache[k].toString(",", charFormatter, grammar)); 976 } 977 return p; 978 } 979 980 983 public static boolean lookaheadEquivForApproxAndFullAnalysis(Lookahead[] bset, int k) { 984 for (int i = 1; i <= k - 1; i++) { 986 BitSet look = bset[i].fset; 987 if (look.degree() > 1) { 988 return false; 989 } 990 } 991 return true; 992 } 993 994 1001 private void removeCompetingPredictionSets(BitSet b, AlternativeElement el) { 1002 GrammarElement head = currentBlock.getAlternativeAt(currentBlock.analysisAlt).head; 1005 if (head instanceof TreeElement) { 1007 if (((TreeElement)head).root != el) { 1008 return; 1009 } 1010 } 1011 else if (el != head) { 1012 return; 1013 } 1014 for (int i = 0; i < currentBlock.analysisAlt; i++) { 1015 AlternativeElement e = currentBlock.getAlternativeAt(i).head; 1016 b.subtractInPlace(e.look(1).fset); 1017 } 1018 } 1019 1020 1027 private void removeCompetingPredictionSetsFromWildcard(Lookahead[] look, AlternativeElement el, int k) { 1028 for (int d = 1; d <= k; d++) { 1029 for (int i = 0; i < currentBlock.analysisAlt; i++) { 1030 AlternativeElement e = currentBlock.getAlternativeAt(i).head; 1031 look[d].fset.subtractInPlace(e.look(d).fset); 1032 } 1033 } 1034 } 1035 1036 1037 private void reset() { 1038 grammar = null; 1039 DEBUG_ANALYZER = false; 1040 currentBlock = null; 1041 lexicalAnalysis = false; 1042 } 1043 1044 1045 public void setGrammar(Grammar g) { 1046 if (grammar != null) { 1047 reset(); 1048 } 1049 grammar = g; 1050 1051 lexicalAnalysis = (grammar instanceof LexerGrammar); 1053 DEBUG_ANALYZER = grammar.analyzerDebug; 1054 } 1055 1056 public boolean subruleCanBeInverted(AlternativeBlock blk, boolean forLexer) { 1057 if ( 1058 blk instanceof ZeroOrMoreBlock || 1059 blk instanceof OneOrMoreBlock || 1060 blk instanceof SynPredBlock 1061 ) { 1062 return false; 1063 } 1064 if (blk.alternatives.size() == 0) { 1066 return false; 1067 } 1068 for (int i = 0; i < blk.alternatives.size(); i++) { 1071 Alternative alt = blk.getAlternativeAt(i); 1072 if (alt.synPred != null || alt.semPred != null || alt.exceptionSpec != null) { 1074 return false; 1075 } 1076 AlternativeElement elt = alt.head; 1078 if ( 1079 !( 1080 elt instanceof CharLiteralElement || 1081 elt instanceof TokenRefElement || 1082 elt instanceof CharRangeElement || 1083 elt instanceof TokenRangeElement || 1084 (elt instanceof StringLiteralElement && !forLexer) 1085 ) || 1086 !(elt.next instanceof BlockEndElement) || 1087 elt.getAutoGenType() != GrammarElement.AUTO_GEN_NONE 1088 ) { 1089 return false; 1090 } 1091 } 1092 return true; 1093 } 1094} 1095 | Popular Tags |