Search in sources :

Example 6 with Transition

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

the class DOTGenerator method getDOT.

/** Return a String containing a DOT description that, when displayed,
     *  will show the incoming state machine visually.  All nodes reachable
     *  from startState will be included.
     */
public String getDOT(ATNState startState, String[] ruleNames, boolean isLexer) {
    if (startState == null)
        return null;
    // The output DOT graph for visualization
    Set<ATNState> markedStates = new HashSet<ATNState>();
    ST dot = stlib.getInstanceOf("atn");
    dot.add("startState", startState.stateNumber);
    dot.add("rankdir", rankdir);
    List<ATNState> work = new LinkedList<ATNState>();
    work.add(startState);
    while (!work.isEmpty()) {
        ATNState s = work.get(0);
        if (markedStates.contains(s)) {
            work.remove(0);
            continue;
        }
        markedStates.add(s);
        // don't go past end of rule node to the follow states
        if (s instanceof RuleStopState)
            continue;
        // special case: if decision point, then line up the alt start states
        // unless it's an end of block
        //			if ( s instanceof BlockStartState ) {
        //				ST rankST = stlib.getInstanceOf("decision-rank");
        //				DecisionState alt = (DecisionState)s;
        //				for (int i=0; i<alt.getNumberOfTransitions(); i++) {
        //					ATNState target = alt.transition(i).target;
        //					if ( target!=null ) {
        //						rankST.add("states", target.stateNumber);
        //					}
        //				}
        //				dot.add("decisionRanks", rankST);
        //			}
        // make a DOT edge for each transition
        ST edgeST;
        for (int i = 0; i < s.getNumberOfTransitions(); i++) {
            Transition edge = s.transition(i);
            if (edge instanceof RuleTransition) {
                RuleTransition rr = ((RuleTransition) edge);
                // don't jump to other rules, but display edge to follow node
                edgeST = stlib.getInstanceOf("edge");
                String label = "<" + ruleNames[rr.ruleIndex];
                if (((RuleStartState) rr.target).isLeftRecursiveRule) {
                    label += "[" + rr.precedence + "]";
                }
                label += ">";
                edgeST.add("label", label);
                edgeST.add("src", "s" + s.stateNumber);
                edgeST.add("target", "s" + rr.followState.stateNumber);
                edgeST.add("arrowhead", arrowhead);
                dot.add("edges", edgeST);
                work.add(rr.followState);
                continue;
            }
            if (edge instanceof ActionTransition) {
                edgeST = stlib.getInstanceOf("action-edge");
                edgeST.add("label", getEdgeLabel(edge.toString()));
            } else if (edge instanceof AbstractPredicateTransition) {
                edgeST = stlib.getInstanceOf("edge");
                edgeST.add("label", getEdgeLabel(edge.toString()));
            } else if (edge.isEpsilon()) {
                edgeST = stlib.getInstanceOf("epsilon-edge");
                edgeST.add("label", getEdgeLabel(edge.toString()));
                boolean loopback = false;
                if (edge.target instanceof PlusBlockStartState) {
                    loopback = s.equals(((PlusBlockStartState) edge.target).loopBackState);
                } else if (edge.target instanceof StarLoopEntryState) {
                    loopback = s.equals(((StarLoopEntryState) edge.target).loopBackState);
                }
                edgeST.add("loopback", loopback);
            } else if (edge instanceof AtomTransition) {
                edgeST = stlib.getInstanceOf("edge");
                AtomTransition atom = (AtomTransition) edge;
                String label = String.valueOf(atom.label);
                if (isLexer)
                    label = "'" + getEdgeLabel(new StringBuilder().appendCodePoint(atom.label).toString()) + "'";
                else if (grammar != null)
                    label = grammar.getTokenDisplayName(atom.label);
                edgeST.add("label", getEdgeLabel(label));
            } else if (edge instanceof SetTransition) {
                edgeST = stlib.getInstanceOf("edge");
                SetTransition set = (SetTransition) edge;
                String label = set.label().toString();
                if (isLexer)
                    label = set.label().toString(true);
                else if (grammar != null)
                    label = set.label().toString(grammar.getVocabulary());
                if (edge instanceof NotSetTransition)
                    label = "~" + label;
                edgeST.add("label", getEdgeLabel(label));
            } else if (edge instanceof RangeTransition) {
                edgeST = stlib.getInstanceOf("edge");
                RangeTransition range = (RangeTransition) edge;
                String label = range.label().toString();
                if (isLexer)
                    label = range.toString();
                else if (grammar != null)
                    label = range.label().toString(grammar.getVocabulary());
                edgeST.add("label", getEdgeLabel(label));
            } else {
                edgeST = stlib.getInstanceOf("edge");
                edgeST.add("label", getEdgeLabel(edge.toString()));
            }
            edgeST.add("src", "s" + s.stateNumber);
            edgeST.add("target", "s" + edge.target.stateNumber);
            edgeST.add("arrowhead", arrowhead);
            if (s.getNumberOfTransitions() > 1) {
                edgeST.add("transitionIndex", i);
            } else {
                edgeST.add("transitionIndex", false);
            }
            dot.add("edges", edgeST);
            work.add(edge.target);
        }
    }
    //		}
    for (ATNState s : markedStates) {
        if (!(s instanceof RuleStopState))
            continue;
        ST st = stlib.getInstanceOf("stopstate");
        st.add("name", "s" + s.stateNumber);
        st.add("label", getStateLabel(s));
        dot.add("states", st);
    }
    for (ATNState s : markedStates) {
        if (s instanceof RuleStopState)
            continue;
        ST st = stlib.getInstanceOf("state");
        st.add("name", "s" + s.stateNumber);
        st.add("label", getStateLabel(s));
        st.add("transitions", s.getTransitions());
        dot.add("states", st);
    }
    return dot.render();
}
Also used : ST(org.stringtemplate.v4.ST) RuleStopState(org.antlr.v4.runtime.atn.RuleStopState) AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) LinkedList(java.util.LinkedList) ATNState(org.antlr.v4.runtime.atn.ATNState) PlusBlockStartState(org.antlr.v4.runtime.atn.PlusBlockStartState) ActionTransition(org.antlr.v4.runtime.atn.ActionTransition) StarLoopEntryState(org.antlr.v4.runtime.atn.StarLoopEntryState) RuleStartState(org.antlr.v4.runtime.atn.RuleStartState) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) ActionTransition(org.antlr.v4.runtime.atn.ActionTransition) Transition(org.antlr.v4.runtime.atn.Transition) AbstractPredicateTransition(org.antlr.v4.runtime.atn.AbstractPredicateTransition) AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) AbstractPredicateTransition(org.antlr.v4.runtime.atn.AbstractPredicateTransition) HashSet(java.util.HashSet)

