LLkAnalyzer.java
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:36k
源码类别:

编译器/解释器

开发平台:

Others

  1. package antlr;
  2. /* ANTLR Translator Generator
  3.  * Project led by Terence Parr at http://www.jGuru.com
  4.  * Software rights: http://www.antlr.org/RIGHTS.html
  5.  *
  6.  * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/LLkAnalyzer.java#1 $
  7.  */
  8. import antlr.collections.impl.BitSet;
  9. import antlr.collections.impl.Vector;
  10. /**A linear-approximate LL(k) grammar analzyer.
  11.  *
  12.  * All lookahead elements are sets of token types.
  13.  *
  14.  * @author  Terence Parr, John Lilley
  15.  * @version 2.00a
  16.  * @see     antlr.Grammar
  17.  * @see     antlr.Lookahead
  18.  */
  19. public class LLkAnalyzer implements LLkGrammarAnalyzer {
  20. // Set "analyzerDebug" to true
  21. public boolean DEBUG_ANALYZER = false;
  22. private AlternativeBlock currentBlock;
  23. protected Tool tool = null;
  24. protected Grammar grammar = null;
  25. // True if analyzing a lexical grammar
  26. protected boolean lexicalAnalysis = false;
  27. // Used for formatting bit sets in default (Java) format
  28. CharFormatter charFormatter = new JavaCharFormatter();
  29. /** Create an LLk analyzer */
  30. public LLkAnalyzer(Tool tool_) {
  31. tool = tool_;
  32. }
  33. /** Return true if someone used the '.' wildcard default idiom.
  34.  *  Either #(. children) or '.' as an alt by itself.
  35.  */
  36. protected boolean altUsesWildcardDefault(Alternative alt) {
  37. AlternativeElement head = alt.head;
  38. // if element is #(. blah) then check to see if el is root
  39. if (head instanceof TreeElement &&
  40. ((TreeElement) head).root instanceof WildcardElement ) {
  41. return true;
  42. }
  43. if (head instanceof WildcardElement && head. next instanceof BlockEndElement) {
  44. return true;
  45. }
  46. return false;
  47. }
  48. /**Is this block of alternatives LL(k)?  Fill in alternative cache for this block.
  49.  * @return true if the block is deterministic
  50.  */
  51. public boolean deterministic(AlternativeBlock blk) {
  52. /** The lookahead depth for this decision */
  53. int k=1; // start at k=1
  54. if ( DEBUG_ANALYZER ) System.out.println("deterministic("+blk+")");
  55. boolean det = true;
  56. int nalts = blk.alternatives.size();
  57. AlternativeBlock saveCurrentBlock = currentBlock;
  58. Alternative wildcardAlt = null;
  59. currentBlock = blk;
  60. /* don't allow nongreedy (...) blocks */
  61. if ( blk.greedy==false && !(blk instanceof OneOrMoreBlock) && !(blk instanceof ZeroOrMoreBlock) ) {
  62. tool.warning("Being nongreedy only makes sense for (...)+ and (...)*", grammar.getFilename(), blk.getLine());
  63. }
  64. // SPECIAL CASE: only one alternative.  We don't need to check the
  65. // determinism, but other code expects the lookahead cache to be
  66. // set for the single alt.
  67. if ( nalts==1 ) {
  68. AlternativeElement e = blk.getAlternativeAt(0).head;
  69. currentBlock.alti = 0;
  70. blk.getAlternativeAt(0).cache[1] = e.look(1);
  71. blk.getAlternativeAt(0).lookaheadDepth = 1; // set lookahead to LL(1)
  72. currentBlock = saveCurrentBlock;
  73. return true; // always deterministic for one alt
  74. }
  75. outer:
  76. for (int i=0; i<nalts-1; i++) {
  77. currentBlock.alti = i;
  78. currentBlock.analysisAlt = i; // which alt are we analyzing?
  79. currentBlock.altj = i+1; // reset this alt.  Haven't computed yet,
  80. // but we need the alt number.
  81. inner:
  82. // compare against other alternatives with lookahead depth k
  83. for (int j=i+1; j<nalts; j++) {
  84. currentBlock.altj = j;
  85. if ( DEBUG_ANALYZER ) System.out.println("comparing "+i+" against alt "+j);
  86. currentBlock.analysisAlt = j; // which alt are we analyzing?
  87. k = 1; // always attempt minimum lookahead possible.
  88. // check to see if there is a lookahead depth that distinguishes
  89. // between alternatives i and j.
  90. Lookahead[] r = new Lookahead[grammar.maxk+1];
  91. boolean haveAmbiguity;
  92. do {
  93. haveAmbiguity = false;
  94. if ( DEBUG_ANALYZER ) System.out.println("checking depth "+k+"<="+grammar.maxk);
  95. Lookahead p,q;
  96. p = getAltLookahead(blk, i, k);
  97. q = getAltLookahead(blk, j, k);
  98. // compare LOOK(alt i) with LOOK(alt j).  Is there an intersection?
  99. // Lookahead must be disjoint.
  100. if ( DEBUG_ANALYZER ) System.out.println("p is "+p.toString(",", charFormatter, grammar));
  101. if ( DEBUG_ANALYZER ) System.out.println("q is "+q.toString(",", charFormatter, grammar));
  102. // r[i] = p.fset.and(q.fset);
  103. r[k] = p.intersection(q);
  104. if ( DEBUG_ANALYZER ) System.out.println("intersection at depth "+k+" is "+r[k].toString());
  105. if ( !r[k].nil() ) {
  106. haveAmbiguity = true;
  107. k++;
  108. }
  109. // go until no more lookahead to use or no intersection
  110. } while ( haveAmbiguity && k <= grammar.maxk );
  111. Alternative ai = blk.getAlternativeAt(i);
  112. Alternative aj = blk.getAlternativeAt(j);
  113. if ( haveAmbiguity ) {
  114. det = false;
  115. ai.lookaheadDepth = NONDETERMINISTIC;
  116. aj.lookaheadDepth = NONDETERMINISTIC;
  117. /* if ith alt starts with a syntactic predicate, computing the
  118.  * lookahead is still done for code generation, but messages
  119.  * should not be generated when comparing against alt j.
  120.  * Alternatives with syn preds that are unnecessary do
  121.  * not result in syn pred try-blocks.
  122.  */
  123. if ( ai.synPred != null ) {
  124. if ( DEBUG_ANALYZER ) {
  125. System.out.println("alt "+i+" has a syn pred");
  126. }
  127. // The alt with the (...)=> block is nondeterministic for sure.
  128. // If the (...)=> conflicts with alt j, j is nondeterministic.
  129. // This prevents alt j from being in any switch statements.
  130. // move on to next alternative=>no possible ambiguity!
  131. // continue inner;
  132. }
  133. /* if ith alt starts with a semantic predicate, computing the
  134.  * lookahead is still done for code generation, but messages
  135.  * should not be generated when comparing against alt j.
  136.  */
  137. else if ( ai.semPred != null ) {
  138. if ( DEBUG_ANALYZER ) {
  139. System.out.println("alt "+i+" has a sem pred");
  140. }
  141. }
  142. /* if jth alt is exactly the wildcard or wildcard root of tree,
  143.  * then remove elements from alt i lookahead from alt j's lookahead.
  144.  * Don't do an ambiguity warning.
  145.  */
  146. else if ( altUsesWildcardDefault(aj) ) {
  147. // System.out.println("removing pred sets");
  148. // removeCompetingPredictionSetsFromWildcard(aj.cache, aj.head, grammar.maxk);
  149. wildcardAlt = aj;
  150. }
  151. /* If the user specified warnWhenFollowAmbig=false, then we
  152.  * can turn off this warning IFF one of the alts is empty;
  153.  * that is, it points immediately at the end block.
  154.  */
  155. else if ( !blk.warnWhenFollowAmbig &&
  156.  (ai.head instanceof BlockEndElement ||
  157.     aj.head instanceof BlockEndElement) )
  158. {
  159. // System.out.println("ai.head pts to "+ai.head.getClass());
  160. // System.out.println("aj.head pts to "+aj.head.getClass());
  161. }
  162. /* If they have the generateAmbigWarnings option off for the block
  163.  * then don't generate a warning.
  164.  */
  165. else if ( !blk.generateAmbigWarnings ) {
  166. }
  167. /* If greedy=true and *one* empty alt shut off warning. */
  168. else if ( blk.greedySet && blk.greedy &&
  169.   ((ai.head instanceof BlockEndElement &&
  170.    !(aj.head instanceof BlockEndElement)) ||
  171.   (aj.head instanceof BlockEndElement &&
  172.    !(ai.head instanceof BlockEndElement))) ) {
  173. // System.out.println("greedy set to true; one alt empty");
  174. }
  175. /* We have no choice, but to report a nondetermism */
  176. else {
  177. tool.errorHandler.warnAltAmbiguity(
  178. grammar,
  179. blk, // the block
  180. lexicalAnalysis,// true if lexical
  181. grammar.maxk, // depth of ambiguity
  182. r, // set of linear ambiguities
  183. i, // first ambiguous alternative
  184. j // second ambiguous alternative
  185. );
  186. }
  187. }
  188. else {
  189. // a lookahead depth, k, was found where i and j do not conflict
  190. ai.lookaheadDepth = Math.max(ai.lookaheadDepth,k);
  191. aj.lookaheadDepth = Math.max(aj.lookaheadDepth,k);
  192. }
  193. }
  194. }
  195. // finished with block.
  196. // If had wildcard default clause idiom, remove competing lookahead
  197. /*
  198. if ( wildcardAlt!=null ) {
  199. removeCompetingPredictionSetsFromWildcard(wildcardAlt.cache, wildcardAlt.head, grammar.maxk);
  200. }
  201. */
  202. currentBlock = saveCurrentBlock;
  203. return det;
  204. }
  205. /**Is (...)+ block LL(1)?  Fill in alternative cache for this block.
  206.  * @return true if the block is deterministic
  207.  */
  208. public boolean deterministic(OneOrMoreBlock blk) {
  209. if ( DEBUG_ANALYZER ) System.out.println("deterministic(...)+("+blk+")");
  210. AlternativeBlock saveCurrentBlock = currentBlock;
  211. currentBlock = blk;
  212. boolean blkOk = deterministic((AlternativeBlock)blk);
  213. // block has been checked, now check that what follows does not conflict
  214. // with the lookahead of the (...)+ block.
  215. boolean det = deterministicImpliedPath(blk);
  216. currentBlock = saveCurrentBlock;
  217. return det&&blkOk;
  218. }
  219. /**Is (...)* block LL(1)?  Fill in alternative cache for this block.
  220.  * @return true if the block is deterministic
  221.  */
  222. public boolean deterministic(ZeroOrMoreBlock blk) {
  223. if ( DEBUG_ANALYZER ) System.out.println("deterministic(...)*("+blk+")");
  224. AlternativeBlock saveCurrentBlock = currentBlock;
  225. currentBlock = blk;
  226. boolean blkOk = deterministic((AlternativeBlock)blk);
  227. // block has been checked, now check that what follows does not conflict
  228. // with the lookahead of the (...)* block.
  229. boolean det = deterministicImpliedPath(blk);
  230. currentBlock = saveCurrentBlock;
  231. return det&&blkOk;
  232. }
  233.     /**Is this (...)* or (...)+ block LL(k)?
  234.      * @return true if the block is deterministic
  235.      */
  236.     public boolean deterministicImpliedPath(BlockWithImpliedExitPath blk) {
  237. /** The lookahead depth for this decision considering implied exit path */
  238. int k;
  239. boolean det = true;
  240. Vector alts = blk.getAlternatives();
  241. int nalts = alts.size();
  242. currentBlock.altj = -1; // comparing against implicit optional/exit alt
  243. if ( DEBUG_ANALYZER ) System.out.println("deterministicImpliedPath");
  244. for (int i=0; i<nalts; i++) { // check follow against all alts
  245.     Alternative alt = blk.getAlternativeAt(i);
  246.     if ( alt.head instanceof BlockEndElement ) {
  247. tool.warning("empty alternative makes no sense in (...)* or (...)+", grammar.getFilename(), blk.getLine());
  248.     }
  249.     k = 1; // assume eac alt is LL(1) with exit branch
  250.     // check to see if there is a lookahead depth that distinguishes
  251.     // between alternative i and the exit branch.
  252.     Lookahead[] r = new Lookahead[grammar.maxk+1];
  253.     boolean haveAmbiguity;
  254.     do {
  255. haveAmbiguity = false;
  256. if ( DEBUG_ANALYZER ) System.out.println("checking depth "+k+"<="+grammar.maxk);
  257. Lookahead p;
  258. Lookahead follow = blk.next.look(k);
  259. blk.exitCache[k] = follow;
  260. currentBlock.alti = i;
  261. p = getAltLookahead(blk, i, k);
  262. if ( DEBUG_ANALYZER ) System.out.println("follow is "+follow.toString(",", charFormatter, grammar));
  263. if ( DEBUG_ANALYZER ) System.out.println("p is "+p.toString(",", charFormatter, grammar));
  264. //r[k] = follow.fset.and(p.fset);
  265. r[k] = follow.intersection(p);
  266. if ( DEBUG_ANALYZER ) System.out.println("intersection at depth "+k+" is "+r[k]);
  267. if ( !r[k].nil() ) {
  268.     haveAmbiguity = true;
  269.     k++;
  270. }
  271. // go until no more lookahead to use or no intersection
  272.     } while ( haveAmbiguity && k <= grammar.maxk );
  273.     if ( haveAmbiguity )
  274. {
  275.     det = false;
  276.     alt.lookaheadDepth = NONDETERMINISTIC;
  277.     blk.exitLookaheadDepth = NONDETERMINISTIC;
  278.     Alternative ambigAlt = blk.getAlternativeAt(currentBlock.alti);
  279. /* If the user specified warnWhenFollowAmbig=false, then we
  280.  * can turn off this warning.
  281.  */
  282.     if ( !blk.warnWhenFollowAmbig ) {
  283.     }
  284. /* If they have the generateAmbigWarnings option off for the block
  285.  * then don't generate a warning.
  286.  */
  287.     else if ( !blk.generateAmbigWarnings ) {
  288.     }
  289. /* If greedy=true and alt not empty, shut off warning */
  290.     else if ( blk.greedy==true && blk.greedySet &&
  291.       !(ambigAlt.head instanceof BlockEndElement) ) {
  292. if ( DEBUG_ANALYZER ) System.out.println("greedy loop");
  293.     }
  294. /* If greedy=false then shut off warning...will have
  295.  * to add "if FOLLOW break"
  296.  * block during code gen to compensate for removal of warning.
  297.  */
  298.     else if( blk.greedy==false &&
  299.      !(ambigAlt.head instanceof BlockEndElement) ) {
  300. if ( DEBUG_ANALYZER ) System.out.println("nongreedy loop");
  301. // if FOLLOW not single k-string (|set[k]| can
  302. // be > 1 actually) then must warn them that
  303. // loop may terminate incorrectly.
  304. // For example, ('a'..'d')+ ("ad"|"cb")
  305. if ( !lookaheadEquivForApproxAndFullAnalysis(blk.exitCache, grammar.maxk) ) {
  306.     tool.warning(new String[] {
  307. "nongreedy block may exit incorrectly due",
  308.     "tto limitations of linear approximate lookahead (first k-1 sets",
  309.     "tin lookahead not singleton)."},
  310. grammar.getFilename(), blk.getLine());
  311. }
  312.     }
  313. // no choice but to generate a warning
  314.     else {
  315. tool.errorHandler.warnAltExitAmbiguity(
  316.        grammar,
  317.        blk, // the block
  318.        lexicalAnalysis, // true if lexical
  319.        grammar.maxk, // depth of ambiguity
  320.        r, // set of linear ambiguities
  321.        i // ambiguous alternative
  322.        );
  323.     }
  324. }
  325.     else {
  326. alt.lookaheadDepth = Math.max(alt.lookaheadDepth,k);
  327. blk.exitLookaheadDepth = Math.max(blk.exitLookaheadDepth,k);
  328.     }
  329. }
  330. return det;
  331.     }
  332. /**Compute the lookahead set of whatever follows references to
  333.  * the rule associated witht the FOLLOW block.
  334.  */
  335. public Lookahead FOLLOW(int k, RuleEndElement end) {
  336. // what rule are we trying to compute FOLLOW of?
  337. RuleBlock rb = (RuleBlock)end.block;
  338. // rule name is different in lexer
  339. String rule;
  340. if (lexicalAnalysis) {
  341. rule = CodeGenerator.lexerRuleName(rb.getRuleName());
  342. } else {
  343. rule = rb.getRuleName();
  344. }
  345. if ( DEBUG_ANALYZER ) System.out.println("FOLLOW("+k+","+rule+")");
  346. // are we in the midst of computing this FOLLOW already?
  347. if ( end.lock[k] ) {
  348. if ( DEBUG_ANALYZER ) System.out.println("FOLLOW cycle to "+rule);
  349. return new Lookahead(rule);
  350. }
  351. // Check to see if there is cached value
  352. if ( end.cache[k]!=null ) {
  353. if ( DEBUG_ANALYZER ) {
  354. System.out.println("cache entry FOLLOW("+k+") for "+rule+": "+end.cache[k].toString(",", charFormatter, grammar));
  355. }
  356. // if the cache is a complete computation then simply return entry 
  357. if ( end.cache[k].cycle==null ) {
  358. return (Lookahead)end.cache[k].clone();
  359. }
  360. // A cache entry exists, but it is a reference to a cyclic computation.
  361. RuleSymbol rs = (RuleSymbol)grammar.getSymbol(end.cache[k].cycle);
  362. RuleEndElement re = rs.getBlock().endNode;
  363. // The other entry may not exist because it is still being
  364. // computed when this cycle cache entry was found here.
  365. if ( re.cache[k]==null ) {
  366. // return the cycle...that's all we can do at the moment.
  367. return (Lookahead)end.cache[k].clone();
  368. }
  369. else {
  370. // replace this cache entry with the entry from the referenced computation.
  371. // Eventually, this percolates a complete (no cycle reference) cache entry
  372. // to this node (or at least gets it closer and closer).  This is not
  373. // crucial, but makes cache lookup faster as we might have to look up
  374. // lots of cycle references before finding a complete reference.
  375. end.cache[k] = re.cache[k];
  376. // Return the cache entry associated with the cycle reference.
  377. return (Lookahead)re.cache[k].clone();
  378. }
  379. }
  380. end.lock[k] = true; // prevent FOLLOW computation cycles
  381. Lookahead p = new Lookahead();
  382. RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rule);
  383. // Walk list of references to this rule to compute FOLLOW
  384. for (int i=0; i<rs.numReferences(); i++) {
  385. RuleRefElement rr = rs.getReference(i);
  386. if ( DEBUG_ANALYZER ) System.out.println("next["+rule+"] is "+rr.next.toString());
  387. Lookahead q = rr.next.look(k);
  388. if ( DEBUG_ANALYZER ) System.out.println("FIRST of next["+rule+"] ptr is "+q.toString());
  389. /* If there is a cycle then if the cycle is to the rule for
  390.  * this end block, you have a cycle to yourself.  Remove the
  391.  * cycle indication--the lookahead is complete.
  392.  */
  393. if ( q.cycle!=null && q.cycle.equals(rule) ) {
  394. q.cycle = null; // don't want cycle to yourself!
  395. }
  396. // add the lookahead into the current FOLLOW computation set
  397. p.combineWith(q);
  398. if ( DEBUG_ANALYZER ) System.out.println("combined FOLLOW["+rule+"] is "+p.toString());
  399. }
  400. end.lock[k] = false; // we're not doing FOLLOW anymore
  401. // if no rules follow this, it can be a start symbol or called by a start sym.
  402. // set the follow to be end of file.
  403. if ( p.fset.nil() && p.cycle==null ) {
  404. if ( grammar instanceof TreeWalkerGrammar ) {
  405. // Tree grammars don't see EOF, they see end of sibling list or
  406. // "NULL TREE LOOKAHEAD".
  407. p.fset.add(Token.NULL_TREE_LOOKAHEAD);
  408. }
  409. else if ( grammar instanceof LexerGrammar ) {
  410. // Lexical grammars use Epsilon to indicate that the end of rule has been hit
  411. // EOF would be misleading; any character can follow a token rule not just EOF
  412. // as in a grammar (where a start symbol is followed by EOF).  There is no
  413. // sequence info in a lexer between tokens to indicate what is the last token
  414. // to be seen.
  415. // p.fset.add(EPSILON_TYPE);
  416. p.setEpsilon();
  417. }
  418. else {
  419. p.fset.add(Token.EOF_TYPE);
  420. }
  421. }
  422. // Cache the result of the FOLLOW computation
  423. if ( DEBUG_ANALYZER ) {
  424. System.out.println("saving FOLLOW("+k+") for "+rule+": "+p.toString(",", charFormatter, grammar));
  425. }
  426. end.cache[k] = (Lookahead)p.clone();
  427. return p;
  428. }
  429. private Lookahead getAltLookahead(AlternativeBlock blk, int alt, int k) {
  430. Lookahead p;
  431. Alternative a = blk.getAlternativeAt(alt);
  432. AlternativeElement e = a.head;
  433. //System.out.println("getAltLookahead("+k+","+e+"), cache size is "+a.cache.length);
  434. if ( a.cache[k]==null ) {
  435. p = e.look(k);
  436. a.cache[k] = p;
  437. }
  438. else {
  439. p = a.cache[k];
  440. }
  441. return p;
  442. }
  443. /**Actions are ignored */
  444. public Lookahead look(int k, ActionElement action) {
  445. if ( DEBUG_ANALYZER ) System.out.println("lookAction("+k+","+action+")");
  446. return action.next.look(k);
  447. }
  448. /**Combine the lookahead computed for each alternative */
  449. public Lookahead look(int k, AlternativeBlock blk) {
  450. if ( DEBUG_ANALYZER ) System.out.println("lookAltBlk(" + k + "," + blk + ")");
  451. AlternativeBlock saveCurrentBlock = currentBlock;
  452. currentBlock = blk;
  453. Lookahead p = new Lookahead();
  454. for (int i=0; i<blk.alternatives.size(); i++) {
  455. if ( DEBUG_ANALYZER ) System.out.println("alt " + i);
  456. // must set analysis alt
  457. currentBlock.analysisAlt = i;
  458. AlternativeElement elem = blk.getAlternativeAt(i).head;
  459. Lookahead q = elem.look(k);
  460. p.combineWith(q);
  461. }
  462. if (k == 1 && blk.not && subruleCanBeInverted(blk, lexicalAnalysis)) {
  463. // Invert the lookahead set
  464. if (lexicalAnalysis) {
  465. BitSet b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone();
  466. int[] elems = p.fset.toArray();
  467. for (int j = 0; j < elems.length; j++) {
  468. b.remove(elems[j]);
  469. }
  470. p.fset = b;
  471. } else {
  472. p.fset.notInPlace(Token.MIN_USER_TYPE, grammar.tokenManager.maxTokenType());
  473. }
  474. }
  475. currentBlock = saveCurrentBlock;
  476. return p;
  477. }
  478. /**Compute what follows this place-holder node and possibly
  479.  * what begins the associated loop unless the
  480.  * node is locked.
  481.  * <p>
  482.  * if we hit the end of a loop, we have to include
  483.  * what tokens can begin the loop as well.  If the start
  484.  * node is locked, then we simply found an empty path
  485.  * through this subrule while analyzing it.  If the
  486.  * start node is not locked, then this node was hit
  487.  * during a FOLLOW operation and the FIRST of this
  488.  * block must be included in that lookahead computation.
  489.  */
  490. public Lookahead look(int k, BlockEndElement end) {
  491. if ( DEBUG_ANALYZER ) System.out.println("lookBlockEnd("+k+")");
  492. if ( end.lock[k] ) {
  493. // computation in progress => the tokens we would have
  494. // computed (had we not been locked) will be included
  495. // in the set by that computation with the lock on this
  496. // node.
  497. return new Lookahead();
  498. }
  499. end.lock[k] = true;
  500. Lookahead p;
  501. /* Hitting the end of a loop means you can see what begins the loop */
  502. if ( end.block instanceof ZeroOrMoreBlock ||
  503.  end.block instanceof OneOrMoreBlock ) {
  504. // compute what can start the block
  505. p = look(k, end.block);
  506. }
  507. else {
  508. p = new Lookahead();
  509. }
  510. /* Tree blocks do not have any follow because they are children
  511.  * of what surrounds them.  For example, A #(B C) D results in
  512.  * a look() for the TreeElement end of NULL_TREE_LOOKAHEAD, which
  513.  * indicates that nothing can follow the last node of tree #(B C)
  514.  */
  515. if (end.block instanceof TreeElement) {
  516. p.combineWith(Lookahead.of(Token.NULL_TREE_LOOKAHEAD));
  517. }
  518. /* Syntactic predicates such as ( (A)? )=> have no follow per se.
  519.  * We cannot accurately say what would be matched following a
  520.  * syntactic predicate (you MIGHT be ok if you said it was whatever
  521.  * followed the alternative predicted by the predicate).  Hence,
  522.  * (like end-of-token) we return Epsilon to indicate "unknown
  523.  * lookahead."
  524.  */
  525. else if ( end.block instanceof SynPredBlock ) {
  526. p.setEpsilon();
  527. }
  528. // compute what can follow the block
  529. else {
  530. Lookahead q = end.block.next.look(k);
  531. p.combineWith(q);
  532. }
  533. end.lock[k] = false;
  534. return p;
  535. }
  536. /**Return this char as the lookahead if k=1.
  537.  * <p>### Doesn't work for ( 'a' 'b' | 'a' ~'b' ) yet!!!
  538.  * <p>
  539.  * If the atom has the <tt>not</tt> flag on, then
  540.  * create the set complement of the tokenType
  541.  * which is the set of all characters referenced
  542.  * in the grammar with this char turned off.
  543.  * Also remove characters from the set that
  544.  * are currently allocated for predicting
  545.  * previous alternatives.  This avoids ambiguity
  546.  * messages and is more properly what is meant.
  547.  * ( 'a' | ~'a' ) implies that the ~'a' is the
  548.  * "else" clause.
  549.  * <p>
  550.  * NOTE: we do <b>NOT</b> include exit path in
  551.  * the exclusion set. E.g.,
  552.  * ( 'a' | ~'a' )* 'b'
  553.  * should exit upon seeing a 'b' during the loop.
  554.  */
  555. public Lookahead look(int k, CharLiteralElement atom) {
  556. if ( DEBUG_ANALYZER ) System.out.println("lookCharLiteral("+k+","+atom+")");
  557. // Skip until analysis hits k==1 
  558. if ( k>1 ) {
  559. return atom.next.look(k-1);
  560. }
  561. if ( lexicalAnalysis) {
  562. if (atom.not) {
  563. BitSet b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone();
  564. if ( DEBUG_ANALYZER ) System.out.println("charVocab is "+b.toString());
  565. // remove stuff predicted by preceding alts and follow of block
  566. removeCompetingPredictionSets(b, atom);
  567. if ( DEBUG_ANALYZER ) System.out.println("charVocab after removal of prior alt lookahead "+b.toString());
  568. // now remove element that is stated not to be in the set
  569. b.clear(atom.getType());
  570. return new Lookahead(b);
  571. } else {
  572. return Lookahead.of(atom.getType());
  573. }
  574. }
  575. else {
  576. // Should have been avoided by MakeGrammar
  577. tool.panic("Character literal reference found in parser");
  578. // ... so we make the compiler happy
  579. return Lookahead.of(atom.getType());
  580. }
  581. }
  582. public Lookahead look(int k, CharRangeElement r) {
  583. if ( DEBUG_ANALYZER ) System.out.println("lookCharRange("+k+","+r+")");
  584. // Skip until analysis hits k==1 
  585. if ( k>1 ) {
  586. return r.next.look(k-1);
  587. }
  588. BitSet p = BitSet.of(r.begin);
  589. for (int i=r.begin+1; i<=r.end; i++) {
  590. p.add(i);
  591. }
  592. return new Lookahead(p);
  593. }
  594. public Lookahead look(int k, GrammarAtom atom) {
  595. if ( DEBUG_ANALYZER ) System.out.println("look("+k+","+atom+"["+atom.getType()+"])");
  596. if ( lexicalAnalysis ) {
  597. // MakeGrammar should have created a rule reference instead
  598. tool.panic("token reference found in lexer");
  599. }
  600. // Skip until analysis hits k==1 
  601. if ( k>1 ) {
  602. return atom.next.look(k-1);
  603. }
  604. Lookahead l = Lookahead.of(atom.getType());
  605. if (atom.not) {
  606. // Invert the lookahead set against the token vocabulary
  607. int maxToken = grammar.tokenManager.maxTokenType();
  608. l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken);
  609. // remove stuff predicted by preceding alts and follow of block
  610. removeCompetingPredictionSets(l.fset, atom);
  611. }
  612. return l;
  613. }
  614. /**The lookahead of a (...)+ block is the combined lookahead of
  615.  * all alternatives and, if an empty path is found, the lookahead
  616.  * of what follows the block.
  617.  */
  618. public Lookahead look(int k, OneOrMoreBlock blk) {
  619. if ( DEBUG_ANALYZER ) System.out.println("look+"+k+","+blk+")");
  620. Lookahead p = look(k, (AlternativeBlock)blk);
  621. return p;
  622. }
  623. /**Combine the lookahead computed for each alternative.
  624.  * Lock the node so that no other computation may come back
  625.  * on itself--infinite loop.  This also implies infinite left-recursion
  626.  * in the grammar (or an error in this algorithm ;)).
  627.  */
  628. public Lookahead look(int k, RuleBlock blk) {
  629. if ( DEBUG_ANALYZER ) System.out.println("lookRuleBlk("+k+","+blk+")");
  630. Lookahead p = look(k, (AlternativeBlock)blk);
  631. return p;
  632. }
  633. /**If not locked or noFOLLOW set, compute FOLLOW of a rule.
  634.  * <p>
  635.  * TJP says 8/12/99: not true anymore:
  636.  * Lexical rules never compute follow.  They set epsilon and
  637.  * the code generator gens code to check for any character.
  638.  * The code generator must remove the tokens used to predict
  639.  * any previous alts in the same block.
  640.  * <p>
  641.  * When the last node of a rule is reached and noFOLLOW,
  642.  * it implies that a "local" FOLLOW will be computed
  643.  * after this call.  I.e.,
  644.  * <pre>
  645.  * a : b A;
  646.  * b : B | ;
  647.  * c : b C;
  648.  * </pre>
  649.  * Here, when computing the look of rule b from rule a,
  650.  * we want only {B,EPSILON_TYPE} so that look(b A) will
  651.  * be {B,A} not {B,A,C}.
  652.  * <p>
  653.  * if the end block is not locked and the FOLLOW is
  654.  * wanted, the algorithm must compute the lookahead
  655.  * of what follows references to this rule.  If
  656.  * end block is locked, FOLLOW will return an empty set
  657.  * with a cycle to the rule associated with this end block.
  658.  */
  659. public Lookahead look(int k, RuleEndElement end) {
  660. if ( DEBUG_ANALYZER )
  661. System.out.println("lookRuleBlockEnd("+k+"); noFOLLOW="+
  662.    end.noFOLLOW+"; lock is "+end.lock[k]);
  663. if ( /*lexicalAnalysis ||*/ end.noFOLLOW ) {
  664. Lookahead p = new Lookahead();
  665. p.setEpsilon();
  666. p.epsilonDepth = BitSet.of(k);
  667. return p;
  668. }
  669. Lookahead p = FOLLOW(k,end);
  670. return p;
  671. }
  672. /**Compute the lookahead contributed by a rule reference.
  673.  *
  674.  * <p>
  675.  * When computing ruleref lookahead, we don't want the FOLLOW
  676.  * computation done if an empty path exists for the rule.
  677.  * The FOLLOW is too loose of a set...we want only to
  678.  * include the "local" FOLLOW or what can follow this
  679.  * particular ref to the node.  In other words, we use
  680.  * context information to reduce the complexity of the
  681.  * analysis and strengthen the parser.
  682.  *
  683.  * The noFOLLOW flag is used as a means of restricting
  684.  * the FOLLOW to a "local" FOLLOW.  This variable is
  685.  * orthogonal to the <tt>lock</tt> variable that prevents
  686.  * infinite recursion.  noFOLLOW does not care about what k is.
  687.  */
  688. public Lookahead look(int k, RuleRefElement rr) {
  689. if ( DEBUG_ANALYZER ) System.out.println("lookRuleRef("+k+","+rr+")");
  690. RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
  691. if ( rs==null || !rs.defined ) {
  692. tool.error("no definition of rule "+rr.targetRule, grammar.getFilename(), rr.getLine());
  693. return new Lookahead();
  694. }
  695. RuleBlock rb = rs.getBlock();
  696. RuleEndElement end = rb.endNode;
  697. boolean saveEnd = end.noFOLLOW;
  698. end.noFOLLOW = true;
  699. // go off to the rule and get the lookahead (w/o FOLLOW)
  700. Lookahead p = look(k, rr.targetRule);
  701. if ( DEBUG_ANALYZER ) System.out.println("back from rule ref to "+rr.targetRule);
  702. // restore state of end block
  703. end.noFOLLOW = saveEnd;
  704. // check for infinite recursion.  If a cycle is returned: trouble!
  705. if ( p.cycle!=null ) {
  706. tool.error("infinite recursion to rule "+p.cycle+" from rule "+
  707. rr.enclosingRuleName, grammar.getFilename(), rr.getLine());
  708. }
  709. // is the local FOLLOW required?
  710. if ( p.containsEpsilon() ) {
  711. if ( DEBUG_ANALYZER )
  712. System.out.println("rule ref to "+
  713. rr.targetRule+" has eps, depth: "+p.epsilonDepth);
  714. // remove epsilon
  715. p.resetEpsilon();
  716. // fset.clear(EPSILON_TYPE);
  717. // for each lookahead depth that saw epsilon
  718. int[] depths = p.epsilonDepth.toArray();
  719. p.epsilonDepth = null; // clear all epsilon stuff
  720. for (int i=0; i<depths.length; i++) {
  721. int rk = k - (k-depths[i]);
  722. Lookahead q = rr.next.look(rk); // see comments in Lookahead
  723. p.combineWith(q);
  724. }
  725. // note: any of these look() computations for local follow can
  726. // set EPSILON in the set again if the end of this rule is found.
  727. }
  728. return p;
  729. }
  730. public Lookahead look(int k, StringLiteralElement atom) {
  731. if ( DEBUG_ANALYZER ) System.out.println("lookStringLiteral("+k+","+atom+")");
  732. if ( lexicalAnalysis ) {
  733. // need more lookahead than string can provide?
  734. if ( k > atom.processedAtomText.length() ) {
  735. return atom.next.look(k - atom.processedAtomText.length());
  736. }
  737. else {
  738. // get char at lookahead depth k, from the processed literal text
  739. return Lookahead.of(atom.processedAtomText.charAt(k-1));
  740. }
  741. }
  742. else {
  743. // Skip until analysis hits k==1 
  744. if ( k>1 ) {
  745. return atom.next.look(k-1);
  746. }
  747. Lookahead l = Lookahead.of(atom.getType());
  748. if (atom.not) {
  749. // Invert the lookahead set against the token vocabulary
  750. int maxToken = grammar.tokenManager.maxTokenType();
  751. l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken);
  752. }
  753. return l;
  754. }
  755. }
  756. /**The lookahead of a (...)=> block is the lookahead of
  757.  * what follows the block.  By definition, the syntactic
  758.  * predicate block defies static analysis (you want to try it
  759.  * out at run-time).  The LOOK of (a)=>A B is A for LL(1)
  760.  * ### is this even called?
  761.  */
  762. public Lookahead look(int k, SynPredBlock blk) {
  763. if ( DEBUG_ANALYZER ) System.out.println("look=>("+k+","+blk+")");
  764. return blk.next.look(k);
  765. }
  766. public Lookahead look(int k, TokenRangeElement r) {
  767. if ( DEBUG_ANALYZER ) System.out.println("lookTokenRange("+k+","+r+")");
  768. // Skip until analysis hits k==1 
  769. if ( k>1 ) {
  770. return r.next.look(k-1);
  771. }
  772. BitSet p = BitSet.of(r.begin);
  773. for (int i=r.begin+1; i<=r.end; i++) {
  774. p.add(i);
  775. }
  776. return new Lookahead(p);
  777. }
  778. public Lookahead look(int k, TreeElement t) {
  779. if (DEBUG_ANALYZER)
  780. System.out.println("look(" + k + "," + t.root + "[" + t.root.getType() + "])");
  781. if (k > 1) {
  782. return t.next.look(k - 1);
  783. }
  784. Lookahead l = null;
  785. if (t.root instanceof WildcardElement) {
  786. l = t.root.look(1); // compute FIRST set minus previous rows
  787. } else {
  788. l = Lookahead.of(t.root.getType());
  789. if (t.root.not) {
  790. // Invert the lookahead set against the token vocabulary
  791. int maxToken = grammar.tokenManager.maxTokenType();
  792. l.fset.notInPlace(Token.MIN_USER_TYPE, maxToken);
  793. }
  794. }
  795. return l;
  796. }
  797. public Lookahead look(int k, WildcardElement wc) {
  798. if ( DEBUG_ANALYZER ) System.out.println("look(" + k + "," + wc + ")");
  799. // Skip until analysis hits k==1 
  800. if ( k>1 ) {
  801. return wc.next.look(k-1);
  802. }
  803. BitSet b;
  804. if ( lexicalAnalysis ) {
  805. // Copy the character vocabulary
  806. b = (BitSet)((LexerGrammar)grammar).charVocabulary.clone();
  807. }
  808. else {
  809. b = new BitSet(1);
  810. // Invert the lookahead set against the token vocabulary
  811. int maxToken = grammar.tokenManager.maxTokenType();
  812. b.notInPlace(Token.MIN_USER_TYPE, maxToken);
  813. if ( DEBUG_ANALYZER ) System.out.println("look(" + k + "," + wc + ") after not: "+b);
  814. }
  815. // Remove prediction sets from competing alternatives
  816. // removeCompetingPredictionSets(b, wc);
  817. return new Lookahead(b);
  818. }
  819. /** The (...)* element is the combined lookahead of the alternatives and what can
  820.  *  follow the loop.
  821.  */
  822. public Lookahead look(int k, ZeroOrMoreBlock blk) {
  823. if ( DEBUG_ANALYZER ) System.out.println("look*("+k+","+blk+")");
  824. Lookahead p = look(k, (AlternativeBlock)blk);
  825. Lookahead q = blk.next.look(k);
  826. p.combineWith(q);
  827. return p;
  828. }
  829. /**Compute the combined lookahead for all productions of a rule.
  830.  * If the lookahead returns with epsilon, at least one epsilon
  831.  * path exists (one that consumes no tokens).  The noFOLLOW
  832.  * flag being set for this endruleblk, indicates that the
  833.  * a rule ref invoked this rule.
  834.  *
  835.  * Currently only look(RuleRef) calls this.  There is no need
  836.  * for the code generator to call this.
  837.  */
  838. public Lookahead look(int k, String rule) {
  839. if ( DEBUG_ANALYZER ) System.out.println("lookRuleName("+k+","+rule+")");
  840. RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rule);
  841. RuleBlock rb = rs.getBlock();
  842. if ( rb.lock[k] ) {
  843. if ( DEBUG_ANALYZER )
  844. System.out.println("infinite recursion to rule "+rb.getRuleName());
  845. return new Lookahead(rule);
  846. }
  847. // have we computed it before?
  848. if ( rb.cache[k]!=null ) {
  849. if ( DEBUG_ANALYZER ) {
  850. System.out.println("found depth "+k+" result in FIRST "+rule+" cache: "+
  851. rb.cache[k].toString(",", charFormatter, grammar));
  852. }
  853. return (Lookahead)rb.cache[k].clone();
  854. }
  855. rb.lock[k] = true;
  856. Lookahead p = look(k, (RuleBlock)rb);
  857. rb.lock[k] = false;
  858. // cache results
  859. rb.cache[k] = (Lookahead)p.clone();
  860. if ( DEBUG_ANALYZER ) {
  861. System.out.println("saving depth "+k+" result in FIRST "+rule+" cache: "+
  862. rb.cache[k].toString(",", charFormatter, grammar));
  863. }
  864. return p;
  865. }
  866. /** If the first k-1 sets are singleton sets, the appoximate
  867.  *  lookahead analysis is equivalent to full lookahead analysis.
  868.  */
  869. public static boolean lookaheadEquivForApproxAndFullAnalysis(Lookahead[] bset, int k) {
  870. // first k-1 sets degree 1?
  871. for (int i=1; i<=k-1; i++) {
  872. BitSet look = bset[i].fset;
  873. if ( look.degree()>1 ) {
  874. return false;
  875. }
  876. }
  877. return true;
  878. }
  879. /** Remove the prediction sets from preceding alternatives
  880.  * and follow set, but *only* if this element is the first element 
  881.  * of the alternative.  The class members currenBlock and
  882.  * currentBlock.analysisAlt must be set correctly.
  883.  * @param b The prediction bitset to be modified
  884.  * @el The element of interest
  885.  */
  886. private void removeCompetingPredictionSets(BitSet b, AlternativeElement el) {
  887. // Only do this if the element is the first element of the alt, 
  888. // because we are making an implicit assumption that k==1.
  889. GrammarElement head = currentBlock.getAlternativeAt(currentBlock.analysisAlt).head;
  890. // if element is #(. blah) then check to see if el is root
  891. if ( head instanceof TreeElement ) {
  892. if ( ((TreeElement) head).root != el ) {
  893. return;
  894. }
  895. }
  896. else if ( el != head ) {
  897. return;
  898. }
  899. for (int i = 0; i < currentBlock.analysisAlt; i++) {
  900. AlternativeElement e = currentBlock.getAlternativeAt(i).head;
  901. b.subtractInPlace(e.look(1).fset);
  902. }
  903. }
  904. /** Remove the prediction sets from preceding alternatives
  905.  * The class members currenBlock must be set correctly.
  906.  * Remove prediction sets from 1..k.
  907.  * @param look The prediction lookahead to be modified
  908.  * @el The element of interest
  909.  * @k  How deep into lookahead to modify
  910.  */
  911. private void removeCompetingPredictionSetsFromWildcard(Lookahead[] look, AlternativeElement el, int k) {
  912. for (int d = 1; d <= k; d++) {
  913. for (int i = 0; i < currentBlock.analysisAlt; i++) {
  914. AlternativeElement e = currentBlock.getAlternativeAt(i).head;
  915. look[d].fset.subtractInPlace(e.look(d).fset);
  916. }
  917. }
  918. }
  919. /** reset the analyzer so it looks like a new one */
  920. private void reset() {
  921. grammar = null;
  922. DEBUG_ANALYZER = false;
  923. currentBlock = null;
  924. lexicalAnalysis = false;
  925. }
  926. /** Set the grammar for the analyzer */
  927. public void setGrammar(Grammar g) {
  928. if (grammar != null) {
  929. reset();
  930. }
  931. grammar = g;
  932. // Is this lexical?
  933. lexicalAnalysis = (grammar instanceof LexerGrammar);
  934. DEBUG_ANALYZER = grammar.analyzerDebug;
  935. }
  936. public boolean subruleCanBeInverted(AlternativeBlock blk, boolean forLexer)
  937. {
  938. if (
  939. blk instanceof ZeroOrMoreBlock ||
  940. blk instanceof OneOrMoreBlock ||
  941. blk instanceof SynPredBlock
  942. ) {
  943. return false;
  944. }
  945. // Cannot invert an empty subrule
  946. if (blk.alternatives.size() == 0) {
  947. return false;
  948. }
  949. // The block must only contain alternatives with a single element,
  950. // where each element is a char, token, char range, or token range.
  951. for (int i = 0; i < blk.alternatives.size(); i++) {
  952. Alternative alt = blk.getAlternativeAt(i);
  953. // Cannot have anything interesting in the alternative ...
  954. if (alt.synPred != null || alt.semPred != null || alt.exceptionSpec != null) {
  955. return false;
  956. }
  957. // ... and there must be one simple element
  958. AlternativeElement elt = alt.head;
  959. if (
  960. !(
  961. elt instanceof CharLiteralElement ||
  962. elt instanceof TokenRefElement ||
  963. elt instanceof CharRangeElement ||
  964. elt instanceof TokenRangeElement ||
  965. (elt instanceof StringLiteralElement && !forLexer)
  966. ) ||
  967. !(elt.next instanceof BlockEndElement) ||
  968. elt.getAutoGenType() != GrammarElement.AUTO_GEN_NONE
  969. ) {
  970. return false;
  971. }
  972. }
  973. return true;
  974. }
  975. }