Search in sources :

Example 71 with DFA

use of org.antlr.v4.runtime.dfa.DFA 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 72 with DFA

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

use of org.antlr.v4.runtime.dfa.DFA in project antlr4 by tunnelvisionlabs.

the class LexerATNSimulator method addDFAEdge.

@NotNull
protected DFAState addDFAEdge(@NotNull DFAState from, int t, @NotNull ATNConfigSet q) {
    /* leading to this call, ATNConfigSet.hasSemanticContext is used as a
		 * marker indicating dynamic predicate evaluation makes this edge
		 * dependent on the specific input sequence, so the static edge in the
		 * DFA should be omitted. The target DFAState is still created since
		 * execATN has the ability to resynchronize with the DFA state cache
		 * following the predicate evaluation step.
		 *
		 * TJP notes: next time through the DFA, we see a pred again and eval.
		 * If that gets us to a previously created (but dangling) DFA
		 * state, we can continue in pure DFA mode from there.
		 */
    boolean suppressEdge = q.hasSemanticContext();
    if (suppressEdge) {
        q.clearExplicitSemanticContext();
    }
    @NotNull DFAState to = addDFAState(q);
    if (suppressEdge) {
        return to;
    }
    addDFAEdge(from, t, to);
    return to;
}
Also used : DFAState(org.antlr.v4.runtime.dfa.DFAState) NotNull(org.antlr.v4.runtime.misc.NotNull) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 74 with DFA

use of org.antlr.v4.runtime.dfa.DFA in project antlr4 by tunnelvisionlabs.

the class ProfilingATNSimulator method getExistingTargetState.

@Override
protected DFAState getExistingTargetState(DFAState previousD, int t) {
    // this method is called after each time the input position advances
    if (currentState.useContext) {
        _llStopIndex = _input.index();
    } else {
        _sllStopIndex = _input.index();
    }
    DFAState existingTargetState = super.getExistingTargetState(previousD, t);
    if (existingTargetState != null) {
        // this method is directly called by execDFA; must construct a SimulatorState
        // to represent the current state for this case
        currentState = new SimulatorState(currentState.outerContext, existingTargetState, currentState.useContext, currentState.remainingOuterContext);
        if (currentState.useContext) {
            decisions[currentDecision].LL_DFATransitions++;
        } else {
            // count only if we transition over a DFA state
            decisions[currentDecision].SLL_DFATransitions++;
        }
        if (existingTargetState == ERROR) {
            SimulatorState state = new SimulatorState(currentState.outerContext, previousD, currentState.useContext, currentState.remainingOuterContext);
            decisions[currentDecision].errors.add(new ErrorInfo(currentDecision, state, _input, _startIndex, _input.index()));
        }
    }
    return existingTargetState;
}
Also used : DFAState(org.antlr.v4.runtime.dfa.DFAState)

Example 75 with DFA

use of org.antlr.v4.runtime.dfa.DFA in project antlr4 by tunnelvisionlabs.

the class ATNDeserializer method deserialize.

