Search in sources :

Example 1 with RangeTransition

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

the class ATNSerializer method serialize.

/** Serialize state descriptors, edge descriptors, and decision→state map
	 *  into list of ints:
	 *
	 * 		grammar-type, (ANTLRParser.LEXER, ...)
	 *  	max token type,
	 *  	num states,
	 *  	state-0-type ruleIndex, state-1-type ruleIndex, ... state-i-type ruleIndex optional-arg ...
	 *  	num rules,
	 *  	rule-1-start-state rule-1-args, rule-2-start-state  rule-2-args, ...
	 *  	(args are token type,actionIndex in lexer else 0,0)
	 *      num modes,
	 *      mode-0-start-state, mode-1-start-state, ... (parser has 0 modes)
	 *      num unicode-bmp-sets
	 *      bmp-set-0-interval-count intervals, bmp-set-1-interval-count intervals, ...
	 *      num unicode-smp-sets
	 *      smp-set-0-interval-count intervals, smp-set-1-interval-count intervals, ...
	 *	num total edges,
	 *      src, trg, edge-type, edge arg1, optional edge arg2 (present always), ...
	 *      num decisions,
	 *      decision-0-start-state, decision-1-start-state, ...
	 *
	 *  Convenient to pack into unsigned shorts to make as Java string.
	 */
