Search in sources :

Example 56 with NotNull

use of org.antlr.v4.runtime.misc.NotNull 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 57 with NotNull

use of org.antlr.v4.runtime.misc.NotNull in project antlr4 by tunnelvisionlabs.

the class ParserATNFactory method elemList.

@NotNull
public Handle elemList(@NotNull List<Handle> els) {
    int n = els.size();
    for (int i = 0; i < n - 1; i++) {
        // hook up elements (visit all but last)
        Handle el = els.get(i);
        // if el is of form o-x->o for x in {rule, action, pred, token, ...}
        // and not last in alt
        Transition tr = null;
        if (el.left.getNumberOfTransitions() == 1)
            tr = el.left.transition(0);
        boolean isRuleTrans = tr instanceof RuleTransition;
        if (el.left.getStateType() == ATNState.BASIC && el.right.getStateType() == ATNState.BASIC && tr != null && (isRuleTrans && ((RuleTransition) tr).followState == el.right || tr.target == el.right)) {
            // we can avoid epsilon edge to next el
            if (isRuleTrans)
                ((RuleTransition) tr).followState = els.get(i + 1).left;
            else
                tr.target = els.get(i + 1).left;
            // we skipped over this state
            atn.removeState(el.right);
        } else {
            // need epsilon if previous block's right end node is complicated
            epsilon(el.right, els.get(i + 1).left);
        }
    }
    Handle first = els.get(0);
    Handle last = els.get(n - 1);
    if (first == null || last == null) {
        g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "element list has first|last == null");
    }
    return new Handle(first.left, last.right);
}
Also used : RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) WildcardTransition(org.antlr.v4.runtime.atn.WildcardTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) PrecedencePredicateTransition(org.antlr.v4.runtime.atn.PrecedencePredicateTransition) AbstractPredicateTransition(org.antlr.v4.runtime.atn.AbstractPredicateTransition) PredicateTransition(org.antlr.v4.runtime.atn.PredicateTransition) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition) ActionTransition(org.antlr.v4.runtime.atn.ActionTransition) Transition(org.antlr.v4.runtime.atn.Transition) AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 58 with NotNull

use of org.antlr.v4.runtime.misc.NotNull in project antlr4 by tunnelvisionlabs.

the class ParserATNFactory method createATN.

@NotNull
@Override
public ATN createATN() {
    _createATN(g.rules.values());
    assert atn.maxTokenType == g.getMaxTokenType();
    addRuleFollowLinks();
    addEOFTransitionToStartRules();
    ATNOptimizer.optimize(g, atn);
    for (Tuple3<? extends Rule, ? extends ATNState, ? extends ATNState> pair : preventEpsilonClosureBlocks) {
        LL1Analyzer analyzer = new LL1Analyzer(atn);
        ATNState blkStart = pair.getItem2();
        ATNState blkStop = pair.getItem3();
        IntervalSet lookahead = analyzer.LOOK(blkStart, blkStop, PredictionContext.EMPTY_LOCAL);
        if (lookahead.contains(org.antlr.v4.runtime.Token.EPSILON)) {
            ErrorType errorType = pair.getItem1() instanceof LeftRecursiveRule ? ErrorType.EPSILON_LR_FOLLOW : ErrorType.EPSILON_CLOSURE;
            g.tool.errMgr.grammarError(errorType, g.fileName, ((GrammarAST) pair.getItem1().ast.getChild(0)).getToken(), pair.getItem1().name);
        }
    }
    optionalCheck: for (Tuple3<? extends Rule, ? extends ATNState, ? extends ATNState> pair : preventEpsilonOptionalBlocks) {
        int bypassCount = 0;
        for (int i = 0; i < pair.getItem2().getNumberOfTransitions(); i++) {
            ATNState startState = pair.getItem2().transition(i).target;
            if (startState == pair.getItem3()) {
                bypassCount++;
                continue;
            }
            LL1Analyzer analyzer = new LL1Analyzer(atn);
            if (analyzer.LOOK(startState, pair.getItem3(), PredictionContext.EMPTY_LOCAL).contains(org.antlr.v4.runtime.Token.EPSILON)) {
                g.tool.errMgr.grammarError(ErrorType.EPSILON_OPTIONAL, g.fileName, ((GrammarAST) pair.getItem1().ast.getChild(0)).getToken(), pair.getItem1().name);
                continue optionalCheck;
            }
        }
        if (bypassCount != 1) {
            throw new UnsupportedOperationException("Expected optional block with exactly 1 bypass alternative.");
        }
    }
    return atn;
}
Also used : LeftRecursiveRule(org.antlr.v4.tool.LeftRecursiveRule) LL1Analyzer(org.antlr.v4.runtime.atn.LL1Analyzer) ErrorType(org.antlr.v4.tool.ErrorType) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Tuple3(org.antlr.v4.runtime.misc.Tuple3) GrammarAST(org.antlr.v4.tool.ast.GrammarAST) Rule(org.antlr.v4.tool.Rule) LeftRecursiveRule(org.antlr.v4.tool.LeftRecursiveRule) ATNState(org.antlr.v4.runtime.atn.ATNState) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 59 with NotNull

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

