Store return states instead of invoking states in PredictionContext instances

This commit is contained in:
Sam Harwell 2012-11-01 13:35:55 -05:00
parent 2ce42f46f8
commit c2722b127a
5 changed files with 23 additions and 24 deletions

View File

@ -318,7 +318,8 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
// is free to conjure up and insert the missing token // is free to conjure up and insert the missing token
ATNState currentState = recognizer.getInterpreter().atn.states.get(recognizer._ctx.s); ATNState currentState = recognizer.getInterpreter().atn.states.get(recognizer._ctx.s);
ATNState next = currentState.transition(0).target; ATNState next = currentState.transition(0).target;
IntervalSet expectingAtLL2 = recognizer.getInterpreter().atn.nextTokens(next, recognizer._ctx); ATN atn = recognizer.getInterpreter().atn;
IntervalSet expectingAtLL2 = atn.nextTokens(next, recognizer._ctx);
// System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames())); // System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames()));
if ( expectingAtLL2.contains(currentSymbolType) ) { if ( expectingAtLL2.contains(currentSymbolType) ) {
reportMissingToken(recognizer); reportMissingToken(recognizer);

View File

@ -80,7 +80,7 @@ public class LL1Analyzer {
public IntervalSet LOOK(@NotNull ATNState s, @Nullable RuleContext ctx) { public IntervalSet LOOK(@NotNull ATNState s, @Nullable RuleContext ctx) {
IntervalSet r = new IntervalSet(); IntervalSet r = new IntervalSet();
boolean seeThruPreds = true; // ignore preds; get all lookahead boolean seeThruPreds = true; // ignore preds; get all lookahead
_LOOK(s, PredictionContext.fromRuleContext(ctx), _LOOK(s, PredictionContext.fromRuleContext(s.atn, ctx),
r, new HashSet<ATNConfig>(), seeThruPreds); r, new HashSet<ATNConfig>(), seeThruPreds);
return r; return r;
} }
@ -109,11 +109,9 @@ public class LL1Analyzer {
if ( ctx != PredictionContext.EMPTY ) { if ( ctx != PredictionContext.EMPTY ) {
// run thru all possible stack tops in ctx // run thru all possible stack tops in ctx
for (SingletonPredictionContext p : ctx) { for (SingletonPredictionContext p : ctx) {
ATNState invokingState = atn.states.get(p.invokingState); ATNState returnState = atn.states.get(p.invokingState);
RuleTransition rt = (RuleTransition)invokingState.transition(0);
ATNState retState = rt.followState;
// System.out.println("popping back to "+retState); // System.out.println("popping back to "+retState);
_LOOK(retState, p.parent, look, lookBusy, seeThruPreds); _LOOK(returnState, p.parent, look, lookBusy, seeThruPreds);
} }
return; return;
} }
@ -124,7 +122,7 @@ public class LL1Analyzer {
Transition t = s.transition(i); Transition t = s.transition(i);
if ( t.getClass() == RuleTransition.class ) { if ( t.getClass() == RuleTransition.class ) {
PredictionContext newContext = PredictionContext newContext =
SingletonPredictionContext.create(ctx, s.stateNumber); SingletonPredictionContext.create(ctx, ((RuleTransition)t).followState.stateNumber);
_LOOK(t.target, newContext, look, lookBusy, seeThruPreds); _LOOK(t.target, newContext, look, lookBusy, seeThruPreds);
} }
else if ( t instanceof PredicateTransition ) { else if ( t instanceof PredicateTransition ) {

View File

@ -418,10 +418,8 @@ public class LexerATNSimulator extends ATNSimulator {
configs.add(c); configs.add(c);
continue; continue;
} }
ATNState invokingState = atn.states.get(ctx.invokingState); ATNState returnState = atn.states.get(ctx.invokingState);
RuleTransition rt = (RuleTransition)invokingState.transition(0); LexerATNConfig c = new LexerATNConfig(returnState, config.alt, newContext);
ATNState retState = rt.followState;
LexerATNConfig c = new LexerATNConfig(retState, config.alt, newContext);
currentAltReachedAcceptState = closure(input, c, configs, currentAltReachedAcceptState, speculative); currentAltReachedAcceptState = closure(input, c, configs, currentAltReachedAcceptState, speculative);
} }
} }
@ -457,12 +455,12 @@ public class LexerATNSimulator extends ATNSimulator {
@NotNull ATNConfigSet configs, @NotNull ATNConfigSet configs,
boolean speculative) boolean speculative)
{ {
ATNState p = config.state;
LexerATNConfig c = null; LexerATNConfig c = null;
switch (t.getSerializationType()) { switch (t.getSerializationType()) {
case Transition.RULE: case Transition.RULE:
RuleTransition ruleTransition = (RuleTransition)t;
PredictionContext newContext = PredictionContext newContext =
SingletonPredictionContext.create(config.context, p.stateNumber); SingletonPredictionContext.create(config.context, ruleTransition.followState.stateNumber);
c = new LexerATNConfig(config, t.target, newContext); c = new LexerATNConfig(config, t.target, newContext);
break; break;

View File

@ -898,7 +898,7 @@ public class ParserATNSimulator extends ATNSimulator {
boolean fullCtx) boolean fullCtx)
{ {
// always at least the implicit call to start rule // always at least the implicit call to start rule
PredictionContext initialContext = PredictionContext.fromRuleContext(ctx); PredictionContext initialContext = PredictionContext.fromRuleContext(atn, ctx);
ATNConfigSet configs = new ATNConfigSet(fullCtx); ATNConfigSet configs = new ATNConfigSet(fullCtx);
for (int i=0; i<p.getNumberOfTransitions(); i++) { for (int i=0; i<p.getNumberOfTransitions(); i++) {
@ -1079,11 +1079,9 @@ public class ParserATNSimulator extends ATNSimulator {
fullCtx, depth); fullCtx, depth);
continue; continue;
} }
ATNState invokingState = atn.states.get(ctx.invokingState); ATNState returnState = atn.states.get(ctx.invokingState);
RuleTransition rt = (RuleTransition)invokingState.transition(0);
ATNState retState = rt.followState;
PredictionContext newContext = ctx.parent; // "pop" invoking state PredictionContext newContext = ctx.parent; // "pop" invoking state
ATNConfig c = new ATNConfig(retState, config.alt, newContext, ATNConfig c = new ATNConfig(returnState, config.alt, newContext,
config.semanticContext); config.semanticContext);
// While we have context to pop back from, we may have // While we have context to pop back from, we may have
// gotten that context AFTER having falling off a rule. // gotten that context AFTER having falling off a rule.
@ -1175,7 +1173,7 @@ public class ParserATNSimulator extends ATNSimulator {
{ {
switch (t.getSerializationType()) { switch (t.getSerializationType()) {
case Transition.RULE: case Transition.RULE:
return ruleTransition(config, t); return ruleTransition(config, (RuleTransition)t);
case Transition.PREDICATE: case Transition.PREDICATE:
return predTransition(config, (PredicateTransition)t, return predTransition(config, (PredicateTransition)t,
@ -1249,13 +1247,15 @@ public class ParserATNSimulator extends ATNSimulator {
} }
@NotNull @NotNull
public ATNConfig ruleTransition(@NotNull ATNConfig config, @NotNull Transition t) { public ATNConfig ruleTransition(@NotNull ATNConfig config, @NotNull RuleTransition t) {
if ( debug ) { if ( debug ) {
System.out.println("CALL rule "+getRuleName(t.target.ruleIndex)+ System.out.println("CALL rule "+getRuleName(t.target.ruleIndex)+
", ctx="+config.context); ", ctx="+config.context);
} }
ATNState returnState = t.followState;
PredictionContext newContext = PredictionContext newContext =
SingletonPredictionContext.create(config.context, config.state.stateNumber); SingletonPredictionContext.create(config.context, returnState.stateNumber);
return new ATNConfig(config, t.target, newContext); return new ATNConfig(config, t.target, newContext);
} }

View File

@ -38,7 +38,7 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
/** Convert a RuleContext tree to a PredictionContext graph. /** Convert a RuleContext tree to a PredictionContext graph.
* Return EMPTY if outerContext is empty or null. * Return EMPTY if outerContext is empty or null.
*/ */
public static PredictionContext fromRuleContext(RuleContext outerContext) { public static PredictionContext fromRuleContext(@NotNull ATN atn, RuleContext outerContext) {
if ( outerContext==null ) outerContext = RuleContext.EMPTY; if ( outerContext==null ) outerContext = RuleContext.EMPTY;
// if we are in RuleContext of start rule, s, then PredictionContext // if we are in RuleContext of start rule, s, then PredictionContext
@ -50,10 +50,12 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
// If we have a parent, convert it to a PredictionContext graph // If we have a parent, convert it to a PredictionContext graph
PredictionContext parent = EMPTY; PredictionContext parent = EMPTY;
if ( outerContext.parent != null ) { if ( outerContext.parent != null ) {
parent = PredictionContext.fromRuleContext(outerContext.parent); parent = PredictionContext.fromRuleContext(atn, outerContext.parent);
} }
return SingletonPredictionContext.create(parent, outerContext.invokingState); ATNState state = atn.states.get(outerContext.invokingState);
RuleTransition transition = (RuleTransition)state.transition(0);
return SingletonPredictionContext.create(parent, transition.followState.stateNumber);
} }
@Override @Override