Search in sources :

Example 16 with ATNConfigSet

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;
}
Also used : DFAState(org.antlr.v4.runtime.dfa.DFAState) AcceptStateInfo(org.antlr.v4.runtime.dfa.AcceptStateInfo) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 17 with ATNConfigSet

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);
}
Also used : DFAState(org.antlr.v4.runtime.dfa.DFAState) ArrayList(java.util.ArrayList) IntegerList(org.antlr.v4.runtime.misc.IntegerList) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 18 with ATNConfigSet

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);
}
Also used : Interval(org.antlr.v4.runtime.misc.Interval)

Example 19 with ATNConfigSet

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);
}
Also used : DFAState(org.antlr.v4.runtime.dfa.DFAState) AcceptStateInfo(org.antlr.v4.runtime.dfa.AcceptStateInfo) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 20 with ATNConfigSet

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;
}
Also used : DFAState(org.antlr.v4.runtime.dfa.DFAState)

Aggregations

DFAState (org.antlr.v4.runtime.dfa.DFAState)13 NotNull (org.antlr.v4.runtime.misc.NotNull)6 BitSet (java.util.BitSet)5 DFA (org.antlr.v4.runtime.dfa.DFA)4 Interval (org.antlr.v4.runtime.misc.Interval)4 ArrayList (java.util.ArrayList)2 CommonTokenStream (org.antlr.v4.runtime.CommonTokenStream)2 NoViableAltException (org.antlr.v4.runtime.NoViableAltException)2 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)2 RecognitionException (org.antlr.v4.runtime.RecognitionException)2 ATNConfigSet (org.antlr.v4.runtime.atn.ATNConfigSet)2 AcceptStateInfo (org.antlr.v4.runtime.dfa.AcceptStateInfo)2 Pair (com.abubusoft.kripton.common.Pair)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 ANTLRErrorListener (org.antlr.v4.runtime.ANTLRErrorListener)1 ANTLRInputStream (org.antlr.v4.runtime.ANTLRInputStream)1 Parser (org.antlr.v4.runtime.Parser)1 IntegerList (org.antlr.v4.runtime.misc.IntegerList)1 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)1 CommentLineContext (org.springframework.ide.vscode.java.properties.antlr.parser.JavaPropertiesParser.CommentLineContext)1