fixed a bug where some decisions that could see predicates thought they were LL(1). Added HIT_PRED invalid token type to the lookahead set to indicate we had a predicate; later we wipe out that entire set before returning from "get token lookahead sets".

This commit is contained in:
Terence Parr 2012-06-01 18:09:25 -07:00
parent 5a2fe297e3
commit 5a7b3b0cab
1 changed files with 12 additions and 6 deletions

View File

@ -40,10 +40,10 @@ import java.util.HashSet;
import java.util.Set;
public class LL1Analyzer {
/** Used during LOOK to detect computation cycles. E.g., ()* causes
* infinite loop without it. If we get to same state would be infinite
* loop.
/** Special value added to the lookahead sets to indicate that we hit
* a predicate during analysis if seeThruPreds==false.
*/
public static final int HIT_PRED = Token.INVALID_TYPE;
@NotNull
public final ATN atn;
@ -65,7 +65,11 @@ public class LL1Analyzer {
_LOOK(s.transition(alt - 1).target,
ParserRuleContext.EMPTY,
look[alt], lookBusy, seeThruPreds);
if ( look[alt].size()==0 ) look[alt] = null;
// Wipe out lookahead for this alternative if we found nothing
// or we had a predicate when we !seeThruPreds
if ( look[alt].size()==0 || look[alt].contains(HIT_PRED) ) {
look[alt] = null;
}
}
return look;
}
@ -116,14 +120,16 @@ public class LL1Analyzer {
for (int i=0; i<n; i++) {
Transition t = s.transition(i);
if ( t.getClass() == RuleTransition.class ) {
RuleContext newContext =
new RuleContext(ctx, s.stateNumber);
RuleContext newContext = new RuleContext(ctx, s.stateNumber);
_LOOK(t.target, newContext, look, lookBusy, seeThruPreds);
}
else if ( t instanceof PredicateTransition ) {
if ( seeThruPreds ) {
_LOOK(t.target, ctx, look, lookBusy, seeThruPreds);
}
else {
look.add(HIT_PRED);
}
}
else if ( t.isEpsilon() ) {
_LOOK(t.target, ctx, look, lookBusy, seeThruPreds);