Example 60 with NotNull

use of org.antlr.v4.runtime.misc.NotNull in project antlr4 by tunnelvisionlabs.

the class ParserATNFactory method block.

/**
 * From {@code A|B|..|Z} alternative block build
 *
 * <pre>
 *  o-&gt;o-A-&gt;o-&gt;o (last ATNState is BlockEndState pointed to by all alts)
 *  |          ^
 *  |-&gt;o-B-&gt;o--|
 *  |          |
 *  ...        |
 *  |          |
 *  |-&gt;o-Z-&gt;o--|
 * </pre>
 *
 * So start node points at every alternative with epsilon transition and
 * every alt right side points at a block end ATNState.
 * <p>
 * Special case: only one alternative: don't make a block with alt
 * begin/end.
 * <p>
 * Special case: if just a list of tokens/chars/sets, then collapse to a
 * single edged o-set-&gt;o graph.
 * <p>
 * TODO: Set alt number (1..n) in the states?
 */
@NotNull
@Override
public Handle block(@NotNull BlockAST blkAST, @NotNull GrammarAST ebnfRoot, @NotNull List<Handle> alts) {
    if (ebnfRoot == null) {
        if (alts.size() == 1) {
            Handle h = alts.get(0);
            blkAST.atnState = h.left;
            return h;
        }
        BlockStartState start = newState(BasicBlockStartState.class, blkAST);
        if (alts.size() > 1)
            atn.defineDecisionState(start);
        return makeBlock(start, blkAST, alts);
    }
    switch(ebnfRoot.getType()) {
        case ANTLRParser.OPTIONAL:
            BlockStartState start = newState(BasicBlockStartState.class, blkAST);
            atn.defineDecisionState(start);
            Handle h = makeBlock(start, blkAST, alts);
            return optional(ebnfRoot, h);
        case ANTLRParser.CLOSURE:
            BlockStartState star = newState(StarBlockStartState.class, ebnfRoot);
            if (alts.size() > 1)
                atn.defineDecisionState(star);
            h = makeBlock(star, blkAST, alts);
            return star(ebnfRoot, h);
        case ANTLRParser.POSITIVE_CLOSURE:
            PlusBlockStartState plus = newState(PlusBlockStartState.class, ebnfRoot);
            if (alts.size() > 1)
                atn.defineDecisionState(plus);
            h = makeBlock(plus, blkAST, alts);
            return plus(ebnfRoot, h);
    }
    return null;
}
Also used : PlusBlockStartState(org.antlr.v4.runtime.atn.PlusBlockStartState) PlusBlockStartState(org.antlr.v4.runtime.atn.PlusBlockStartState) StarBlockStartState(org.antlr.v4.runtime.atn.StarBlockStartState) BasicBlockStartState(org.antlr.v4.runtime.atn.BasicBlockStartState) BlockStartState(org.antlr.v4.runtime.atn.BlockStartState) NotNull(org.antlr.v4.runtime.misc.NotNull)

Aggregations

NotNull (org.antlr.v4.runtime.misc.NotNull)40 ATNState (org.antlr.v4.runtime.atn.ATNState)14 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)14 DFAState (org.antlr.v4.runtime.dfa.DFAState)12 ParseTree (org.antlr.v4.runtime.tree.ParseTree)9 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)8 ArrayList (java.util.ArrayList)7 Token (org.antlr.v4.runtime.Token)7 RuleTransition (org.antlr.v4.runtime.atn.RuleTransition)4 DFA (org.antlr.v4.runtime.dfa.DFA)4 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)4 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)4 QuantifierAST (org.antlr.v4.tool.ast.QuantifierAST)4 List (java.util.List)3 ATN (org.antlr.v4.runtime.atn.ATN)3 BlockEndState (org.antlr.v4.runtime.atn.BlockEndState)3 Transition (org.antlr.v4.runtime.atn.Transition)3 WildcardTransition (org.antlr.v4.runtime.atn.WildcardTransition)3 Interval (org.antlr.v4.runtime.misc.Interval)3 Nullable (org.antlr.v4.runtime.misc.Nullable)3