@SuppressWarnings("deprecation")
public ATN deserialize(@NotNull char[] data) {
    data = data.clone();
    // was implemented.
    for (int i = 1; i < data.length; i++) {
        data[i] = (char) (data[i] - 2);
    }
    int p = 0;
    int version = toInt(data[p++]);
    if (version != SERIALIZED_VERSION) {
        String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with version %d (expected %d).", version, SERIALIZED_VERSION);
        throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
    }
    UUID uuid = toUUID(data, p);
    p += 8;
    if (!SUPPORTED_UUIDS.contains(uuid)) {
        String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with UUID %s (expected %s or a legacy UUID).", uuid, SERIALIZED_UUID);
        throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
    }
    boolean supportsLexerActions = isFeatureSupported(ADDED_LEXER_ACTIONS, uuid);
    ATNType grammarType = ATNType.values()[toInt(data[p++])];
    int maxTokenType = toInt(data[p++]);
    ATN atn = new ATN(grammarType, maxTokenType);
    // 
    // STATES
    // 
    List<Tuple2<LoopEndState, Integer>> loopBackStateNumbers = new ArrayList<Tuple2<LoopEndState, Integer>>();
    List<Tuple2<BlockStartState, Integer>> endStateNumbers = new ArrayList<Tuple2<BlockStartState, Integer>>();
    int nstates = toInt(data[p++]);
    for (int i = 0; i < nstates; i++) {
        int stype = toInt(data[p++]);
        // ignore bad type of states
        if (stype == ATNState.INVALID_TYPE) {
            atn.addState(null);
            continue;
        }
        int ruleIndex = toInt(data[p++]);
        if (ruleIndex == Character.MAX_VALUE) {
            ruleIndex = -1;
        }
        ATNState s = stateFactory(stype, ruleIndex);
        if (stype == ATNState.LOOP_END) {
            // special case
            int loopBackStateNumber = toInt(data[p++]);
            loopBackStateNumbers.add(Tuple.create((LoopEndState) s, loopBackStateNumber));
        } else if (s instanceof BlockStartState) {
            int endStateNumber = toInt(data[p++]);
            endStateNumbers.add(Tuple.create((BlockStartState) s, endStateNumber));
        }
        atn.addState(s);
    }
    // delay the assignment of loop back and end states until we know all the state instances have been initialized
    for (Tuple2<LoopEndState, Integer> pair : loopBackStateNumbers) {
        pair.getItem1().loopBackState = atn.states.get(pair.getItem2());
    }
    for (Tuple2<BlockStartState, Integer> pair : endStateNumbers) {
        pair.getItem1().endState = (BlockEndState) atn.states.get(pair.getItem2());
    }
    int numNonGreedyStates = toInt(data[p++]);
    for (int i = 0; i < numNonGreedyStates; i++) {
        int stateNumber = toInt(data[p++]);
        ((DecisionState) atn.states.get(stateNumber)).nonGreedy = true;
    }
    int numSllDecisions = toInt(data[p++]);
    for (int i = 0; i < numSllDecisions; i++) {
        int stateNumber = toInt(data[p++]);
        ((DecisionState) atn.states.get(stateNumber)).sll = true;
    }
    int numPrecedenceStates = toInt(data[p++]);
    for (int i = 0; i < numPrecedenceStates; i++) {
        int stateNumber = toInt(data[p++]);
        ((RuleStartState) atn.states.get(stateNumber)).isPrecedenceRule = true;
    }
    // 
    // RULES
    // 
    int nrules = toInt(data[p++]);
    if (atn.grammarType == ATNType.LEXER) {
        atn.ruleToTokenType = new int[nrules];
    }
    atn.ruleToStartState = new RuleStartState[nrules];
    for (int i = 0; i < nrules; i++) {
        int s = toInt(data[p++]);
        RuleStartState startState = (RuleStartState) atn.states.get(s);
        startState.leftFactored = toInt(data[p++]) != 0;
        atn.ruleToStartState[i] = startState;
        if (atn.grammarType == ATNType.LEXER) {
            int tokenType = toInt(data[p++]);
            if (tokenType == 0xFFFF) {
                tokenType = Token.EOF;
            }
            atn.ruleToTokenType[i] = tokenType;
            if (!isFeatureSupported(ADDED_LEXER_ACTIONS, uuid)) {
                // this piece of unused metadata was serialized prior to the
                // addition of LexerAction
                int actionIndexIgnored = toInt(data[p++]);
                if (actionIndexIgnored == 0xFFFF) {
                    actionIndexIgnored = -1;
                }
            }
        }
    }
    atn.ruleToStopState = new RuleStopState[nrules];
    for (ATNState state : atn.states) {
        if (!(state instanceof RuleStopState)) {
            continue;
        }
        RuleStopState stopState = (RuleStopState) state;
        atn.ruleToStopState[state.ruleIndex] = stopState;
        atn.ruleToStartState[state.ruleIndex].stopState = stopState;
    }
    // 
    // MODES
    // 
    int nmodes = toInt(data[p++]);
    for (int i = 0; i < nmodes; i++) {
        int s = toInt(data[p++]);
        atn.modeToStartState.add((TokensStartState) atn.states.get(s));
    }
    atn.modeToDFA = new DFA[nmodes];
    for (int i = 0; i < nmodes; i++) {
        atn.modeToDFA[i] = new DFA(atn.modeToStartState.get(i));
    }
    // 
    // SETS
    // 
    List<IntervalSet> sets = new ArrayList<IntervalSet>();
    // First, read all sets with 16-bit Unicode code points <= U+FFFF.
    p = deserializeSets(data, p, sets, getUnicodeDeserializer(UnicodeDeserializingMode.UNICODE_BMP));
    // deserialize sets with 32-bit arguments <= U+10FFFF.
    if (isFeatureSupported(ADDED_UNICODE_SMP, uuid)) {
        int previousSetCount = sets.size();
        p = deserializeSets(data, p, sets, getUnicodeDeserializer(UnicodeDeserializingMode.UNICODE_SMP));
        atn.setHasUnicodeSMPTransitions(sets.size() > previousSetCount);
    }
    // 
    // EDGES
    // 
    int nedges = toInt(data[p++]);
    for (int i = 0; i < nedges; i++) {
        int src = toInt(data[p]);
        int trg = toInt(data[p + 1]);
        int ttype = toInt(data[p + 2]);
        int arg1 = toInt(data[p + 3]);
        int arg2 = toInt(data[p + 4]);
        int arg3 = toInt(data[p + 5]);
        Transition trans = edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets);
        // System.out.println("EDGE "+trans.getClass().getSimpleName()+" "+
        // src+"->"+trg+
        // " "+Transition.serializationNames[ttype]+
        // " "+arg1+","+arg2+","+arg3);
        ATNState srcState = atn.states.get(src);
        srcState.addTransition(trans);
        p += 6;
    }
    // edges for rule stop states can be derived, so they aren't serialized
    // Map rule stop state -> return state -> outermost precedence return
    Set<Tuple3<Integer, Integer, Integer>> returnTransitions = new LinkedHashSet<Tuple3<Integer, Integer, Integer>>();
    for (ATNState state : atn.states) {
        boolean returningToLeftFactored = state.ruleIndex >= 0 && atn.ruleToStartState[state.ruleIndex].leftFactored;
        for (int i = 0; i < state.getNumberOfTransitions(); i++) {
            Transition t = state.transition(i);
            if (!(t instanceof RuleTransition)) {
                continue;
            }
            RuleTransition ruleTransition = (RuleTransition) t;
            boolean returningFromLeftFactored = atn.ruleToStartState[ruleTransition.target.ruleIndex].leftFactored;
            if (!returningFromLeftFactored && returningToLeftFactored) {
                continue;
            }
            int outermostPrecedenceReturn = -1;
            if (atn.ruleToStartState[ruleTransition.target.ruleIndex].isPrecedenceRule) {
                if (ruleTransition.precedence == 0) {
                    outermostPrecedenceReturn = ruleTransition.target.ruleIndex;
                }
            }
            returnTransitions.add(Tuple.create(ruleTransition.target.ruleIndex, ruleTransition.followState.stateNumber, outermostPrecedenceReturn));
        }
    }
    // Add all elements from returnTransitions to the ATN
    for (Tuple3<Integer, Integer, Integer> returnTransition : returnTransitions) {
        EpsilonTransition transition = new EpsilonTransition(atn.states.get(returnTransition.getItem2()), returnTransition.getItem3());
        atn.ruleToStopState[returnTransition.getItem1()].addTransition(transition);
    }
    for (ATNState state : atn.states) {
        if (state instanceof BlockStartState) {
            // we need to know the end state to set its start state
            if (((BlockStartState) state).endState == null) {
                throw new IllegalStateException();
            }
            // block end states can only be associated to a single block start state
            if (((BlockStartState) state).endState.startState != null) {
                throw new IllegalStateException();
            }
            ((BlockStartState) state).endState.startState = (BlockStartState) state;
        }
        if (state instanceof PlusLoopbackState) {
            PlusLoopbackState loopbackState = (PlusLoopbackState) state;
            for (int i = 0; i < loopbackState.getNumberOfTransitions(); i++) {
                ATNState target = loopbackState.transition(i).target;
                if (target instanceof PlusBlockStartState) {
                    ((PlusBlockStartState) target).loopBackState = loopbackState;
                }
            }
        } else if (state instanceof StarLoopbackState) {
            StarLoopbackState loopbackState = (StarLoopbackState) state;
            for (int i = 0; i < loopbackState.getNumberOfTransitions(); i++) {
                ATNState target = loopbackState.transition(i).target;
                if (target instanceof StarLoopEntryState) {
                    ((StarLoopEntryState) target).loopBackState = loopbackState;
                }
            }
        }
    }
    // 
    // DECISIONS
    // 
    int ndecisions = toInt(data[p++]);
    for (int i = 1; i <= ndecisions; i++) {
        int s = toInt(data[p++]);
        DecisionState decState = (DecisionState) atn.states.get(s);
        atn.decisionToState.add(decState);
        decState.decision = i - 1;
    }
    // 
    if (atn.grammarType == ATNType.LEXER) {
        if (supportsLexerActions) {
            atn.lexerActions = new LexerAction[toInt(data[p++])];
            for (int i = 0; i < atn.lexerActions.length; i++) {
                LexerActionType actionType = LexerActionType.values()[toInt(data[p++])];
                int data1 = toInt(data[p++]);
                if (data1 == 0xFFFF) {
                    data1 = -1;
                }
                int data2 = toInt(data[p++]);
                if (data2 == 0xFFFF) {
                    data2 = -1;
                }
                LexerAction lexerAction = lexerActionFactory(actionType, data1, data2);
                atn.lexerActions[i] = lexerAction;
            }
        } else {
            // for compatibility with older serialized ATNs, convert the old
            // serialized action index for action transitions to the new
            // form, which is the index of a LexerCustomAction
            List<LexerAction> legacyLexerActions = new ArrayList<LexerAction>();
            for (ATNState state : atn.states) {
                for (int i = 0; i < state.getNumberOfTransitions(); i++) {
                    Transition transition = state.transition(i);
                    if (!(transition instanceof ActionTransition)) {
                        continue;
                    }
                    int ruleIndex = ((ActionTransition) transition).ruleIndex;
                    int actionIndex = ((ActionTransition) transition).actionIndex;
                    LexerCustomAction lexerAction = new LexerCustomAction(ruleIndex, actionIndex);
                    state.setTransition(i, new ActionTransition(transition.target, ruleIndex, legacyLexerActions.size(), false));
                    legacyLexerActions.add(lexerAction);
                }
            }
            atn.lexerActions = legacyLexerActions.toArray(new LexerAction[legacyLexerActions.size()]);
        }
    }
    markPrecedenceDecisions(atn);
    atn.decisionToDFA = new DFA[ndecisions];
    for (int i = 0; i < ndecisions; i++) {
        atn.decisionToDFA[i] = new DFA(atn.decisionToState.get(i), i);
    }
    if (deserializationOptions.isVerifyATN()) {
        verifyATN(atn);
    }
    if (deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType.PARSER) {
        atn.ruleToTokenType = new int[atn.ruleToStartState.length];
        for (int i = 0; i < atn.ruleToStartState.length; i++) {
            atn.ruleToTokenType[i] = atn.maxTokenType + i + 1;
        }
        for (int i = 0; i < atn.ruleToStartState.length; i++) {
            BasicBlockStartState bypassStart = new BasicBlockStartState();
            bypassStart.ruleIndex = i;
            atn.addState(bypassStart);
            BlockEndState bypassStop = new BlockEndState();
            bypassStop.ruleIndex = i;
            atn.addState(bypassStop);
            bypassStart.endState = bypassStop;
            atn.defineDecisionState(bypassStart);
            bypassStop.startState = bypassStart;
            ATNState endState;
            Transition excludeTransition = null;
            if (atn.ruleToStartState[i].isPrecedenceRule) {
                // wrap from the beginning of the rule to the StarLoopEntryState
                endState = null;
                for (ATNState state : atn.states) {
                    if (state.ruleIndex != i) {
                        continue;
                    }
                    if (!(state instanceof StarLoopEntryState)) {
                        continue;
                    }
                    ATNState maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target;
                    if (!(maybeLoopEndState instanceof LoopEndState)) {
                        continue;
                    }
                    if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) {
                        endState = state;
                        break;
                    }
                }
                if (endState == null) {
                    throw new UnsupportedOperationException("Couldn't identify final state of the precedence rule prefix section.");
                }
                excludeTransition = ((StarLoopEntryState) endState).loopBackState.transition(0);
            } else {
                endState = atn.ruleToStopState[i];
            }
            // all non-excluded transitions that currently target end state need to target blockEnd instead
            for (ATNState state : atn.states) {
                for (Transition transition : state.transitions) {
                    if (transition == excludeTransition) {
                        continue;
                    }
                    if (transition.target == endState) {
                        transition.target = bypassStop;
                    }
                }
            }
            // all transitions leaving the rule start state need to leave blockStart instead
            while (atn.ruleToStartState[i].getNumberOfTransitions() > 0) {
                Transition transition = atn.ruleToStartState[i].removeTransition(atn.ruleToStartState[i].getNumberOfTransitions() - 1);
                bypassStart.addTransition(transition);
            }
            // link the new states
            atn.ruleToStartState[i].addTransition(new EpsilonTransition(bypassStart));
            bypassStop.addTransition(new EpsilonTransition(endState));
            ATNState matchState = new BasicState();
            atn.addState(matchState);
            matchState.addTransition(new AtomTransition(bypassStop, atn.ruleToTokenType[i]));
            bypassStart.addTransition(new EpsilonTransition(matchState));
        }
        if (deserializationOptions.isVerifyATN()) {
            // reverify after modification
            verifyATN(atn);
        }
    }
    if (deserializationOptions.isOptimize()) {
        while (true) {
            int optimizationCount = 0;
            optimizationCount += inlineSetRules(atn);
            optimizationCount += combineChainedEpsilons(atn);
            boolean preserveOrder = atn.grammarType == ATNType.LEXER;
            optimizationCount += optimizeSets(atn, preserveOrder);
            if (optimizationCount == 0) {
                break;
            }
        }
        if (deserializationOptions.isVerifyATN()) {
            // reverify after modification
            verifyATN(atn);
        }
    }
    identifyTailCalls(atn);
    return atn;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) UUID(java.util.UUID) InvalidClassException(java.io.InvalidClassException) Tuple2(org.antlr.v4.runtime.misc.Tuple2) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Tuple3(org.antlr.v4.runtime.misc.Tuple3) DFA(org.antlr.v4.runtime.dfa.DFA)

Aggregations

DFA (org.antlr.v4.runtime.dfa.DFA)37 DFAState (org.antlr.v4.runtime.dfa.DFAState)28 Test (org.junit.Test)19 Grammar (org.antlr.v4.tool.Grammar)18 LexerGrammar (org.antlr.v4.tool.LexerGrammar)18 LexerATNSimulator (org.antlr.v4.runtime.atn.LexerATNSimulator)16 ArrayList (java.util.ArrayList)14 STGroupString (org.stringtemplate.v4.STGroupString)14 CharStream (org.antlr.v4.runtime.CharStream)13 IOException (java.io.IOException)10 IntegerList (org.antlr.v4.runtime.misc.IntegerList)10 BaseRuntimeTest.antlrOnString (org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString)9 InputStream (java.io.InputStream)8 BitSet (java.util.BitSet)8 CommonTokenStream (org.antlr.v4.runtime.CommonTokenStream)7 ATN (org.antlr.v4.runtime.atn.ATN)7 Interval (org.antlr.v4.runtime.misc.Interval)7 NotNull (org.antlr.v4.runtime.misc.NotNull)7 ANTLRInputStream (org.antlr.v4.runtime.ANTLRInputStream)6 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)5