A transition containing a set of values.
Inheritance: Transition
Exemplo n.º 1
0
        private static int OptimizeSets(ATN atn, bool preserveOrder)
        {
            if (preserveOrder)
            {
                // this optimization currently doesn't preserve edge order.
                return(0);
            }
            int removedPaths = 0;
            IList <DecisionState> decisions = atn.decisionToState;

            foreach (DecisionState decision in decisions)
            {
                IntervalSet setTransitions = new IntervalSet();
                for (int i = 0; i < decision.NumberOfOptimizedTransitions; i++)
                {
                    Transition epsTransition = decision.GetOptimizedTransition(i);
                    if (!(epsTransition is EpsilonTransition))
                    {
                        continue;
                    }
                    if (epsTransition.target.NumberOfOptimizedTransitions != 1)
                    {
                        continue;
                    }
                    Transition transition = epsTransition.target.GetOptimizedTransition(0);
                    if (!(transition.target is BlockEndState))
                    {
                        continue;
                    }
                    if (transition is NotSetTransition)
                    {
                        // TODO: not yet implemented
                        continue;
                    }
                    if (transition is AtomTransition || transition is RangeTransition || transition is SetTransition)
                    {
                        setTransitions.Add(i);
                    }
                }
                if (setTransitions.Count <= 1)
                {
                    continue;
                }
                IList <Transition> optimizedTransitions = new List <Transition>();
                for (int i_1 = 0; i_1 < decision.NumberOfOptimizedTransitions; i_1++)
                {
                    if (!setTransitions.Contains(i_1))
                    {
                        optimizedTransitions.Add(decision.GetOptimizedTransition(i_1));
                    }
                }
                ATNState    blockEndState = decision.GetOptimizedTransition(setTransitions.MinElement).target.GetOptimizedTransition(0).target;
                IntervalSet matchSet      = new IntervalSet();
                for (int i_2 = 0; i_2 < setTransitions.GetIntervals().Count; i_2++)
                {
                    Interval interval = setTransitions.GetIntervals()[i_2];
                    for (int j = interval.a; j <= interval.b; j++)
                    {
                        Transition matchTransition = decision.GetOptimizedTransition(j).target.GetOptimizedTransition(0);
                        if (matchTransition is NotSetTransition)
                        {
                            throw new NotSupportedException("Not yet implemented.");
                        }
                        else
                        {
                            matchSet.AddAll(matchTransition.Label);
                        }
                    }
                }
                Transition newTransition;
                if (matchSet.GetIntervals().Count == 1)
                {
                    if (matchSet.Count == 1)
                    {
                        newTransition = new AtomTransition(blockEndState, matchSet.MinElement);
                    }
                    else
                    {
                        Interval matchInterval = matchSet.GetIntervals()[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.NumberOfOptimizedTransitions - optimizedTransitions.Count;
                if (decision.IsOptimized)
                {
                    while (decision.NumberOfOptimizedTransitions > 0)
                    {
                        decision.RemoveOptimizedTransition(decision.NumberOfOptimizedTransitions - 1);
                    }
                }
                foreach (Transition transition_1 in optimizedTransitions)
                {
                    decision.AddOptimizedTransition(transition_1);
                }
            }
            return(removedPaths);
        }
Exemplo n.º 2
0
 private static int OptimizeSets(ATN atn, bool preserveOrder)
 {
     if (preserveOrder)
     {
         // this optimization currently doesn't preserve edge order.
         return 0;
     }
     int removedPaths = 0;
     IList<DecisionState> decisions = atn.decisionToState;
     foreach (DecisionState decision in decisions)
     {
         IntervalSet setTransitions = new IntervalSet();
         for (int i = 0; i < decision.NumberOfOptimizedTransitions; i++)
         {
             Transition epsTransition = decision.GetOptimizedTransition(i);
             if (!(epsTransition is EpsilonTransition))
             {
                 continue;
             }
             if (epsTransition.target.NumberOfOptimizedTransitions != 1)
             {
                 continue;
             }
             Transition transition = epsTransition.target.GetOptimizedTransition(0);
             if (!(transition.target is BlockEndState))
             {
                 continue;
             }
             if (transition is NotSetTransition)
             {
                 // TODO: not yet implemented
                 continue;
             }
             if (transition is AtomTransition || transition is RangeTransition || transition is SetTransition)
             {
                 setTransitions.Add(i);
             }
         }
         if (setTransitions.Count <= 1)
         {
             continue;
         }
         IList<Transition> optimizedTransitions = new List<Transition>();
         for (int i_1 = 0; i_1 < decision.NumberOfOptimizedTransitions; i_1++)
         {
             if (!setTransitions.Contains(i_1))
             {
                 optimizedTransitions.Add(decision.GetOptimizedTransition(i_1));
             }
         }
         ATNState blockEndState = decision.GetOptimizedTransition(setTransitions.MinElement).target.GetOptimizedTransition(0).target;
         IntervalSet matchSet = new IntervalSet();
         for (int i_2 = 0; i_2 < setTransitions.GetIntervals().Count; i_2++)
         {
             Interval interval = setTransitions.GetIntervals()[i_2];
             for (int j = interval.a; j <= interval.b; j++)
             {
                 Transition matchTransition = decision.GetOptimizedTransition(j).target.GetOptimizedTransition(0);
                 if (matchTransition is NotSetTransition)
                 {
                     throw new NotSupportedException("Not yet implemented.");
                 }
                 else
                 {
                     matchSet.AddAll(matchTransition.Label);
                 }
             }
         }
         Transition newTransition;
         if (matchSet.GetIntervals().Count == 1)
         {
             if (matchSet.Count == 1)
             {
                 newTransition = new AtomTransition(blockEndState, matchSet.MinElement);
             }
             else
             {
                 Interval matchInterval = matchSet.GetIntervals()[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.NumberOfOptimizedTransitions - optimizedTransitions.Count;
         if (decision.IsOptimized)
         {
             while (decision.NumberOfOptimizedTransitions > 0)
             {
                 decision.RemoveOptimizedTransition(decision.NumberOfOptimizedTransitions - 1);
             }
         }
         foreach (Transition transition_1 in optimizedTransitions)
         {
             decision.AddOptimizedTransition(transition_1);
         }
     }
     return removedPaths;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Serialize state descriptors, edge descriptors, and decision&rarr;state map
        /// into list of ints:
        /// grammar-type, (ANTLRParser.LEXER, ...)
        /// max token type,
        /// num states,
        /// state-0-type ruleIndex, state-1-type ruleIndex, ...
        /// </summary>
        /// <remarks>
        /// Serialize state descriptors, edge descriptors, and decision&rarr;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 sets
        /// set-0-interval-count intervals, 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.
        /// </remarks>
        public virtual List <int> Serialize()
        {
            List <int> data = new List <int>();

            data.Add(ATNDeserializer.SerializedVersion);
            SerializeUUID(data, ATNDeserializer.SerializedUuid);
            // convert grammar type to ATN const to avoid dependence on ANTLRParser
            data.Add((int)(atn.grammarType));
            data.Add(atn.maxTokenType);
            int nedges = 0;
            IDictionary <IntervalSet, int> setIndices = new Dictionary <IntervalSet, int>();
            IList <IntervalSet>            sets       = new List <IntervalSet>();
            // dump states, count edges and collect sets while doing so
            List <int> nonGreedyStates  = new List <int>();
            List <int> sllStates        = new List <int>();
            List <int> precedenceStates = new List <int>();

            data.Add(atn.states.Count);
            foreach (ATNState s in atn.states)
            {
                if (s == null)
                {
                    // might be optimized away
                    data.Add((int)(StateType.InvalidType));
                    continue;
                }
                StateType stateType = s.StateType;
                if (s is DecisionState)
                {
                    DecisionState decisionState = (DecisionState)s;
                    if (decisionState.nonGreedy)
                    {
                        nonGreedyStates.Add(s.stateNumber);
                    }
                    if (decisionState.sll)
                    {
                        sllStates.Add(s.stateNumber);
                    }
                }
                if (s is RuleStartState && ((RuleStartState)s).isPrecedenceRule)
                {
                    precedenceStates.Add(s.stateNumber);
                }
                data.Add((int)(stateType));
                if (s.ruleIndex == -1)
                {
                    data.Add(char.MaxValue);
                }
                else
                {
                    data.Add(s.ruleIndex);
                }
                if (s.StateType == StateType.LoopEnd)
                {
                    data.Add(((LoopEndState)s).loopBackState.stateNumber);
                }
                else
                {
                    if (s is BlockStartState)
                    {
                        data.Add(((BlockStartState)s).endState.stateNumber);
                    }
                }
                if (s.StateType != StateType.RuleStop)
                {
                    // the deserializer can trivially derive these edges, so there's no need to serialize them
                    nedges += s.NumberOfTransitions;
                }
                for (int i = 0; i < s.NumberOfTransitions; i++)
                {
                    Transition     t        = s.Transition(i);
                    TransitionType edgeType = Transition.serializationTypes.Get(t.GetType());
                    if (edgeType == TransitionType.Set || edgeType == TransitionType.NotSet)
                    {
                        SetTransition st = (SetTransition)t;
                        if (!setIndices.ContainsKey(st.set))
                        {
                            sets.AddItem(st.set);
                            setIndices.Put(st.set, sets.Count - 1);
                        }
                    }
                }
            }
            // non-greedy states
            data.Add(nonGreedyStates.Size());
            for (int i_1 = 0; i_1 < nonGreedyStates.Size(); i_1++)
            {
                data.Add(nonGreedyStates.Get(i_1));
            }
            // SLL decisions
            data.Add(sllStates.Size());
            for (int i_2 = 0; i_2 < sllStates.Size(); i_2++)
            {
                data.Add(sllStates.Get(i_2));
            }
            // precedence states
            data.Add(precedenceStates.Size());
            for (int i_3 = 0; i_3 < precedenceStates.Size(); i_3++)
            {
                data.Add(precedenceStates.Get(i_3));
            }
            int nrules = atn.ruleToStartState.Length;

            data.Add(nrules);
            for (int r = 0; r < nrules; r++)
            {
                ATNState ruleStartState = atn.ruleToStartState[r];
                data.Add(ruleStartState.stateNumber);
                bool leftFactored = ruleNames[ruleStartState.ruleIndex].IndexOf(ATNSimulator.RuleVariantDelimiter) >= 0;
                data.Add(leftFactored ? 1 : 0);
                if (atn.grammarType == ATNType.Lexer)
                {
                    if (atn.ruleToTokenType[r] == TokenConstants.Eof)
                    {
                        data.Add(char.MaxValue);
                    }
                    else
                    {
                        data.Add(atn.ruleToTokenType[r]);
                    }
                }
            }
            int nmodes = atn.modeToStartState.Count;

            data.Add(nmodes);
            if (nmodes > 0)
            {
                foreach (ATNState modeStartState in atn.modeToStartState)
                {
                    data.Add(modeStartState.stateNumber);
                }
            }
            int nsets = sets.Count;

            data.Add(nsets);
            foreach (IntervalSet set in sets)
            {
                bool containsEof = set.Contains(TokenConstants.Eof);
                if (containsEof && set.GetIntervals()[0].b == TokenConstants.Eof)
                {
                    data.Add(set.GetIntervals().Count - 1);
                }
                else
                {
                    data.Add(set.GetIntervals().Count);
                }
                data.Add(containsEof ? 1 : 0);
                foreach (Interval I in set.GetIntervals())
                {
                    if (I.a == TokenConstants.Eof)
                    {
                        if (I.b == TokenConstants.Eof)
                        {
                            continue;
                        }
                        else
                        {
                            data.Add(0);
                        }
                    }
                    else
                    {
                        data.Add(I.a);
                    }
                    data.Add(I.b);
                }
            }
            data.Add(nedges);
            foreach (ATNState s_1 in atn.states)
            {
                if (s_1 == null)
                {
                    // might be optimized away
                    continue;
                }
                if (s_1.StateType == StateType.RuleStop)
                {
                    continue;
                }
                for (int i = 0; i_3 < s_1.NumberOfTransitions; i_3++)
                {
                    Transition t = s_1.Transition(i_3);
                    if (atn.states[t.target.stateNumber] == null)
                    {
                        throw new InvalidOperationException("Cannot serialize a transition to a removed state.");
                    }
                    int            src      = s_1.stateNumber;
                    int            trg      = t.target.stateNumber;
                    TransitionType edgeType = Transition.serializationTypes.Get(t.GetType());
                    int            arg1     = 0;
                    int            arg2     = 0;
                    int            arg3     = 0;
                    switch (edgeType)
                    {
                    case TransitionType.Rule:
                    {
                        trg  = ((RuleTransition)t).followState.stateNumber;
                        arg1 = ((RuleTransition)t).target.stateNumber;
                        arg2 = ((RuleTransition)t).ruleIndex;
                        arg3 = ((RuleTransition)t).precedence;
                        break;
                    }

                    case TransitionType.Precedence:
                    {
                        PrecedencePredicateTransition ppt = (PrecedencePredicateTransition)t;
                        arg1 = ppt.precedence;
                        break;
                    }

                    case TransitionType.Predicate:
                    {
                        PredicateTransition pt = (PredicateTransition)t;
                        arg1 = pt.ruleIndex;
                        arg2 = pt.predIndex;
                        arg3 = pt.isCtxDependent ? 1 : 0;
                        break;
                    }

                    case TransitionType.Range:
                    {
                        arg1 = ((RangeTransition)t).from;
                        arg2 = ((RangeTransition)t).to;
                        if (arg1 == TokenConstants.Eof)
                        {
                            arg1 = 0;
                            arg3 = 1;
                        }
                        break;
                    }

                    case TransitionType.Atom:
                    {
                        arg1 = ((AtomTransition)t).label;
                        if (arg1 == TokenConstants.Eof)
                        {
                            arg1 = 0;
                            arg3 = 1;
                        }
                        break;
                    }

                    case TransitionType.Action:
                    {
                        ActionTransition at = (ActionTransition)t;
                        arg1 = at.ruleIndex;
                        arg2 = at.actionIndex;
                        if (arg2 == -1)
                        {
                            arg2 = unchecked ((int)(0xFFFF));
                        }
                        arg3 = at.isCtxDependent ? 1 : 0;
                        break;
                    }

                    case TransitionType.Set:
                    {
                        arg1 = setIndices.Get(((SetTransition)t).set);
                        break;
                    }

                    case TransitionType.NotSet:
                    {
                        arg1 = setIndices.Get(((SetTransition)t).set);
                        break;
                    }

                    case TransitionType.Wildcard:
                    {
                        break;
                    }
                    }
                    data.Add(src);
                    data.Add(trg);
                    data.Add((int)(edgeType));
                    data.Add(arg1);
                    data.Add(arg2);
                    data.Add(arg3);
                }
            }
            int ndecisions = atn.decisionToState.Count;

            data.Add(ndecisions);
            foreach (DecisionState decStartState in atn.decisionToState)
            {
                data.Add(decStartState.stateNumber);
            }
            //
            // LEXER ACTIONS
            //
            if (atn.grammarType == ATNType.Lexer)
            {
                data.Add(atn.lexerActions.Length);
                foreach (ILexerAction action in atn.lexerActions)
                {
                    data.Add((int)(action.GetActionType()));
                    switch (action.GetActionType())
                    {
                    case LexerActionType.Channel:
                    {
                        int channel = ((LexerChannelAction)action).GetChannel();
                        data.Add(channel != -1 ? channel : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.Custom:
                    {
                        int ruleIndex   = ((LexerCustomAction)action).GetRuleIndex();
                        int actionIndex = ((LexerCustomAction)action).GetActionIndex();
                        data.Add(ruleIndex != -1 ? ruleIndex : unchecked ((int)(0xFFFF)));
                        data.Add(actionIndex != -1 ? actionIndex : unchecked ((int)(0xFFFF)));
                        break;
                    }

                    case LexerActionType.Mode:
                    {
                        int mode = ((LexerModeAction)action).GetMode();
                        data.Add(mode != -1 ? mode : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.More:
                    {
                        data.Add(0);
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.PopMode:
                    {
                        data.Add(0);
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.PushMode:
                    {
                        mode = ((LexerPushModeAction)action).GetMode();
                        data.Add(mode != -1 ? mode : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.Skip:
                    {
                        data.Add(0);
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.Type:
                    {
                        int type = ((LexerTypeAction)action).GetType();
                        data.Add(type != -1 ? type : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    default:
                    {
                        string message = string.Format(CultureInfo.CurrentCulture, "The specified lexer action type {0} is not valid.", action.GetActionType());
                        throw new ArgumentException(message);
                    }
                    }
                }
            }
            // don't adjust the first value since that's the version number
            for (int i_4 = 1; i_4 < data.Size(); i_4++)
            {
                if (data.Get(i_4) < char.MinValue || data.Get(i_4) > char.MaxValue)
                {
                    throw new NotSupportedException("Serialized ATN data element out of range.");
                }
                int value = (data.Get(i_4) + 2) & unchecked ((int)(0xFFFF));
                data.Set(i_4, value);
            }
            return(data);
        }
Exemplo n.º 4
0
        public override Handle Set(GrammarAST associatedAST, IList<GrammarAST> alts, bool invert)
        {
            ATNState left = NewState(associatedAST);
            ATNState right = NewState(associatedAST);
            IntervalSet set = new IntervalSet();
            foreach (GrammarAST t in alts)
            {
                if (t.Type == ANTLRParser.RANGE)
                {
                    int a = CharSupport.GetCharValueFromGrammarCharLiteral(t.GetChild(0).Text);
                    int b = CharSupport.GetCharValueFromGrammarCharLiteral(t.GetChild(1).Text);
                    if (CheckRange((GrammarAST)t.GetChild(0), (GrammarAST)t.GetChild(1), a, b))
                    {
                        CheckSetCollision(associatedAST, set, a, b);
                        set.Add(a, b);
                    }
                }
                else if (t.Type == ANTLRParser.LEXER_CHAR_SET)
                {
                    set.AddAll(GetSetFromCharSetLiteral(t));
                }
                else if (t.Type == ANTLRParser.STRING_LITERAL)
                {
                    int c = CharSupport.GetCharValueFromGrammarCharLiteral(t.Text);
                    if (c != -1)
                    {
                        CheckSetCollision(associatedAST, set, c);
                        set.Add(c);
                    }
                    else
                    {
                        g.tool.errMgr.GrammarError(ErrorType.INVALID_LITERAL_IN_LEXER_SET,
                                                   g.fileName, t.Token, t.Text);
                    }
                }
                else if (t.Type == ANTLRParser.TOKEN_REF)
                {
                    g.tool.errMgr.GrammarError(ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET,
                                               g.fileName, t.Token, t.Text);
                }
            }
            if (invert)
            {
                left.AddTransition(new NotSetTransition(right, set));
            }
            else
            {
                Transition transition;
                if (set.GetIntervals().Count == 1)
                {
                    Interval interval = set.GetIntervals()[0];
                    transition = new RangeTransition(right, interval.a, interval.b);
                }
                else
                {
                    transition = new SetTransition(right, set);
                }

                left.AddTransition(transition);
            }
            associatedAST.atnState = left;
            return new Handle(left, right);
        }
Exemplo n.º 5
0
        private static void OptimizeSets(Grammar g, ATN atn)
        {
            if (g.IsParser())
            {
                // parser codegen doesn't currently support SetTransition
                return;
            }

            int removedStates = 0;
            IList<DecisionState> decisions = atn.decisionToState;
            foreach (DecisionState decision in decisions)
            {
                if (decision.ruleIndex >= 0)
                {
                    Rule rule = g.GetRule(decision.ruleIndex);
                    if (char.IsLower(rule.name[0]))
                    {
                        // parser codegen doesn't currently support SetTransition
                        continue;
                    }
                }

                IntervalSet setTransitions = new IntervalSet();
                for (int i = 0; i < decision.NumberOfTransitions; i++)
                {
                    Transition epsTransition = decision.Transition(i);
                    if (!(epsTransition is EpsilonTransition))
                    {
                        continue;
                    }

                    if (epsTransition.target.NumberOfTransitions != 1)
                    {
                        continue;
                    }

                    Transition transition = epsTransition.target.Transition(0);
                    if (!(transition.target is BlockEndState))
                    {
                        continue;
                    }

                    if (transition is NotSetTransition)
                    {
                        // TODO: not yet implemented
                        continue;
                    }

                    if (transition is AtomTransition
                        || transition is RangeTransition
                        || transition is SetTransition)
                    {
                        setTransitions.Add(i);
                    }
                }

                // due to min alt resolution policies, can only collapse sequential alts
                for (int i = setTransitions.GetIntervals().Count - 1; i >= 0; i--)
                {
                    Interval interval = setTransitions.GetIntervals()[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 is NotSetTransition)
                        {
                            throw new NotImplementedException();
                        }

                        IntervalSet set = matchTransition.Label;
                        int minElem = set.MinElement;
                        int maxElem = set.MaxElement;
                        for (int k = minElem; k <= maxElem; k++)
                        {
                            if (matchSet.Contains(k))
                            {
                                char setMin = (char)set.MinElement;
                                char setMax = (char)set.MaxElement;
                                // 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, (char)minElem + "-" + (char)maxElem, "[" + setMin + "-" + setMax + "]");
                                break;
                            }
                        }

                        matchSet.AddAll(set);
                    }

                    Transition newTransition;
                    if (matchSet.GetIntervals().Count == 1)
                    {
                        if (matchSet.Count == 1)
                        {
                            newTransition = new AtomTransition(blockEndState, matchSet.MinElement);
                        }
                        else
                        {
                            Interval matchInterval = matchSet.GetIntervals()[0];
                            newTransition = new RangeTransition(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.Transition(interval.a + 1);
                        decision.RemoveTransition(interval.a + 1);
                        atn.RemoveState(removed.target);
                        removedStates++;
                    }
                }
            }

            //System.Console.WriteLine("ATN optimizer removed " + removedStates + " states by collapsing sets.");
        }