use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by tunnelvisionlabs.
the class ParserATNSimulator method addDFAState.
/**
* See comment on LexerInterpreter.addDFAState.
*/
@NotNull
protected DFAState addDFAState(@NotNull DFA dfa, @NotNull ATNConfigSet configs, PredictionContextCache contextCache) {
final boolean enableDfa = enable_global_context_dfa || !configs.isOutermostConfigSet();
if (enableDfa) {
if (!configs.isReadOnly()) {
configs.optimizeConfigs(this);
}
DFAState proposed = createDFAState(dfa, configs);
DFAState existing = dfa.states.get(proposed);
if (existing != null)
return existing;
}
if (!configs.isReadOnly()) {
if (configs.getConflictInfo() == null) {
configs.setConflictInfo(isConflicted(configs, contextCache));
}
}
DFAState newState = createDFAState(dfa, configs.clone(true));
DecisionState decisionState = atn.getDecisionState(dfa.decision);
int predictedAlt = getUniqueAlt(configs);
if (predictedAlt != ATN.INVALID_ALT_NUMBER) {
newState.setAcceptState(new AcceptStateInfo(predictedAlt));
} else if (configs.getConflictingAlts() != null) {
newState.setAcceptState(new AcceptStateInfo(newState.configs.getConflictingAlts().nextSetBit(0)));
}
if (newState.isAcceptState() && configs.hasSemanticContext()) {
predicateDFAState(newState, configs, decisionState.getNumberOfTransitions());
}
if (!enableDfa) {
return newState;
}
DFAState added = dfa.addState(newState);
if (debug && added == newState)
System.out.println("adding new DFA state: " + newState);
return added;
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by tunnelvisionlabs.
the class ParserATNSimulator method computeTargetState.
/**
* Compute a target state for an edge in the DFA, and attempt to add the
* computed state and corresponding edge to the DFA.
*
* @param dfa
* @param s The current DFA state
* @param remainingGlobalContext
* @param t The next input symbol
* @param useContext
* @param contextCache
*
* @return The computed target DFA state for the given input symbol
* {@code t}. If {@code t} does not lead to a valid DFA state, this method
* returns {@link #ERROR}.
*/
@NotNull
protected Tuple2<DFAState, ParserRuleContext> computeTargetState(@NotNull DFA dfa, @NotNull DFAState s, ParserRuleContext remainingGlobalContext, int t, boolean useContext, PredictionContextCache contextCache) {
List<ATNConfig> closureConfigs = new ArrayList<ATNConfig>(s.configs);
IntegerList contextElements = null;
ATNConfigSet reach = new ATNConfigSet();
boolean stepIntoGlobal;
do {
boolean hasMoreContext = !useContext || remainingGlobalContext != null;
if (!hasMoreContext) {
reach.setOutermostConfigSet(true);
}
ATNConfigSet reachIntermediate = new ATNConfigSet();
/* Configurations already in a rule stop state indicate reaching the end
* of the decision rule (local context) or end of the start rule (full
* context). Once reached, these configurations are never updated by a
* closure operation, so they are handled separately for the performance
* advantage of having a smaller intermediate set when calling closure.
*
* For full-context reach operations, separate handling is required to
* ensure that the alternative matching the longest overall sequence is
* chosen when multiple such configurations can match the input.
*/
List<ATNConfig> skippedStopStates = null;
for (ATNConfig c : closureConfigs) {
if (debug)
System.out.println("testing " + getTokenName(t) + " at " + c.toString());
if (c.getState() instanceof RuleStopState) {
assert c.getContext().isEmpty();
if (useContext && !c.getReachesIntoOuterContext() || t == IntStream.EOF) {
if (skippedStopStates == null) {
skippedStopStates = new ArrayList<ATNConfig>();
}
skippedStopStates.add(c);
}
continue;
}
int n = c.getState().getNumberOfOptimizedTransitions();
for (int ti = 0; ti < n; ti++) {
// for each optimized transition
Transition trans = c.getState().getOptimizedTransition(ti);
ATNState target = getReachableTarget(c, trans, t);
if (target != null) {
reachIntermediate.add(c.transform(target, false), contextCache);
}
}
}
/* This block optimizes the reach operation for intermediate sets which
* trivially indicate a termination state for the overall
* adaptivePredict operation.
*
* The conditions assume that intermediate
* contains all configurations relevant to the reach set, but this
* condition is not true when one or more configurations have been
* withheld in skippedStopStates, or when the current symbol is EOF.
*/
if (optimize_unique_closure && skippedStopStates == null && t != Token.EOF && reachIntermediate.getUniqueAlt() != ATN.INVALID_ALT_NUMBER) {
reachIntermediate.setOutermostConfigSet(reach.isOutermostConfigSet());
reach = reachIntermediate;
break;
}
/* If the reach set could not be trivially determined, perform a closure
* operation on the intermediate set to compute its initial value.
*/
final boolean collectPredicates = false;
boolean treatEofAsEpsilon = t == Token.EOF;
closure(reachIntermediate, reach, collectPredicates, hasMoreContext, contextCache, treatEofAsEpsilon);
stepIntoGlobal = reach.getDipsIntoOuterContext();
if (t == IntStream.EOF) {
/* After consuming EOF no additional input is possible, so we are
* only interested in configurations which reached the end of the
* decision rule (local context) or end of the start rule (full
* context). Update reach to contain only these configurations. This
* handles both explicit EOF transitions in the grammar and implicit
* EOF transitions following the end of the decision or start rule.
*
* This is handled before the configurations in skippedStopStates,
* because any configurations potentially added from that list are
* already guaranteed to meet this condition whether or not it's
* required.
*/
reach = removeAllConfigsNotInRuleStopState(reach, contextCache);
}
/* If skippedStopStates is not null, then it contains at least one
* configuration. For full-context reach operations, these
* configurations reached the end of the start rule, in which case we
* only add them back to reach if no configuration during the current
* closure operation reached such a state. This ensures adaptivePredict
* chooses an alternative matching the longest overall sequence when
* multiple alternatives are viable.
*/
if (skippedStopStates != null && (!useContext || !PredictionMode.hasConfigInRuleStopState(reach))) {
assert !skippedStopStates.isEmpty();
for (ATNConfig c : skippedStopStates) {
reach.add(c, contextCache);
}
}
if (useContext && stepIntoGlobal) {
reach.clear();
remainingGlobalContext = skipTailCalls(remainingGlobalContext);
int nextContextElement = getReturnState(remainingGlobalContext);
if (contextElements == null) {
contextElements = new IntegerList();
}
if (remainingGlobalContext.isEmpty()) {
remainingGlobalContext = null;
} else {
remainingGlobalContext = remainingGlobalContext.getParent();
}
contextElements.add(nextContextElement);
if (nextContextElement != PredictionContext.EMPTY_FULL_STATE_KEY) {
for (int i = 0; i < closureConfigs.size(); i++) {
closureConfigs.set(i, closureConfigs.get(i).appendContext(nextContextElement, contextCache));
}
}
}
} while (useContext && stepIntoGlobal);
if (reach.isEmpty()) {
addDFAEdge(s, t, ERROR);
return Tuple.create(ERROR, remainingGlobalContext);
}
DFAState result = addDFAEdge(dfa, s, t, contextElements, reach, contextCache);
return Tuple.create(result, remainingGlobalContext);
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by tunnelvisionlabs.
the class ParserATNSimulator method reportAmbiguity.
/**
* If context sensitive parsing, we know it's ambiguity not conflict
*/
protected void reportAmbiguity(@NotNull DFA dfa, // the DFA state from execATN() that had SLL conflicts
DFAState D, int startIndex, int stopIndex, boolean exact, @NotNull BitSet ambigAlts, // configs that LL not SLL considered conflicting
@NotNull ATNConfigSet configs) {
if (debug || retry_debug) {
Interval interval = Interval.of(startIndex, stopIndex);
System.out.println("reportAmbiguity " + ambigAlts + ":" + configs + ", input=" + parser.getInputStream().getText(interval));
}
if (parser != null)
parser.getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex, exact, ambigAlts, configs);
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by tunnelvisionlabs.
the class LexerATNSimulator method addDFAState.
/**
* Add a new DFA state if there isn't one with this set of
* configurations already. This method also detects the first
* configuration containing an ATN rule stop state. Later, when
* traversing the DFA, we will know which rule to accept.
*/
@NotNull
protected DFAState addDFAState(@NotNull ATNConfigSet configs) {
/* the lexer evaluates predicates on-the-fly; by this point configs
* should not contain any configurations with unevaluated predicates.
*/
assert !configs.hasSemanticContext();
DFAState proposed = new DFAState(atn.modeToDFA[mode], configs);
DFAState existing = atn.modeToDFA[mode].states.get(proposed);
if (existing != null)
return existing;
configs.optimizeConfigs(this);
DFAState newState = new DFAState(atn.modeToDFA[mode], configs.clone(true));
ATNConfig firstConfigWithRuleStopState = null;
for (ATNConfig c : configs) {
if (c.getState() instanceof RuleStopState) {
firstConfigWithRuleStopState = c;
break;
}
}
if (firstConfigWithRuleStopState != null) {
int prediction = atn.ruleToTokenType[firstConfigWithRuleStopState.getState().ruleIndex];
LexerActionExecutor lexerActionExecutor = firstConfigWithRuleStopState.getLexerActionExecutor();
newState.setAcceptState(new AcceptStateInfo(prediction, lexerActionExecutor));
}
return atn.modeToDFA[mode].addState(newState);
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by tunnelvisionlabs.
the class LexerATNSimulator method matchATN.
protected int matchATN(@NotNull CharStream input) {
ATNState startState = atn.modeToStartState.get(mode);
if (debug) {
System.out.format(Locale.getDefault(), "matchATN mode %d start: %s\n", mode, startState);
}
int old_mode = mode;
ATNConfigSet s0_closure = computeStartState(input, startState);
boolean suppressEdge = s0_closure.hasSemanticContext();
if (suppressEdge) {
s0_closure.clearExplicitSemanticContext();
}
DFAState next = addDFAState(s0_closure);
if (!suppressEdge) {
if (!atn.modeToDFA[mode].s0.compareAndSet(null, next)) {
next = atn.modeToDFA[mode].s0.get();
}
}
int predict = execATN(input, next);
if (debug) {
System.out.format(Locale.getDefault(), "DFA after matchATN: %s\n", atn.modeToDFA[old_mode].toLexerString());
}
return predict;
}
Aggregations