Example 7 with Transition

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

the class ParserATNFactory method addEOFTransitionToStartRules.

/** Add an EOF transition to any rule end ATNState that points to nothing
     *  (i.e., for all those rules not invoked by another rule).  These
     *  are start symbols then.
	 *
	 *  Return the number of grammar entry points; i.e., how many rules are
	 *  not invoked by another rule (they can only be invoked from outside).
	 *  These are the start rules.
     */
public int addEOFTransitionToStartRules() {
    int n = 0;
    // one unique EOF target for all rules
    ATNState eofTarget = newState(null);
    for (Rule r : g.rules.values()) {
        ATNState stop = atn.ruleToStopState[r.index];
        if (stop.getNumberOfTransitions() > 0)
            continue;
        n++;
        Transition t = new AtomTransition(eofTarget, Token.EOF);
        stop.addTransition(t);
    }
    return n;
}
Also used : AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) 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) Rule(org.antlr.v4.tool.Rule) LeftRecursiveRule(org.antlr.v4.tool.LeftRecursiveRule) ATNState(org.antlr.v4.runtime.atn.ATNState)

Example 8 with Transition

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

the class LeftRecursionDetector method check.

/** From state s, look for any transition to a rule that is currently
	 *  being traced.  When tracing r, visitedPerRuleCheck has r
	 *  initially.  If you reach a rule stop state, return but notify the
	 *  invoking rule that the called rule is nullable. This implies that
	 *  invoking rule must look at follow transition for that invoking state.
	 *
	 *  The visitedStates tracks visited states within a single rule so
	 *  we can avoid epsilon-loop-induced infinite recursion here.  Keep
	 *  filling the cycles in listOfRecursiveCycles and also, as a
	 *  side-effect, set leftRecursiveRules.
	 */
