Add the StarLoopEntryState.precedenceRuleDecision field so the information can be shared between ParserATNSimulator and ParserInterpreter

This commit is contained in:
Sam Harwell 2014-01-11 16:27:27 -06:00
parent bef086e874
commit e75beb69b1
4 changed files with 50 additions and 24 deletions

View File

@ -41,7 +41,6 @@ import org.antlr.v4.runtime.atn.PrecedencePredicateTransition;
import org.antlr.v4.runtime.atn.PredicateTransition;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.atn.RuleStartState;
import org.antlr.v4.runtime.atn.RuleStopState;
import org.antlr.v4.runtime.atn.RuleTransition;
import org.antlr.v4.runtime.atn.StarLoopEntryState;
import org.antlr.v4.runtime.atn.Transition;
@ -100,17 +99,7 @@ public class ParserInterpreter extends Parser {
continue;
}
RuleStartState ruleStartState = atn.ruleToStartState[state.ruleIndex];
if (!ruleStartState.isPrecedenceRule) {
continue;
}
ATNState maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target;
if (!(maybeLoopEndState instanceof LoopEndState)) {
continue;
}
if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) {
if (((StarLoopEntryState)state).precedenceRuleDecision) {
this.pushRecursionContextStates.set(state.stateNumber);
}
}

View File

@ -358,6 +358,8 @@ public class ATNDeserializer {
decState.decision = i-1;
}
markPrecedenceDecisions(atn);
if (deserializationOptions.isVerifyATN()) {
verifyATN(atn);
}
@ -455,6 +457,34 @@ public class ATNDeserializer {
return atn;
}
/**
* Analyze the {@link StarLoopEntryState} states in the specified ATN to set
* the {@link StarLoopEntryState#precedenceRuleDecision} field to the
* correct value.
*
* @param atn The ATN.
*/
protected void markPrecedenceDecisions(@NotNull ATN atn) {
for (ATNState state : atn.states) {
if (!(state instanceof StarLoopEntryState)) {
continue;
}
/* We analyze the ATN to determine if this ATN decision state is the
* decision for the closure block that determines whether a
* precedence rule should continue or complete.
*/
if (atn.ruleToStartState[state.ruleIndex].isPrecedenceRule) {
ATNState maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target;
if (maybeLoopEndState instanceof LoopEndState) {
if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) {
((StarLoopEntryState)state).precedenceRuleDecision = true;
}
}
}
}
}
protected void verifyATN(ATN atn) {
// verify assumptions
for (ATNState state : atn.states) {

View File

@ -344,22 +344,14 @@ public class ParserATNSimulator extends ATNSimulator {
", outerContext="+ outerContext.toString(parser));
}
/* If this is not a precedence DFA, we analyze the ATN to
* determine if this ATN start state is the decision for the
/* If this is not a precedence DFA, we check the ATN start state
* to determine if this ATN start state is the decision for the
* closure block that determines whether a precedence rule
* should continue or complete.
*
* This analysis is also in ParserInterpreter to initialize the
* pushRecursionContextStates field.
*/
if (!dfa.isPrecedenceDfa() && dfa.atnStartState instanceof StarLoopEntryState) {
if (atn.ruleToStartState[dfa.atnStartState.ruleIndex].isPrecedenceRule) {
ATNState maybeLoopEndState = dfa.atnStartState.transition(dfa.atnStartState.getNumberOfTransitions() - 1).target;
if (maybeLoopEndState instanceof LoopEndState) {
if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) {
dfa.setPrecedenceDfa(true);
}
}
if (((StarLoopEntryState)dfa.atnStartState).precedenceRuleDecision) {
dfa.setPrecedenceDfa(true);
}
}

View File

@ -30,9 +30,24 @@
package org.antlr.v4.runtime.atn;
import org.antlr.v4.runtime.ParserInterpreter;
import org.antlr.v4.runtime.dfa.DFA;
public final class StarLoopEntryState extends DecisionState {
public StarLoopbackState loopBackState;
/**
* Indicates whether this state can benefit from a precedence DFA during SLL
* decision making.
* <p/>
* This is a computed property that is calculated during ATN deserialization
* and stored for use in {@link ParserATNSimulator} and
* {@link ParserInterpreter}.
*
* @see DFA#isPrecedenceDfa()
*/
public boolean precedenceRuleDecision;
@Override
public int getStateType() {
return STAR_LOOP_ENTRY;