Search in sources :

Example 6 with SetTransition

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

the class ATNOptimizer method optimizeSets.

private static void optimizeSets(Grammar g, ATN atn) {
    if (g.isParser()) {
        // parser codegen doesn't currently support SetTransition
        return;
    }
    int removedStates = 0;
    List<DecisionState> decisions = atn.decisionToState;
    for (DecisionState decision : decisions) {
        if (decision.ruleIndex >= 0) {
            Rule rule = g.getRule(decision.ruleIndex);
            if (Character.isLowerCase(rule.name.charAt(0))) {
                // parser codegen doesn't currently support SetTransition
                continue;
            }
        }
        IntervalSet setTransitions = new IntervalSet();
        for (int i = 0; i < decision.getNumberOfTransitions(); i++) {
            Transition epsTransition = decision.transition(i);
            if (!(epsTransition instanceof EpsilonTransition)) {
                continue;
            }
            if (epsTransition.target.getNumberOfTransitions() != 1) {
                continue;
            }
            Transition transition = epsTransition.target.transition(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);
            }
        }
        // due to min alt resolution policies, can only collapse sequential alts
        for (int i = setTransitions.getIntervals().size() - 1; i >= 0; i--) {
            Interval interval = setTransitions.getIntervals().get(i);
            if (interval.length() <= 1) {
                continue;
            }
            ATNState blockEndState = decision.transition(interval.a).target.transition(0).target;
            IntervalSet matchSet = new IntervalSet();
            for (int j = interval.a; j <= interval.b; j++) {
                Transition matchTransition = decision.transition(j).target.transition(0);
                if (matchTransition instanceof NotSetTransition) {
                    throw new UnsupportedOperationException("Not yet implemented.");
                }
                IntervalSet set = matchTransition.label();
                List<Interval> intervals = set.getIntervals();
                int n = intervals.size();
                for (int k = 0; k < n; k++) {
                    Interval setInterval = intervals.get(k);
                    int a = setInterval.a;
                    int b = setInterval.b;
                    if (a != -1 && b != -1) {
                        for (int v = a; v <= b; v++) {
                            if (matchSet.contains(v)) {
                                // TODO: Token is missing (i.e. position in source will not be displayed).
                                g.tool.errMgr.grammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, null, CharSupport.getANTLRCharLiteralForChar(v), CharSupport.getIntervalSetEscapedString(matchSet));
                                break;
                            }
                        }
                    }
                }
                matchSet.addAll(set);
            }
            Transition newTransition;
            if (matchSet.getIntervals().size() == 1) {
                if (matchSet.size() == 1) {
                    newTransition = CodePointTransitions.createWithCodePoint(blockEndState, matchSet.getMinElement());
                } else {
                    Interval matchInterval = matchSet.getIntervals().get(0);
                    newTransition = CodePointTransitions.createWithCodePointRange(blockEndState, matchInterval.a, matchInterval.b);
                }
            } else {
                newTransition = new SetTransition(blockEndState, matchSet);
            }
            decision.transition(interval.a).target.setTransition(0, newTransition);
            for (int j = interval.a + 1; j <= interval.b; j++) {
                Transition removed = decision.removeTransition(interval.a + 1);
                atn.removeState(removed.target);
                removedStates++;
            }
        }
    }
//		System.out.println("ATN optimizer removed " + removedStates + " states by collapsing sets.");
}
Also used : AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) DecisionState(org.antlr.v4.runtime.atn.DecisionState) BlockEndState(org.antlr.v4.runtime.atn.BlockEndState) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) ATNState(org.antlr.v4.runtime.atn.ATNState) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) Transition(org.antlr.v4.runtime.atn.Transition) Rule(org.antlr.v4.tool.Rule) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition) Interval(org.antlr.v4.runtime.misc.Interval)

Example 7 with SetTransition

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

the class ATNPrinter method asString.