public IntegerList serialize() {
    IntegerList data = new IntegerList();
    data.add(ATNDeserializer.SERIALIZED_VERSION);
    serializeUUID(data, ATNDeserializer.SERIALIZED_UUID);
    // convert grammar type to ATN const to avoid dependence on ANTLRParser
    data.add(atn.grammarType.ordinal());
    data.add(atn.maxTokenType);
    int nedges = 0;
    // Note that we use a LinkedHashMap as a set to
    // maintain insertion order while deduplicating
    // entries with the same key.
    Map<IntervalSet, Boolean> sets = new LinkedHashMap<>();
    // dump states, count edges and collect sets while doing so
    IntegerList nonGreedyStates = new IntegerList();
    IntegerList precedenceStates = new IntegerList();
    data.add(atn.states.size());
    for (ATNState s : atn.states) {
        if (s == null) {
            // might be optimized away
            data.add(ATNState.INVALID_TYPE);
            continue;
        }
        int stateType = s.getStateType();
        if (s instanceof DecisionState && ((DecisionState) s).nonGreedy) {
            nonGreedyStates.add(s.stateNumber);
        }
        if (s instanceof RuleStartState && ((RuleStartState) s).isLeftRecursiveRule) {
            precedenceStates.add(s.stateNumber);
        }
        data.add(stateType);
        if (s.ruleIndex == -1) {
            data.add(Character.MAX_VALUE);
        } else {
            data.add(s.ruleIndex);
        }
        if (s.getStateType() == ATNState.LOOP_END) {
            data.add(((LoopEndState) s).loopBackState.stateNumber);
        } else if (s instanceof BlockStartState) {
            data.add(((BlockStartState) s).endState.stateNumber);
        }
        if (s.getStateType() != ATNState.RULE_STOP) {
            // the deserializer can trivially derive these edges, so there's no need to serialize them
            nedges += s.getNumberOfTransitions();
        }
        for (int i = 0; i < s.getNumberOfTransitions(); i++) {
            Transition t = s.transition(i);
            int edgeType = Transition.serializationTypes.get(t.getClass());
            if (edgeType == Transition.SET || edgeType == Transition.NOT_SET) {
                SetTransition st = (SetTransition) t;
                sets.put(st.set, true);
            }
        }
    }
    // non-greedy states
    data.add(nonGreedyStates.size());
    for (int i = 0; i < nonGreedyStates.size(); i++) {
        data.add(nonGreedyStates.get(i));
    }
    // precedence states
    data.add(precedenceStates.size());
    for (int i = 0; i < precedenceStates.size(); i++) {
        data.add(precedenceStates.get(i));
    }
    int nrules = atn.ruleToStartState.length;
    data.add(nrules);
    for (int r = 0; r < nrules; r++) {
        ATNState ruleStartState = atn.ruleToStartState[r];
        data.add(ruleStartState.stateNumber);
        if (atn.grammarType == ATNType.LEXER) {
            if (atn.ruleToTokenType[r] == Token.EOF) {
                data.add(Character.MAX_VALUE);
            } else {
                data.add(atn.ruleToTokenType[r]);
            }
        }
    }
    int nmodes = atn.modeToStartState.size();
    data.add(nmodes);
    if (nmodes > 0) {
        for (ATNState modeStartState : atn.modeToStartState) {
            data.add(modeStartState.stateNumber);
        }
    }
    List<IntervalSet> bmpSets = new ArrayList<>();
    List<IntervalSet> smpSets = new ArrayList<>();
    for (IntervalSet set : sets.keySet()) {
        if (set.getMaxElement() <= Character.MAX_VALUE) {
            bmpSets.add(set);
        } else {
            smpSets.add(set);
        }
    }
    serializeSets(data, bmpSets, new CodePointSerializer() {

        @Override
        public void serializeCodePoint(IntegerList data, int cp) {
            data.add(cp);
        }
    });
    serializeSets(data, smpSets, new CodePointSerializer() {

        @Override
        public void serializeCodePoint(IntegerList data, int cp) {
            serializeInt(data, cp);
        }
    });
    Map<IntervalSet, Integer> setIndices = new HashMap<>();
    int setIndex = 0;
    for (IntervalSet bmpSet : bmpSets) {
        setIndices.put(bmpSet, setIndex++);
    }
    for (IntervalSet smpSet : smpSets) {
        setIndices.put(smpSet, setIndex++);
    }
    data.add(nedges);
    for (ATNState s : atn.states) {
        if (s == null) {
            // might be optimized away
            continue;
        }
        if (s.getStateType() == ATNState.RULE_STOP) {
            continue;
        }
        for (int i = 0; i < s.getNumberOfTransitions(); i++) {
            Transition t = s.transition(i);
            if (atn.states.get(t.target.stateNumber) == null) {
                throw new IllegalStateException("Cannot serialize a transition to a removed state.");
            }
            int src = s.stateNumber;
            int trg = t.target.stateNumber;
            int edgeType = Transition.serializationTypes.get(t.getClass());
            int arg1 = 0;
            int arg2 = 0;
            int arg3 = 0;
            switch(edgeType) {
                case Transition.RULE:
                    trg = ((RuleTransition) t).followState.stateNumber;
                    arg1 = ((RuleTransition) t).target.stateNumber;
                    arg2 = ((RuleTransition) t).ruleIndex;
                    arg3 = ((RuleTransition) t).precedence;
                    break;
                case Transition.PRECEDENCE:
                    PrecedencePredicateTransition ppt = (PrecedencePredicateTransition) t;
                    arg1 = ppt.precedence;
                    break;
                case Transition.PREDICATE:
                    PredicateTransition pt = (PredicateTransition) t;
                    arg1 = pt.ruleIndex;
                    arg2 = pt.predIndex;
                    arg3 = pt.isCtxDependent ? 1 : 0;
                    break;
                case Transition.RANGE:
                    arg1 = ((RangeTransition) t).from;
                    arg2 = ((RangeTransition) t).to;
                    if (arg1 == Token.EOF) {
                        arg1 = 0;
                        arg3 = 1;
                    }
                    break;
                case Transition.ATOM:
                    arg1 = ((AtomTransition) t).label;
                    if (arg1 == Token.EOF) {
                        arg1 = 0;
                        arg3 = 1;
                    }
                    break;
                case Transition.ACTION:
                    ActionTransition at = (ActionTransition) t;
                    arg1 = at.ruleIndex;
                    arg2 = at.actionIndex;
                    if (arg2 == -1) {
                        arg2 = 0xFFFF;
                    }
                    arg3 = at.isCtxDependent ? 1 : 0;
                    break;
                case Transition.SET:
                    arg1 = setIndices.get(((SetTransition) t).set);
                    break;
                case Transition.NOT_SET:
                    arg1 = setIndices.get(((SetTransition) t).set);
                    break;
                case Transition.WILDCARD:
                    break;
            }
            data.add(src);
            data.add(trg);
            data.add(edgeType);
            data.add(arg1);
            data.add(arg2);
            data.add(arg3);
        }
    }
    int ndecisions = atn.decisionToState.size();
    data.add(ndecisions);
    for (DecisionState decStartState : atn.decisionToState) {
        data.add(decStartState.stateNumber);
    }
    //
    if (atn.grammarType == ATNType.LEXER) {
        data.add(atn.lexerActions.length);
        for (LexerAction action : atn.lexerActions) {
            data.add(action.getActionType().ordinal());
            switch(action.getActionType()) {
                case CHANNEL:
                    int channel = ((LexerChannelAction) action).getChannel();
                    data.add(channel != -1 ? channel : 0xFFFF);
                    data.add(0);
                    break;
                case CUSTOM:
                    int ruleIndex = ((LexerCustomAction) action).getRuleIndex();
                    int actionIndex = ((LexerCustomAction) action).getActionIndex();
                    data.add(ruleIndex != -1 ? ruleIndex : 0xFFFF);
                    data.add(actionIndex != -1 ? actionIndex : 0xFFFF);
                    break;
                case MODE:
                    int mode = ((LexerModeAction) action).getMode();
                    data.add(mode != -1 ? mode : 0xFFFF);
                    data.add(0);
                    break;
                case MORE:
                    data.add(0);
                    data.add(0);
                    break;
                case POP_MODE:
                    data.add(0);
                    data.add(0);
                    break;
                case PUSH_MODE:
                    mode = ((LexerPushModeAction) action).getMode();
                    data.add(mode != -1 ? mode : 0xFFFF);
                    data.add(0);
                    break;
                case SKIP:
                    data.add(0);
                    data.add(0);
                    break;
                case TYPE:
                    int type = ((LexerTypeAction) action).getType();
                    data.add(type != -1 ? type : 0xFFFF);
                    data.add(0);
                    break;
                default:
                    String message = String.format(Locale.getDefault(), "The specified lexer action type %s is not valid.", action.getActionType());
                    throw new IllegalArgumentException(message);
            }
        }
    }
    // don't adjust the first value since that's the version number
    for (int i = 1; i < data.size(); i++) {
        if (data.get(i) < Character.MIN_VALUE || data.get(i) > Character.MAX_VALUE) {
            throw new UnsupportedOperationException("Serialized ATN data element " + data.get(i) + " element " + i + " out of range " + (int) Character.MIN_VALUE + ".." + (int) Character.MAX_VALUE);
        }
        int value = (data.get(i) + 2) & 0xFFFF;
        data.set(i, value);
    }
    return data;
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) IntegerList(org.antlr.v4.runtime.misc.IntegerList) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet)

