forked from jasder/antlr
Add the StarLoopEntryState.precedenceRuleDecision field so the information can be shared between ParserATNSimulator and ParserInterpreter
This commit is contained in:
parent
bef086e874
commit
e75beb69b1
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue