Search in sources :

Example 6 with BlockEndState

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

Example 7 with BlockEndState

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

the class ATNDeserializer method optimizeSets.

private static int optimizeSets(ATN atn, boolean preserveOrder) {
    if (preserveOrder) {
        // this optimization currently doesn't preserve edge order.
        return 0;
    }
    int removedPaths = 0;
    List<DecisionState> decisions = atn.decisionToState;
    for (DecisionState decision : decisions) {
        IntervalSet setTransitions = new IntervalSet();
        for (int i = 0; i < decision.getNumberOfOptimizedTransitions(); i++) {
            Transition epsTransition = decision.getOptimizedTransition(i);
            if (!(epsTransition instanceof EpsilonTransition)) {
                continue;
            }
            if (epsTransition.target.getNumberOfOptimizedTransitions() != 1) {
                continue;
            }
            Transition transition = epsTransition.target.getOptimizedTransition(0);
            if (!(transition.target instanceof BlockEndState)) {
                continue;
            }
            if (transition instanceof NotSetTransition) {
                // TODO: not yet implemented
                continue;
            }
            if (transition instanceof AtomTransition || transition instanceof RangeTransition || transition instanceof SetTransition) {
                setTransitions.add(i);
            }
        }
        if (setTransitions.size() <= 1) {
            continue;
        }
        List<Transition> optimizedTransitions = new ArrayList<Transition>();
        for (int i = 0; i < decision.getNumberOfOptimizedTransitions(); i++) {
            if (!setTransitions.contains(i)) {
                optimizedTransitions.add(decision.getOptimizedTransition(i));
            }
        }
        ATNState blockEndState = decision.getOptimizedTransition(setTransitions.getMinElement()).target.getOptimizedTransition(0).target;
        IntervalSet matchSet = new IntervalSet();
        for (int i = 0; i < setTransitions.getIntervals().size(); i++) {
            Interval interval = setTransitions.getIntervals().get(i);
            for (int j = interval.a; j <= interval.b; j++) {
                Transition matchTransition = decision.getOptimizedTransition(j).target.getOptimizedTransition(0);
                if (matchTransition instanceof NotSetTransition) {
                    throw new UnsupportedOperationException("Not yet implemented.");
                } else {
                    matchSet.addAll(matchTransition.label());
                }
            }
        }
        Transition newTransition;
        if (matchSet.getIntervals().size() == 1) {
            if (matchSet.size() == 1) {
                newTransition = new AtomTransition(blockEndState, matchSet.getMinElement());
            } else {
                Interval matchInterval = matchSet.getIntervals().get(0);
                newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval.b);
            }
        } else {
            newTransition = new SetTransition(blockEndState, matchSet);
        }
        ATNState setOptimizedState = new BasicState();
        setOptimizedState.setRuleIndex(decision.ruleIndex);
        atn.addState(setOptimizedState);
        setOptimizedState.addTransition(newTransition);
        optimizedTransitions.add(new EpsilonTransition(setOptimizedState));
        removedPaths += decision.getNumberOfOptimizedTransitions() - optimizedTransitions.size();
        if (decision.isOptimized()) {
            while (decision.getNumberOfOptimizedTransitions() > 0) {
                decision.removeOptimizedTransition(decision.getNumberOfOptimizedTransitions() - 1);
            }
        }
        for (Transition transition : optimizedTransitions) {
            decision.addOptimizedTransition(transition);
        }
    }
    if (ParserATNSimulator.debug) {
        System.out.println("ATN runtime optimizer removed " + removedPaths + " paths by collapsing sets.");
    }
    return removedPaths;
}
Also used : ArrayList(java.util.ArrayList) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Interval(org.antlr.v4.runtime.misc.Interval)

Example 8 with BlockEndState

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

the class ParserATNFactory method plus.

/**
 * From {@code (blk)+} build
 *
 * <pre>
 *   |---------|
 *   v         |
 *  [o-blk-o]-&gt;o-&gt;o
 * </pre>
 *
 * We add a decision for loop back node to the existing one at {@code blk}
 * start.
 */
@NotNull
@Override
public Handle plus(@NotNull GrammarAST plusAST, @NotNull Handle blk) {
    PlusBlockStartState blkStart = (PlusBlockStartState) blk.left;
    BlockEndState blkEnd = (BlockEndState) blk.right;
    preventEpsilonClosureBlocks.add(Tuple.create(currentRule, blkStart, blkEnd));
    PlusLoopbackState loop = newState(PlusLoopbackState.class, plusAST);
    loop.nonGreedy = !((QuantifierAST) plusAST).isGreedy();
    // no way to express SLL restriction
    loop.sll = false;
    atn.defineDecisionState(loop);
    LoopEndState end = newState(LoopEndState.class, plusAST);
    blkStart.loopBackState = loop;
    end.loopBackState = loop;
    plusAST.atnState = loop;
    // blk can see loop back
    epsilon(blkEnd, loop);
    BlockAST blkAST = (BlockAST) plusAST.getChild(0);
    if (((QuantifierAST) plusAST).isGreedy()) {
        if (expectNonGreedy(blkAST)) {
            g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, plusAST.getToken(), plusAST.getToken().getText());
        }
        // loop back to start
        epsilon(loop, blkStart);
        // or exit
        epsilon(loop, end);
    } else {
        // if not greedy, priority to exit branch; make it first
        // exit
        epsilon(loop, end);
        // loop back to start
        epsilon(loop, blkStart);
    }
    return new Handle(blkStart, end);
}
Also used : LoopEndState(org.antlr.v4.runtime.atn.LoopEndState) PlusBlockStartState(org.antlr.v4.runtime.atn.PlusBlockStartState) PlusLoopbackState(org.antlr.v4.runtime.atn.PlusLoopbackState) BlockAST(org.antlr.v4.tool.ast.BlockAST) QuantifierAST(org.antlr.v4.tool.ast.QuantifierAST) BlockEndState(org.antlr.v4.runtime.atn.BlockEndState) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 9 with BlockEndState

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

