Search in sources :

Example 71 with ATNState

use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by tunnelvisionlabs.

the class RuleDependencyProcessor method extractRuleRelations.

private RuleRelations extractRuleRelations(TypeMirror recognizer) {
    String serializedATN = getSerializedATN(recognizer);
    if (serializedATN == null) {
        return null;
    }
    ATN atn = new ATNDeserializer().deserialize(serializedATN.toCharArray());
    RuleRelations relations = new RuleRelations(atn.ruleToStartState.length);
    for (ATNState state : atn.states) {
        if (!state.epsilonOnlyTransitions) {
            continue;
        }
        for (Transition transition : state.getTransitions()) {
            if (transition.getSerializationType() != Transition.RULE) {
                continue;
            }
            RuleTransition ruleTransition = (RuleTransition) transition;
            relations.addRuleInvocation(state.ruleIndex, ruleTransition.target.ruleIndex);
        }
    }
    return relations;
}
Also used : ATNDeserializer(org.antlr.v4.runtime.atn.ATNDeserializer) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) Transition(org.antlr.v4.runtime.atn.Transition) ATN(org.antlr.v4.runtime.atn.ATN) ATNState(org.antlr.v4.runtime.atn.ATNState)

Example 72 with ATNState

use of org.antlr.v4.runtime.atn.ATNState 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 73 with ATNState

use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by tunnelvisionlabs.

the class LL1Analyzer method LOOK.

/**
 * Compute set of tokens that can follow {@code s} in the ATN in the
 * specified {@code ctx}.
 *
 * <p>If {@code ctx} is {@code null} and the end of the rule containing
 * {@code s} is reached, {@link Token#EPSILON} is added to the result set.
 * If {@code ctx} is not {@code PredictionContext#EMPTY_LOCAL} and the end of the outermost rule is
 * reached, {@link Token#EOF} is added to the result set.</p>
 *
 * @param s the ATN state
 * @param stopState the ATN state to stop at. This can be a
 * {@link BlockEndState} to detect epsilon paths through a closure.
 * @param ctx the complete parser context, or {@code null} if the context
 * should be ignored
 *
 * @return The set of tokens that can follow {@code s} in the ATN in the
 * specified {@code ctx}.
 */
@NotNull
public IntervalSet LOOK(@NotNull ATNState s, @Nullable ATNState stopState, @NotNull PredictionContext ctx) {
    IntervalSet r = new IntervalSet();
    // ignore preds; get all lookahead
    final boolean seeThruPreds = true;
    final boolean addEOF = true;
    _LOOK(s, stopState, ctx, r, new HashSet<ATNConfig>(), new BitSet(), seeThruPreds, addEOF);
    return r;
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) BitSet(java.util.BitSet) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 74 with ATNState

use of org.antlr.v4.runtime.atn.ATNState 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)

Example 75 with ATNState

use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by tunnelvisionlabs.

the class GrammarParserInterpreter method findOuterMostDecisionStates.

/**
 * identify the ATN states where we need to set the outer alt number.
 *  For regular rules, that's the block at the target to rule start state.
 *  For left-recursive rules, we track the primary block, which looks just
 *  like a regular rule's outer block, and the star loop block (always
 *  there even if 1 alt).
 */
public BitSet findOuterMostDecisionStates() {
    BitSet track = new BitSet(atn.states.size());
    int numberOfDecisions = atn.getNumberOfDecisions();
    for (int i = 0; i < numberOfDecisions; i++) {
        DecisionState decisionState = atn.getDecisionState(i);
        RuleStartState startState = atn.ruleToStartState[decisionState.ruleIndex];
        // Look for StarLoopEntryState that is in any left recursive rule
        if (decisionState instanceof StarLoopEntryState) {
            StarLoopEntryState loopEntry = (StarLoopEntryState) decisionState;
            if (loopEntry.precedenceRuleDecision) {
                // Recursive alts always result in a (...)* in the transformed
                // left recursive rule and that always has a BasicBlockStartState
                // even if just 1 recursive alt exists.
                ATNState blockStart = loopEntry.transition(0).target;
                // track the StarBlockStartState associated with the recursive alternatives
                track.set(blockStart.stateNumber);
            }
        } else if (startState.transition(0).target == decisionState) {
            // always track outermost block for any rule if it exists
            track.set(decisionState.stateNumber);
        }
    }
    return track;
}
Also used : StarLoopEntryState(org.antlr.v4.runtime.atn.StarLoopEntryState) RuleStartState(org.antlr.v4.runtime.atn.RuleStartState) BitSet(java.util.BitSet) DecisionState(org.antlr.v4.runtime.atn.DecisionState) ATNState(org.antlr.v4.runtime.atn.ATNState)

Aggregations

ATNState (org.antlr.v4.runtime.atn.ATNState)94 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)34 ATN (org.antlr.v4.runtime.atn.ATN)25 RuleTransition (org.antlr.v4.runtime.atn.RuleTransition)23 Rule (org.antlr.v4.tool.Rule)22 Transition (org.antlr.v4.runtime.atn.Transition)21 NotNull (org.antlr.v4.runtime.misc.NotNull)19 AtomTransition (org.antlr.v4.runtime.atn.AtomTransition)18 RuleStartState (org.antlr.v4.runtime.atn.RuleStartState)17 ActionTransition (org.antlr.v4.runtime.atn.ActionTransition)16 SetTransition (org.antlr.v4.runtime.atn.SetTransition)16 NotSetTransition (org.antlr.v4.runtime.atn.NotSetTransition)15 DecisionState (org.antlr.v4.runtime.atn.DecisionState)11 DOTGenerator (org.antlr.v4.tool.DOTGenerator)10 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)10 ParserATNFactory (org.antlr.v4.automata.ParserATNFactory)9 LeftRecursiveRule (org.antlr.v4.tool.LeftRecursiveRule)9 ArrayList (java.util.ArrayList)8 EpsilonTransition (org.antlr.v4.runtime.atn.EpsilonTransition)8 PrecedencePredicateTransition (org.antlr.v4.runtime.atn.PrecedencePredicateTransition)8