public String asString() {
    if (start == null)
        return null;
    marked = new HashSet<ATNState>();
    work = new ArrayList<ATNState>();
    work.add(start);
    StringBuilder buf = new StringBuilder();
    ATNState s;
    while (!work.isEmpty()) {
        s = work.remove(0);
        if (marked.contains(s))
            continue;
        int n = s.getNumberOfTransitions();
        //			System.out.println("visit "+s+"; edges="+n);
        marked.add(s);
        for (int i = 0; i < n; i++) {
            Transition t = s.transition(i);
            if (!(s instanceof RuleStopState)) {
                // don't add follow states to work
                if (t instanceof RuleTransition)
                    work.add(((RuleTransition) t).followState);
                else
                    work.add(t.target);
            }
            buf.append(getStateString(s));
            if (t instanceof EpsilonTransition) {
                buf.append("->").append(getStateString(t.target)).append('\n');
            } else if (t instanceof RuleTransition) {
                buf.append("-").append(g.getRule(((RuleTransition) t).ruleIndex).name).append("->").append(getStateString(t.target)).append('\n');
            } else if (t instanceof ActionTransition) {
                ActionTransition a = (ActionTransition) t;
                buf.append("-").append(a.toString()).append("->").append(getStateString(t.target)).append('\n');
            } else if (t instanceof SetTransition) {
                SetTransition st = (SetTransition) t;
                boolean not = st instanceof NotSetTransition;
                if (g.isLexer()) {
                    buf.append("-").append(not ? "~" : "").append(st.toString()).append("->").append(getStateString(t.target)).append('\n');
                } else {
                    buf.append("-").append(not ? "~" : "").append(st.label().toString(g.getVocabulary())).append("->").append(getStateString(t.target)).append('\n');
                }
            } else if (t instanceof AtomTransition) {
                AtomTransition a = (AtomTransition) t;
                String label = g.getTokenDisplayName(a.label);
                buf.append("-").append(label).append("->").append(getStateString(t.target)).append('\n');
            } else {
                buf.append("-").append(t.toString()).append("->").append(getStateString(t.target)).append('\n');
            }
        }
    }
    return buf.toString();
}
Also used : 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) ATNState(org.antlr.v4.runtime.atn.ATNState) ActionTransition(org.antlr.v4.runtime.atn.ActionTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) ActionTransition(org.antlr.v4.runtime.atn.ActionTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) Transition(org.antlr.v4.runtime.atn.Transition) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition)

Example 8 with SetTransition

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

the class LexerATNFactory method set.

@Override
public Handle set(GrammarAST associatedAST, List<GrammarAST> alts, boolean invert) {
    ATNState left = newState(associatedAST);
    ATNState right = newState(associatedAST);
    IntervalSet set = new IntervalSet();
    for (GrammarAST t : alts) {
        if (t.getType() == ANTLRParser.RANGE) {
            int a = CharSupport.getCharValueFromGrammarCharLiteral(t.getChild(0).getText());
            int b = CharSupport.getCharValueFromGrammarCharLiteral(t.getChild(1).getText());
            if (checkRange((GrammarAST) t.getChild(0), (GrammarAST) t.getChild(1), a, b)) {
                checkSetCollision(associatedAST, set, a, b);
                set.add(a, b);
            }
        } else if (t.getType() == ANTLRParser.LEXER_CHAR_SET) {
            set.addAll(getSetFromCharSetLiteral(t));
        } else if (t.getType() == ANTLRParser.STRING_LITERAL) {
            int c = CharSupport.getCharValueFromGrammarCharLiteral(t.getText());
            if (c != -1) {
                checkSetCollision(associatedAST, set, c);
                set.add(c);
            } else {
                g.tool.errMgr.grammarError(ErrorType.INVALID_LITERAL_IN_LEXER_SET, g.fileName, t.getToken(), t.getText());
            }
        } else if (t.getType() == ANTLRParser.TOKEN_REF) {
            g.tool.errMgr.grammarError(ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET, g.fileName, t.getToken(), t.getText());
        }
    }
    if (invert) {
        left.addTransition(new NotSetTransition(right, set));
    } else {
        Transition transition;
        if (set.getIntervals().size() == 1) {
            Interval interval = set.getIntervals().get(0);
            transition = CodePointTransitions.createWithCodePointRange(right, interval.a, interval.b);
        } else {
            transition = new SetTransition(right, set);
        }
        left.addTransition(transition);
    }
    associatedAST.atnState = left;
    return new Handle(left, right);
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) GrammarAST(org.antlr.v4.tool.ast.GrammarAST) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) 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) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) ATNState(org.antlr.v4.runtime.atn.ATNState) Interval(org.antlr.v4.runtime.misc.Interval)

Aggregations

ATNState (org.antlr.v4.runtime.atn.ATNState)7 SetTransition (org.antlr.v4.runtime.atn.SetTransition)7 NotSetTransition (org.antlr.v4.runtime.atn.NotSetTransition)6 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)6 AtomTransition (org.antlr.v4.runtime.atn.AtomTransition)5 Transition (org.antlr.v4.runtime.atn.Transition)5 ActionTransition (org.antlr.v4.runtime.atn.ActionTransition)4 RangeTransition (org.antlr.v4.runtime.atn.RangeTransition)3 RuleTransition (org.antlr.v4.runtime.atn.RuleTransition)3 Interval (org.antlr.v4.runtime.misc.Interval)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 DecisionState (org.antlr.v4.runtime.atn.DecisionState)2 EpsilonTransition (org.antlr.v4.runtime.atn.EpsilonTransition)2 RuleStartState (org.antlr.v4.runtime.atn.RuleStartState)2 RuleStopState (org.antlr.v4.runtime.atn.RuleStopState)2 IntegerList (org.antlr.v4.runtime.misc.IntegerList)2 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)2 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1