the class ParserATNFactory method star.

/**
 * From {@code (blk)*} build {@code ( blk+ )?} with *two* decisions, one for
 * entry and one for choosing alts of {@code blk}.
 *
 * <pre>
 *   |-------------|
 *   v             |
 *   o--[o-blk-o]-&gt;o  o
 *   |                ^
 *   -----------------|
 * </pre>
 *
 * Note that the optional bypass must jump outside the loop as
 * {@code (A|B)*} is not the same thing as {@code (A|B|)+}.
 */
@NotNull
@Override
public Handle star(@NotNull GrammarAST starAST, @NotNull Handle elem) {
    StarBlockStartState blkStart = (StarBlockStartState) elem.left;
    BlockEndState blkEnd = (BlockEndState) elem.right;
    preventEpsilonClosureBlocks.add(Tuple.create(currentRule, blkStart, blkEnd));
    StarLoopEntryState entry = newState(StarLoopEntryState.class, starAST);
    entry.nonGreedy = !((QuantifierAST) starAST).isGreedy();
    // no way to express SLL restriction
    entry.sll = false;
    atn.defineDecisionState(entry);
    LoopEndState end = newState(LoopEndState.class, starAST);
    StarLoopbackState loop = newState(StarLoopbackState.class, starAST);
    entry.loopBackState = loop;
    end.loopBackState = loop;
    BlockAST blkAST = (BlockAST) starAST.getChild(0);
    if (((QuantifierAST) starAST).isGreedy()) {
        if (expectNonGreedy(blkAST)) {
            g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, starAST.getToken(), starAST.getToken().getText());
        }
        // loop enter edge (alt 1)
        epsilon(entry, blkStart);
        // bypass loop edge (alt 2)
        epsilon(entry, end);
    } else {
        // if not greedy, priority to exit branch; make it first
        // bypass loop edge (alt 1)
        epsilon(entry, end);
        // loop enter edge (alt 2)
        epsilon(entry, blkStart);
    }
    // block end hits loop back
    epsilon(blkEnd, loop);
    // loop back to entry/exit decision
    epsilon(loop, entry);
    // decision is to enter/exit; blk is its own decision
    starAST.atnState = entry;
    return new Handle(entry, end);
}
Also used : StarBlockStartState(org.antlr.v4.runtime.atn.StarBlockStartState) LoopEndState(org.antlr.v4.runtime.atn.LoopEndState) StarLoopbackState(org.antlr.v4.runtime.atn.StarLoopbackState) StarLoopEntryState(org.antlr.v4.runtime.atn.StarLoopEntryState) BlockAST(org.antlr.v4.tool.ast.BlockAST) QuantifierAST(org.antlr.v4.tool.ast.QuantifierAST) BlockEndState(org.antlr.v4.runtime.atn.BlockEndState) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 10 with BlockEndState

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

the class ParserATNFactory method makeBlock.

@NotNull
protected Handle makeBlock(@NotNull BlockStartState start, @NotNull BlockAST blkAST, @NotNull List<Handle> alts) {
    start.sll = isSLLDecision(blkAST);
    BlockEndState end = newState(BlockEndState.class, blkAST);
    start.endState = end;
    for (Handle alt : alts) {
        // hook alts up to decision block
        epsilon(start, alt.left);
        epsilon(alt.right, end);
        // no back link in ATN so must walk entire alt to see if we can
        // strip out the epsilon to 'end' state
        TailEpsilonRemover opt = new TailEpsilonRemover(atn);
        opt.visit(alt.left);
    }
    Handle h = new Handle(start, end);
    // FASerializer ser = new FASerializer(g, h.left);
    // System.out.println(blkAST.toStringTree()+":\n"+ser);
    blkAST.atnState = start;
    return h;
}
Also used : BlockEndState(org.antlr.v4.runtime.atn.BlockEndState) NotNull(org.antlr.v4.runtime.misc.NotNull)

Aggregations

BlockEndState (org.antlr.v4.runtime.atn.BlockEndState)8 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)7 NotNull (org.antlr.v4.runtime.misc.NotNull)5 ATNState (org.antlr.v4.runtime.atn.ATNState)4 LoopEndState (org.antlr.v4.runtime.atn.LoopEndState)4 PlusBlockStartState (org.antlr.v4.runtime.atn.PlusBlockStartState)4 StarBlockStartState (org.antlr.v4.runtime.atn.StarBlockStartState)4 Rule (org.antlr.v4.tool.Rule)4 BlockAST (org.antlr.v4.tool.ast.BlockAST)4 QuantifierAST (org.antlr.v4.tool.ast.QuantifierAST)4 ArrayList (java.util.ArrayList)3 Interval (org.antlr.v4.runtime.misc.Interval)3 InvalidClassException (java.io.InvalidClassException)2 BitSet (java.util.BitSet)2 UUID (java.util.UUID)2 AtomTransition (org.antlr.v4.runtime.atn.AtomTransition)2 BasicBlockStartState (org.antlr.v4.runtime.atn.BasicBlockStartState)2 BlockStartState (org.antlr.v4.runtime.atn.BlockStartState)2 DecisionState (org.antlr.v4.runtime.atn.DecisionState)2 EpsilonTransition (org.antlr.v4.runtime.atn.EpsilonTransition)2