Example 2 with RangeTransition

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

the class SwiftTarget method serializeTojson.

//added by janyou -->
public String serializeTojson(ATN atn) {
    JsonObjectBuilder builder = Json.createObjectBuilder();
    builder.add("version", ATNDeserializer.SERIALIZED_VERSION);
    builder.add("uuid", ATNDeserializer.SERIALIZED_UUID.toString());
    // convert grammar type to ATN const to avoid dependence on ANTLRParser
    builder.add("grammarType", atn.grammarType.ordinal());
    builder.add("maxTokenType", atn.maxTokenType);
    //states
    int nedges = 0;
    Map<IntervalSet, Integer> setIndices = new HashMap<IntervalSet, Integer>();
    List<IntervalSet> sets = new ArrayList<IntervalSet>();
    JsonArrayBuilder statesBuilder = Json.createArrayBuilder();
    IntegerList nonGreedyStates = new IntegerList();
    IntegerList precedenceStates = new IntegerList();
    for (ATNState s : atn.states) {
        JsonObjectBuilder stateBuilder = Json.createObjectBuilder();
        if (s == null) {
            // might be optimized away
            statesBuilder.addNull();
            continue;
        }
        int stateType = s.getStateType();
        stateBuilder.add("stateType", stateType);
        //stateBuilder.add("stateNumber",s.stateNumber);
        stateBuilder.add("ruleIndex", s.ruleIndex);
        if (s instanceof DecisionState && ((DecisionState) s).nonGreedy) {
            nonGreedyStates.add(s.stateNumber);
        }
        if (s instanceof RuleStartState && ((RuleStartState) s).isLeftRecursiveRule) {
            precedenceStates.add(s.stateNumber);
        }
        if (s.getStateType() == ATNState.LOOP_END) {
            stateBuilder.add("detailStateNumber", ((LoopEndState) s).loopBackState.stateNumber);
        } else if (s instanceof BlockStartState) {
            stateBuilder.add("detailStateNumber", ((BlockStartState) s).endState.stateNumber);
        }
        if (s.getStateType() != ATNState.RULE_STOP) {
            // the deserializer can trivially derive these edges, so there's no need to serialize them
            nedges += s.getNumberOfTransitions();
        }
        for (int i = 0; i < s.getNumberOfTransitions(); i++) {
            Transition t = s.transition(i);
            int edgeType = Transition.serializationTypes.get(t.getClass());
            if (edgeType == Transition.SET || edgeType == Transition.NOT_SET) {
                SetTransition st = (SetTransition) t;
                if (!setIndices.containsKey(st.set)) {
                    sets.add(st.set);
                    setIndices.put(st.set, sets.size() - 1);
                }
            }
        }
        statesBuilder.add(stateBuilder);
    }
    builder.add("states", statesBuilder);
    // non-greedy states
    JsonArrayBuilder nonGreedyStatesBuilder = Json.createArrayBuilder();
    for (int i = 0; i < nonGreedyStates.size(); i++) {
        nonGreedyStatesBuilder.add(nonGreedyStates.get(i));
    }
    builder.add("nonGreedyStates", nonGreedyStatesBuilder);
    // precedence states
    JsonArrayBuilder precedenceStatesBuilder = Json.createArrayBuilder();
    for (int i = 0; i < precedenceStates.size(); i++) {
        precedenceStatesBuilder.add(precedenceStates.get(i));
    }
    builder.add("precedenceStates", precedenceStatesBuilder);
    JsonArrayBuilder ruleToStartStateBuilder = Json.createArrayBuilder();
    int nrules = atn.ruleToStartState.length;
    for (int r = 0; r < nrules; r++) {
        JsonObjectBuilder stateBuilder = Json.createObjectBuilder();
        ATNState ruleStartState = atn.ruleToStartState[r];
        stateBuilder.add("stateNumber", ruleStartState.stateNumber);
        if (atn.grammarType == ATNType.LEXER) {
            //				if (atn.ruleToTokenType[r] == Token.EOF) {
            //					//data.add(Character.MAX_VALUE);
            //					stateBuilder.add("ruleToTokenType",-1);
            //				}
            //				else {
            //					//data.add(atn.ruleToTokenType[r]);
            stateBuilder.add("ruleToTokenType", atn.ruleToTokenType[r]);
        //				}
        }
        ruleToStartStateBuilder.add(stateBuilder);
    }
    builder.add("ruleToStartState", ruleToStartStateBuilder);
    JsonArrayBuilder modeToStartStateBuilder = Json.createArrayBuilder();
    int nmodes = atn.modeToStartState.size();
    if (nmodes > 0) {
        for (ATNState modeStartState : atn.modeToStartState) {
            modeToStartStateBuilder.add(modeStartState.stateNumber);
        }
    }
    builder.add("modeToStartState", modeToStartStateBuilder);
    JsonArrayBuilder nsetsBuilder = Json.createArrayBuilder();
    int nsets = sets.size();
    //data.add(nsets);
    builder.add("nsets", nsets);
    for (IntervalSet set : sets) {
        JsonObjectBuilder setBuilder = Json.createObjectBuilder();
        boolean containsEof = set.contains(Token.EOF);
        if (containsEof && set.getIntervals().get(0).b == Token.EOF) {
            //data.add(set.getIntervals().size() - 1);
            setBuilder.add("size", set.getIntervals().size() - 1);
        } else {
            //data.add(set.getIntervals().size());
            setBuilder.add("size", set.getIntervals().size());
        }
        setBuilder.add("containsEof", containsEof ? 1 : 0);
        JsonArrayBuilder IntervalsBuilder = Json.createArrayBuilder();
        for (Interval I : set.getIntervals()) {
            JsonObjectBuilder IntervalBuilder = Json.createObjectBuilder();
            if (I.a == Token.EOF) {
                if (I.b == Token.EOF) {
                    continue;
                } else {
                    IntervalBuilder.add("a", 0);
                //data.add(0);
                }
            } else {
                IntervalBuilder.add("a", I.a);
            //data.add(I.a);
            }
            IntervalBuilder.add("b", I.b);
            IntervalsBuilder.add(IntervalBuilder);
        }
        setBuilder.add("Intervals", IntervalsBuilder);
        nsetsBuilder.add(setBuilder);
    }
    builder.add("IntervalSet", nsetsBuilder);
    //builder.add("nedges",nedges);
    JsonArrayBuilder allTransitionsBuilder = Json.createArrayBuilder();
    for (ATNState s : atn.states) {
        if (s == null) {
            // might be optimized away
            continue;
        }
        if (s.getStateType() == ATNState.RULE_STOP) {
            continue;
        }
        JsonArrayBuilder transitionsBuilder = Json.createArrayBuilder();
        for (int i = 0; i < s.getNumberOfTransitions(); i++) {
            JsonObjectBuilder transitionBuilder = Json.createObjectBuilder();
            Transition t = s.transition(i);
            if (atn.states.get(t.target.stateNumber) == null) {
                throw new IllegalStateException("Cannot serialize a transition to a removed state.");
            }
            int src = s.stateNumber;
            int trg = t.target.stateNumber;
            int edgeType = Transition.serializationTypes.get(t.getClass());
            int arg1 = 0;
            int arg2 = 0;
            int arg3 = 0;
            switch(edgeType) {
                case Transition.RULE:
                    trg = ((RuleTransition) t).followState.stateNumber;
                    arg1 = ((RuleTransition) t).target.stateNumber;
                    arg2 = ((RuleTransition) t).ruleIndex;
                    arg3 = ((RuleTransition) t).precedence;
                    break;
                case Transition.PRECEDENCE:
                    PrecedencePredicateTransition ppt = (PrecedencePredicateTransition) t;
                    arg1 = ppt.precedence;
                    break;
                case Transition.PREDICATE:
                    PredicateTransition pt = (PredicateTransition) t;
                    arg1 = pt.ruleIndex;
                    arg2 = pt.predIndex;
                    arg3 = pt.isCtxDependent ? 1 : 0;
                    break;
                case Transition.RANGE:
                    arg1 = ((RangeTransition) t).from;
                    arg2 = ((RangeTransition) t).to;
                    if (arg1 == Token.EOF) {
                        arg1 = 0;
                        arg3 = 1;
                    }
                    break;
                case Transition.ATOM:
                    arg1 = ((AtomTransition) t).label;
                    if (arg1 == Token.EOF) {
                        arg1 = 0;
                        arg3 = 1;
                    }
                    break;
                case Transition.ACTION:
                    ActionTransition at = (ActionTransition) t;
                    arg1 = at.ruleIndex;
                    arg2 = at.actionIndex;
                    //						if (arg2 == -1) {
                    //							arg2 = 0xFFFF;
                    //						}
                    arg3 = at.isCtxDependent ? 1 : 0;
                    break;
                case Transition.SET:
                    arg1 = setIndices.get(((SetTransition) t).set);
                    break;
                case Transition.NOT_SET:
                    arg1 = setIndices.get(((SetTransition) t).set);
                    break;
                case Transition.WILDCARD:
                    break;
            }
            transitionBuilder.add("src", src);
            transitionBuilder.add("trg", trg);
            transitionBuilder.add("edgeType", edgeType);
            transitionBuilder.add("arg1", arg1);
            transitionBuilder.add("arg2", arg2);
            transitionBuilder.add("arg3", arg3);
            transitionsBuilder.add(transitionBuilder);
        }
        allTransitionsBuilder.add(transitionsBuilder);
    }
    builder.add("allTransitionsBuilder", allTransitionsBuilder);
    int ndecisions = atn.decisionToState.size();
    //data.add(ndecisions);
    JsonArrayBuilder decisionToStateBuilder = Json.createArrayBuilder();
    for (DecisionState decStartState : atn.decisionToState) {
        //data.add(decStartState.stateNumber);
        decisionToStateBuilder.add(decStartState.stateNumber);
    }
    builder.add("decisionToState", decisionToStateBuilder);
    //
    // LEXER ACTIONS
    //
    JsonArrayBuilder lexerActionsBuilder = Json.createArrayBuilder();
    if (atn.grammarType == ATNType.LEXER) {
        //data.add(atn.lexerActions.length);
        for (LexerAction action : atn.lexerActions) {
            JsonObjectBuilder lexerActionBuilder = Json.createObjectBuilder();
            lexerActionBuilder.add("actionType", action.getActionType().ordinal());
            //data.add(action.getActionType().ordinal());
            switch(action.getActionType()) {
                case CHANNEL:
                    int channel = ((LexerChannelAction) action).getChannel();
                    lexerActionBuilder.add("a", channel);
                    lexerActionBuilder.add("b", 0);
                    break;
                case CUSTOM:
                    int ruleIndex = ((LexerCustomAction) action).getRuleIndex();
                    int actionIndex = ((LexerCustomAction) action).getActionIndex();
                    lexerActionBuilder.add("a", ruleIndex);
                    lexerActionBuilder.add("b", actionIndex);
                    break;
                case MODE:
                    int mode = ((LexerModeAction) action).getMode();
                    lexerActionBuilder.add("a", mode);
                    lexerActionBuilder.add("b", 0);
                    break;
                case MORE:
                    lexerActionBuilder.add("a", 0);
                    lexerActionBuilder.add("b", 0);
                    break;
                case POP_MODE:
                    lexerActionBuilder.add("a", 0);
                    lexerActionBuilder.add("b", 0);
                    break;
                case PUSH_MODE:
                    mode = ((LexerPushModeAction) action).getMode();
                    lexerActionBuilder.add("a", mode);
                    lexerActionBuilder.add("b", 0);
                    break;
                case SKIP:
                    lexerActionBuilder.add("a", 0);
                    lexerActionBuilder.add("b", 0);
                    break;
                case TYPE:
                    int type = ((LexerTypeAction) action).getType();
                    lexerActionBuilder.add("a", type);
                    lexerActionBuilder.add("b", 0);
                    break;
                default:
                    String message = String.format(Locale.getDefault(), "The specified lexer action type %s is not valid.", action.getActionType());
                    throw new IllegalArgumentException(message);
            }
            lexerActionsBuilder.add(lexerActionBuilder);
        }
    }
    builder.add("lexerActions", lexerActionsBuilder);
    // don't adjust the first value since that's the version number
    //		for (int i = 1; i < data.size(); i++) {
    //			if (data.get(i) < Character.MIN_VALUE || data.get(i) > Character.MAX_VALUE) {
    //				throw new UnsupportedOperationException("Serialized ATN data element out of range.");
    //			}
    //
    //			int value = (data.get(i) + 2) & 0xFFFF;
    //			data.set(i, value);
    //		}
    JsonObject data = builder.build();
    //  System.out.print(data.toString());
    return data.toString();
}
Also used : HashMap(java.util.HashMap) LexerTypeAction(org.antlr.v4.runtime.atn.LexerTypeAction) ArrayList(java.util.ArrayList) SetTransition(org.antlr.v4.runtime.atn.SetTransition) PrecedencePredicateTransition(org.antlr.v4.runtime.atn.PrecedencePredicateTransition) JsonObject(javax.json.JsonObject) ATNState(org.antlr.v4.runtime.atn.ATNState) IntegerList(org.antlr.v4.runtime.misc.IntegerList) LexerModeAction(org.antlr.v4.runtime.atn.LexerModeAction) JsonArrayBuilder(javax.json.JsonArrayBuilder) JsonObjectBuilder(javax.json.JsonObjectBuilder) LoopEndState(org.antlr.v4.runtime.atn.LoopEndState) LexerChannelAction(org.antlr.v4.runtime.atn.LexerChannelAction) LexerAction(org.antlr.v4.runtime.atn.LexerAction) PrecedencePredicateTransition(org.antlr.v4.runtime.atn.PrecedencePredicateTransition) PredicateTransition(org.antlr.v4.runtime.atn.PredicateTransition) DecisionState(org.antlr.v4.runtime.atn.DecisionState) ActionTransition(org.antlr.v4.runtime.atn.ActionTransition) RuleStartState(org.antlr.v4.runtime.atn.RuleStartState) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) PrecedencePredicateTransition(org.antlr.v4.runtime.atn.PrecedencePredicateTransition) PredicateTransition(org.antlr.v4.runtime.atn.PredicateTransition) 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) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) BlockStartState(org.antlr.v4.runtime.atn.BlockStartState) LexerCustomAction(org.antlr.v4.runtime.atn.LexerCustomAction) Interval(org.antlr.v4.runtime.misc.Interval)

Example 3 with RangeTransition

use of org.antlr.v4.runtime.atn.RangeTransition 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 4 with RangeTransition

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

Aggregations

ATNState (org.antlr.v4.runtime.atn.ATNState)3 AtomTransition (org.antlr.v4.runtime.atn.AtomTransition)3 RangeTransition (org.antlr.v4.runtime.atn.RangeTransition)3 SetTransition (org.antlr.v4.runtime.atn.SetTransition)3 Transition (org.antlr.v4.runtime.atn.Transition)3 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 ActionTransition (org.antlr.v4.runtime.atn.ActionTransition)2 DecisionState (org.antlr.v4.runtime.atn.DecisionState)2 NotSetTransition (org.antlr.v4.runtime.atn.NotSetTransition)2 RuleStartState (org.antlr.v4.runtime.atn.RuleStartState)2 RuleTransition (org.antlr.v4.runtime.atn.RuleTransition)2 IntegerList (org.antlr.v4.runtime.misc.IntegerList)2 Interval (org.antlr.v4.runtime.misc.Interval)2 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 JsonArrayBuilder (javax.json.JsonArrayBuilder)1 JsonObject (javax.json.JsonObject)1