public boolean check(Rule enclosingRule, ATNState s, Set<ATNState> visitedStates) {
    if (s instanceof RuleStopState)
        return true;
    if (visitedStates.contains(s))
        return false;
    visitedStates.add(s);
    //System.out.println("visit "+s);
    int n = s.getNumberOfTransitions();
    boolean stateReachesStopState = false;
    for (int i = 0; i < n; i++) {
        Transition t = s.transition(i);
        if (t instanceof RuleTransition) {
            RuleTransition rt = (RuleTransition) t;
            Rule r = g.getRule(rt.ruleIndex);
            if (rulesVisitedPerRuleCheck.contains((RuleStartState) t.target)) {
                addRulesToCycle(enclosingRule, r);
            } else {
                // must visit if not already visited; mark target, pop when done
                rulesVisitedPerRuleCheck.add((RuleStartState) t.target);
                // send new visitedStates set per rule invocation
                boolean nullable = check(r, t.target, new HashSet<ATNState>());
                // we're back from visiting that rule
                rulesVisitedPerRuleCheck.remove((RuleStartState) t.target);
                if (nullable) {
                    stateReachesStopState |= check(enclosingRule, rt.followState, visitedStates);
                }
            }
        } else if (t.isEpsilon()) {
            stateReachesStopState |= check(enclosingRule, t.target, visitedStates);
        }
    // else ignore non-epsilon transitions
    }
    return stateReachesStopState;
}
Also used : RuleStopState(org.antlr.v4.runtime.atn.RuleStopState) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) Transition(org.antlr.v4.runtime.atn.Transition) Rule(org.antlr.v4.tool.Rule) ATNState(org.antlr.v4.runtime.atn.ATNState)

Example 9 with Transition

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

the class LexerATNFactory method tokenRef.

@Override
public Handle tokenRef(TerminalAST node) {
    // Ref to EOF in lexer yields char transition on -1
    if (node.getText().equals("EOF")) {
        ATNState left = newState(node);
        ATNState right = newState(node);
        left.addTransition(new AtomTransition(right, IntStream.EOF));
        return new Handle(left, right);
    }
    return _ruleRef(node);
}
Also used : AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) ATNState(org.antlr.v4.runtime.atn.ATNState)

Example 10 with Transition

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

the class LexerATNFactory method stringLiteral.

/** For a lexer, a string is a sequence of char to match.  That is,
	 *  "fog" is treated as 'f' 'o' 'g' not as a single transition in
	 *  the DFA.  Machine== o-'f'-&gt;o-'o'-&gt;o-'g'-&gt;o and has n+1 states
	 *  for n characters.
	 */
@Override
public Handle stringLiteral(TerminalAST stringLiteralAST) {
    String chars = stringLiteralAST.getText();
    ATNState left = newState(stringLiteralAST);
    ATNState right;
    chars = CharSupport.getStringFromGrammarStringLiteral(chars);
    if (chars == null) {
        g.tool.errMgr.grammarError(ErrorType.INVALID_ESCAPE_SEQUENCE, g.fileName, stringLiteralAST.getToken());
        return new Handle(left, left);
    }
    int n = chars.length();
    ATNState prev = left;
    right = null;
    for (int i = 0; i < n; ) {
        right = newState(stringLiteralAST);
        int codePoint = chars.codePointAt(i);
        prev.addTransition(CodePointTransitions.createWithCodePoint(right, codePoint));
        prev = right;
        i += Character.charCount(codePoint);
    }
    stringLiteralAST.atnState = left;
    return new Handle(left, right);
}
Also used : ATNState(org.antlr.v4.runtime.atn.ATNState)

Aggregations

ATNState (org.antlr.v4.runtime.atn.ATNState)12 Transition (org.antlr.v4.runtime.atn.Transition)11 AtomTransition (org.antlr.v4.runtime.atn.AtomTransition)9 ActionTransition (org.antlr.v4.runtime.atn.ActionTransition)8 RuleTransition (org.antlr.v4.runtime.atn.RuleTransition)8 SetTransition (org.antlr.v4.runtime.atn.SetTransition)7 NotSetTransition (org.antlr.v4.runtime.atn.NotSetTransition)6 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)6 PrecedencePredicateTransition (org.antlr.v4.runtime.atn.PrecedencePredicateTransition)5 PredicateTransition (org.antlr.v4.runtime.atn.PredicateTransition)5 RuleStartState (org.antlr.v4.runtime.atn.RuleStartState)5 AbstractPredicateTransition (org.antlr.v4.runtime.atn.AbstractPredicateTransition)4 EpsilonTransition (org.antlr.v4.runtime.atn.EpsilonTransition)4 ArrayList (java.util.ArrayList)3 DecisionState (org.antlr.v4.runtime.atn.DecisionState)3 RangeTransition (org.antlr.v4.runtime.atn.RangeTransition)3 RuleStopState (org.antlr.v4.runtime.atn.RuleStopState)3 Interval (org.antlr.v4.runtime.misc.Interval)3 Rule (org.antlr.v4.tool.Rule)3 HashMap (java.util.HashMap)2