An ATN transition between any two ATN states.
An ATN transition between any two ATN states. Subclasses define atom, set, epsilon, action, predicate, rule transitions.

This is a one way link. It emanates from a state (usually via a list of transitions) and has a target state.

Since we never have to change the ATN transitions once we construct it, we can fix these transitions as specific classes. The DFA transitions on the other hand need to update the labels as it adds transitions to the states. We'll use the term Edge for the DFA to distinguish them from ATN transitions.

Exemple #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);
        }
Exemple #2
0
 public virtual void AddTransition(Antlr4.Runtime.Atn.Transition e)
 {
     AddTransition(transitions.Count, e);
 }
Exemple #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.Add(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.ActionType));
                    switch (action.ActionType)
                    {
                    case LexerActionType.Channel:
                    {
                        int channel = ((LexerChannelAction)action).Channel;
                        data.Add(channel != -1 ? channel : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

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

                    case LexerActionType.Mode:
                    {
                        int mode = ((LexerModeAction)action).Mode;
                        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).Mode;
                        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).Type;
                        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.ActionType);
                        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);
        }
Exemple #4
0
        private static int CombineChainedEpsilons(ATN atn)
        {
            int removedEdges = 0;

            foreach (ATNState state in atn.states)
            {
                if (!state.OnlyHasEpsilonTransitions || state is RuleStopState)
                {
                    continue;
                }
                IList <Transition> optimizedTransitions = null;
                for (int i = 0; i < state.NumberOfOptimizedTransitions; i++)
                {
                    Transition transition   = state.GetOptimizedTransition(i);
                    ATNState   intermediate = transition.target;
                    if (transition.TransitionType != TransitionType.EPSILON || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
                    {
                        if (optimizedTransitions != null)
                        {
                            optimizedTransitions.Add(transition);
                        }
                        goto nextTransition_continue;
                    }
                    for (int j = 0; j < intermediate.NumberOfOptimizedTransitions; j++)
                    {
                        if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.EPSILON || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
                        {
                            if (optimizedTransitions != null)
                            {
                                optimizedTransitions.Add(transition);
                            }
                            goto nextTransition_continue;
                        }
                    }
                    removedEdges++;
                    if (optimizedTransitions == null)
                    {
                        optimizedTransitions = new List <Transition>();
                        for (int j_1 = 0; j_1 < i; j_1++)
                        {
                            optimizedTransitions.Add(state.GetOptimizedTransition(j_1));
                        }
                    }
                    for (int j_2 = 0; j_2 < intermediate.NumberOfOptimizedTransitions; j_2++)
                    {
                        ATNState target = intermediate.GetOptimizedTransition(j_2).target;
                        optimizedTransitions.Add(new EpsilonTransition(target));
                    }
                    nextTransition_continue :;
                }

                if (optimizedTransitions != null)
                {
                    if (state.IsOptimized)
                    {
                        while (state.NumberOfOptimizedTransitions > 0)
                        {
                            state.RemoveOptimizedTransition(state.NumberOfOptimizedTransitions - 1);
                        }
                    }
                    foreach (Transition transition in optimizedTransitions)
                    {
                        state.AddOptimizedTransition(transition);
                    }
                }
            }

            return(removedEdges);
        }
Exemple #5
0
        protected ATNState GetReachableTarget(Transition trans, int ttype)
        {
            if (trans.Matches(ttype, 0, atn.maxTokenType))
            {
                return trans.target;
            }

            return null;
        }
        protected override ATNState GetReachableTarget(ATNConfig source, Transition trans, int ttype)
        {
            if (ttype == AntlrV4.CaretToken.CaretTokenType)
            {
                ATNState target = null;
                AtomTransition atomTransition = trans as AtomTransition;
                if (atomTransition != null)
                {
                    if (GetWordlikeTokenTypes().Contains(atomTransition.label))
                        target = atomTransition.target;
                }
                else
                {
                    SetTransition setTransition = trans as SetTransition;
                    if (setTransition != null)
                    {
                        bool not = trans is NotSetTransition;
                        foreach (int t in GetWordlikeTokenTypes().ToArray())
                        {
                            if (!not && setTransition.set.Contains(t) || not && !setTransition.set.Contains(t))
                            {
                                target = setTransition.target;
                                break;
                            }
                        }
                    }
                    else
                    {
                        RangeTransition rangeTransition = trans as RangeTransition;
                        if (rangeTransition != null)
                        {
                            // TODO: there must be a better algorithm here
                            int[] wordlikeTokenTypes = GetWordlikeTokenTypes().ToArray();
                            int lowerBound = Array.BinarySearch(wordlikeTokenTypes, rangeTransition.from);
                            int upperBound = Array.BinarySearch(wordlikeTokenTypes, rangeTransition.to);
                            if (lowerBound >= 0 || upperBound >= 0 || lowerBound != upperBound)
                                target = rangeTransition.target;
                        }
                        else
                        {
                            WildcardTransition wildcardTransition = trans as WildcardTransition;
                            if (wildcardTransition != null)
                            {
                                target = trans.target;
                            }
                        }
                    }
                }

                if (_caretTransitions == null)
                    _caretTransitions = new Dictionary<ATNConfig, IList<Transition>>();

                IList<Transition> configTransitions;
                if (!_caretTransitions.TryGetValue(source, out configTransitions))
                {
                    configTransitions = new List<Transition>();
                    _caretTransitions[source] = configTransitions;
                }

                configTransitions.Add(trans);
                return target;
            }

            return base.GetReachableTarget(source, trans, ttype);
        }
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition t, ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;
            switch (t.TransitionType)
            {
                case TransitionType.Rule:
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                        c = config.Transform(t.target, newContext, true);
                    }
                    break;
                }

                case TransitionType.Precedence:
                {
                    throw new NotSupportedException("Precedence predicates are not supported in lexers.");
                }

                case TransitionType.Predicate:
                {
                    PredicateTransition pt = (PredicateTransition)t;
                    configs.MarkExplicitSemanticContext();
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        c = null;
                    }
                    break;
                }

                case TransitionType.Action:
                {
                    if (config.Context.HasEmpty)
                    {
                        // execute actions anywhere in the start rule for a token.
                        //
                        // TODO: if the entry rule is invoked recursively, some
                        // actions may be executed during the recursive call. The
                        // problem can appear when hasEmpty() is true but
                        // isEmpty() is false. In this case, the config needs to be
                        // split into two contexts - one with just the empty path
                        // and another with everything but the empty path.
                        // Unfortunately, the current algorithm does not allow
                        // getEpsilonTarget to return two configurations, so
                        // additional modifications are needed before we can support
                        // the split operation.
                        LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                        c = config.Transform(t.target, lexerActionExecutor, true);
                        break;
                    }
                    else
                    {
                        // ignore actions in referenced rules
                        c = config.Transform(t.target, true);
                        break;
                    }
                }

                case TransitionType.Epsilon:
                {
                    c = config.Transform(t.target, true);
                    break;
                }

                case TransitionType.Atom:
                case TransitionType.Range:
                case TransitionType.Set:
                {
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                        {
                            c = config.Transform(t.target, false);
                            break;
                        }
                    }
                    c = null;
                    break;
                }

                default:
                {
                    c = null;
                    break;
                }
            }
            return c;
        }
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig
             config, Transition t, ATNConfigSet configs, bool speculative)
        {
            ATNConfig c;
            switch (t.TransitionType)
            {
                case TransitionType.Rule:
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                    {
                        c = config.Transform(t.target);
                    }
                    else
                    {
                        PredictionContext newContext = config.Context.GetChild(ruleTransition.followState
                            .stateNumber);
                        c = config.Transform(t.target, newContext);
                    }
                    break;
                }

                case TransitionType.Precedence:
                {
                    throw new NotSupportedException("Precedence predicates are not supported in lexers."
                        );
                }

                case TransitionType.Predicate:
                {
                    PredicateTransition pt = (PredicateTransition)t;
                    configs.MarkExplicitSemanticContext();
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = config.Transform(t.target);
                    }
                    else
                    {
                        c = null;
                    }
                    break;
                }

                case TransitionType.Action:
                {
                    // ignore actions; just exec one per rule upon accept
                    c = config.Transform(t.target, ((ActionTransition)t).actionIndex);
                    break;
                }

                case TransitionType.Epsilon:
                {
                    c = config.Transform(t.target);
                    break;
                }

                default:
                {
                    c = null;
                    break;
                }
            }
            return c;
        }
Exemple #9
0
        // side-effect: can alter configs.hasSemanticContext

        protected LexerATNConfig GetEpsilonTarget(ICharStream input,
                                                  LexerATNConfig config,
                                                  Transition t,
                                                  ATNConfigSet configs,
                                                  bool speculative,
                                                  bool treatEofAsEpsilon)
        {
            LexerATNConfig c = null;

            switch (t.TransitionType)
            {
            case TransitionType.RULE:
                RuleTransition    ruleTransition = (RuleTransition)t;
                PredictionContext newContext     = new SingletonPredictionContext(config.context, ruleTransition.followState.stateNumber);
                c = new LexerATNConfig(config, t.target, newContext);
                break;

            case TransitionType.PRECEDENCE:
                throw new Exception("Precedence predicates are not supported in lexers.");

            case TransitionType.PREDICATE:
                /*  Track traversing semantic predicates. If we traverse,
                 * we cannot add a DFA state for this "reach" computation
                 * because the DFA would not test the predicate again in the
                 * future. Rather than creating collections of semantic predicates
                 * like v3 and testing them on prediction, v4 will test them on the
                 * fly all the time using the ATN not the DFA. This is slower but
                 * semantically it's not used that often. One of the key elements to
                 * this predicate mechanism is not adding DFA states that see
                 * predicates immediately afterwards in the ATN. For example,
                 *
                 * a : ID {p1}? | ID {p2}? ;
                 *
                 * should create the start state for rule 'a' (to save start state
                 * competition), but should not create target of ID state. The
                 * collection of ATN states the following ID references includes
                 * states reached by traversing predicates. Since this is when we
                 * test them, we cannot cash the DFA state target of ID.
                 */
                PredicateTransition pt = (PredicateTransition)t;
                if (debug)
                {
                    Console.WriteLine("EVAL rule " + pt.ruleIndex + ":" + pt.predIndex);
                }
                configs.hasSemanticContext = true;
                if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                {
                    c = new LexerATNConfig(config, t.target);
                }
                break;

            case TransitionType.ACTION:
                if (config.context == null || config.context.HasEmptyPath)
                {
                    // execute actions anywhere in the start rule for a token.
                    //
                    // TODO: if the entry rule is invoked recursively, some
                    // actions may be executed during the recursive call. The
                    // problem can appear when hasEmptyPath() is true but
                    // isEmpty() is false. In this case, the config needs to be
                    // split into two contexts - one with just the empty path
                    // and another with everything but the empty path.
                    // Unfortunately, the current algorithm does not allow
                    // getEpsilonTarget to return two configurations, so
                    // additional modifications are needed before we can support
                    // the split operation.
                    LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.getLexerActionExecutor(), atn.lexerActions[((ActionTransition)t).actionIndex]);
                    c = new LexerATNConfig(config, t.target, lexerActionExecutor);
                    break;
                }
                else
                {
                    // ignore actions in referenced rules
                    c = new LexerATNConfig(config, t.target);
                    break;
                }

            case TransitionType.EPSILON:
                c = new LexerATNConfig(config, t.target);
                break;

            case TransitionType.ATOM:
            case TransitionType.RANGE:
            case TransitionType.SET:
                if (treatEofAsEpsilon)
                {
                    if (t.Matches(IntStreamConstants.EOF, Lexer.MinCharValue, Lexer.MaxCharValue))
                    {
                        c = new LexerATNConfig(config, t.target);
                        break;
                    }
                }

                break;
            }

            return(c);
        }
Exemple #10
0
 /**
  * Compute set of tokens that can follow {@code s} in the ATN in the
  * specified {@code ctx}.
  *
  * <p>If {@code ctx} is {@code null} and {@code stopState} or the end of the
  * rule containing {@code s} is reached, {@link Token#EPSILON} is added to
  * the result set. If {@code ctx} is not {@code null} and {@code addEOF} is
  * {@code true} and {@code stopState} or the end of the outermost rule is
  * reached, {@link Token#EOF} is added to the result set.</p>
  *
  * @param s the ATN state.
  * @param stopState the ATN state to stop at. This can be a
  * {@link BlockEndState} to detect epsilon paths through a closure.
  * @param ctx The outer context, or {@code null} if the outer context should
  * not be used.
  * @param look The result lookahead set.
  * @param lookBusy A set used for preventing epsilon closures in the ATN
  * from causing a stack overflow. Outside code should pass
  * {@code new HashSet<ATNConfig>} for this argument.
  * @param calledRuleStack A set used for preventing left recursion in the
  * ATN from causing a stack overflow. Outside code should pass
  * {@code new BitSet()} for this argument.
  * @param seeThruPreds {@code true} to true semantic predicates as
  * implicitly {@code true} and "see through them", otherwise {@code false}
  * to treat semantic predicates as opaque and add {@link #HIT_PRED} to the
  * result if one is encountered.
  * @param addEOF Add {@link Token#EOF} to the result if the end of the
  * outermost context is reached. This parameter has no effect if {@code ctx}
  * is {@code null}.
  */
 protected internal virtual void Look_(ATNState s, ATNState stopState, PredictionContext ctx, IntervalSet look, HashSet<ATNConfig> lookBusy, BitSet calledRuleStack, bool seeThruPreds, bool addEOF)
 {
     ATNConfig c = new ATNConfig(s, 0, ctx);
     if (!lookBusy.Add(c))
     {
         return;
     }
     if (s == stopState)
     {
         if (ctx == null)
         {
             look.Add(TokenConstants.EPSILON);
             return;
         }
         else if (ctx.IsEmpty && addEOF)
         {
             look.Add(TokenConstants.EOF);
             return;
         }
     }
     if (s is RuleStopState)
     {
         if (ctx == null)
         {
             look.Add(TokenConstants.EPSILON);
             return;
         }
         else if (ctx.IsEmpty && addEOF)
         {
             look.Add(TokenConstants.EOF);
             return;
         }
         if (ctx != PredictionContext.EMPTY)
         {
             bool removed = calledRuleStack.Get(s.ruleIndex);
             try
             {
                 calledRuleStack.Clear(s.ruleIndex);
                 for (int i = 0; i < ctx.Size; i++)
                 {
                     ATNState returnState = atn.states[ctx.GetReturnState(i)];
                     Look_(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                 }
             }
             finally
             {
                 if (removed)
                 {
                     calledRuleStack.Set(s.ruleIndex);
                 }
             }
             return;
         }
     }
     int n = s.NumberOfTransitions;
     for (int i_1 = 0; i_1 < n; i_1++)
     {
         Transition t = s.Transition(i_1);
         if (t.GetType() == typeof(RuleTransition))
         {
             RuleTransition ruleTransition = (RuleTransition)t;
             if (calledRuleStack.Get(ruleTransition.ruleIndex))
             {
                 continue;
             }
             PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber);
             try
             {
                 calledRuleStack.Set(ruleTransition.target.ruleIndex);
                 Look_(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
             }
             finally
             {
                 calledRuleStack.Clear(ruleTransition.target.ruleIndex);
             }
         }
         else if (t is AbstractPredicateTransition)
         {
             if (seeThruPreds)
             {
                 Look_(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
             }
             else
             {
                 look.Add(HitPred);
             }
         }
         else if (t.IsEpsilon)
         {
             Look_(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
         }
         else if (t.GetType() == typeof(WildcardTransition))
         {
             look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
         }
         else
         {
             IntervalSet set = t.Label;
             if (set != null)
             {
                 if (t is NotSetTransition)
                 {
                     set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                 }
                 look.AddAll(set);
             }
         }
     }
 }
Exemple #11
0
        /**
         * Since the alternatives within any lexer decision are ordered by
         * preference, this method stops pursuing the closure as soon as an accept
         * state is reached. After the first accept state is reached by depth-first
         * search from {@code config}, all other (potentially reachable) states for
         * this rule would have a lower priority.
         *
         * @return {@code true} if an accept state is reached, otherwise
         * {@code false}.
         */
        protected bool Closure(ICharStream input, LexerATNConfig config, ATNConfigSet configs, bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon)
        {
            if (debug)
            {
                Console.WriteLine("closure(" + config.ToString(recog, true) + ")");
            }

            if (config.state is RuleStopState)
            {
                if (debug)
                {
                    if (recog != null)
                    {
                        Console.WriteLine("closure at " + recog.RuleNames[config.state.ruleIndex] + " rule stop " + config);
                    }
                    else
                    {
                        Console.WriteLine("closure at rule stop " + config);
                    }
                }

                if (config.context == null || config.context.HasEmptyPath)
                {
                    if (config.context == null || config.context.IsEmpty)
                    {
                        configs.Add(config);
                        return(true);
                    }
                    else
                    {
                        configs.Add(new LexerATNConfig(config, config.state, PredictionContext.EMPTY));
                        currentAltReachedAcceptState = true;
                    }
                }

                if (config.context != null && !config.context.IsEmpty)
                {
                    for (int i = 0; i < config.context.Size; i++)
                    {
                        if (config.context.GetReturnState(i) != PredictionContext.EMPTY_RETURN_STATE)
                        {
                            PredictionContext newContext  = config.context.GetParent(i);                            // "pop" return state
                            ATNState          returnState = atn.states[config.context.GetReturnState(i)];
                            LexerATNConfig    c           = new LexerATNConfig(config, returnState, newContext);
                            currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
                        }
                    }
                }

                return(currentAltReachedAcceptState);
            }

            // optimization
            if (!config.state.OnlyHasEpsilonTransitions)
            {
                if (!currentAltReachedAcceptState || !config.hasPassedThroughNonGreedyDecision())
                {
                    configs.Add(config);
                }
            }

            ATNState p = config.state;

            for (int i = 0; i < p.NumberOfTransitions; i++)
            {
                Transition     t = p.Transition(i);
                LexerATNConfig c = GetEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon);
                if (c != null)
                {
                    currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
                }
            }

            return(currentAltReachedAcceptState);
        }
Exemple #12
0
 public virtual void SetTransition(int i, Antlr4.Runtime.Atn.Transition e)
 {
     transitions[i] = e;
 }
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition t, ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;

            switch (t.TransitionType)
            {
            case TransitionType.Rule:
            {
                RuleTransition ruleTransition = (RuleTransition)t;
                if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                {
                    c = config.Transform(t.target, true);
                }
                else
                {
                    PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                    c = config.Transform(t.target, newContext, true);
                }
                break;
            }

            case TransitionType.Precedence:
            {
                throw new NotSupportedException("Precedence predicates are not supported in lexers.");
            }

            case TransitionType.Predicate:
            {
                PredicateTransition pt = (PredicateTransition)t;
                configs.MarkExplicitSemanticContext();
                if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                {
                    c = config.Transform(t.target, true);
                }
                else
                {
                    c = null;
                }
                break;
            }

            case TransitionType.Action:
            {
                if (config.Context.HasEmpty)
                {
                    // execute actions anywhere in the start rule for a token.
                    //
                    // TODO: if the entry rule is invoked recursively, some
                    // actions may be executed during the recursive call. The
                    // problem can appear when hasEmpty() is true but
                    // isEmpty() is false. In this case, the config needs to be
                    // split into two contexts - one with just the empty path
                    // and another with everything but the empty path.
                    // Unfortunately, the current algorithm does not allow
                    // getEpsilonTarget to return two configurations, so
                    // additional modifications are needed before we can support
                    // the split operation.
                    LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                    c = config.Transform(t.target, lexerActionExecutor, true);
                    break;
                }
                else
                {
                    // ignore actions in referenced rules
                    c = config.Transform(t.target, true);
                    break;
                }
            }

            case TransitionType.Epsilon:
            {
                c = config.Transform(t.target, true);
                break;
            }

            case TransitionType.Atom:
            case TransitionType.Range:
            case TransitionType.Set:
            {
                if (treatEofAsEpsilon)
                {
                    if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                    {
                        c = config.Transform(t.target, false);
                        break;
                    }
                }
                c = null;
                break;
            }

            default:
            {
                c = null;
                break;
            }
            }
            return(c);
        }
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition t, ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;
            switch (t.TransitionType)
            {
                case TransitionType.Rule:
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                        c = config.Transform(t.target, newContext, true);
                    }
                    break;
                }

                case TransitionType.Precedence:
                {
                    throw new NotSupportedException("Precedence predicates are not supported in lexers.");
                }

                case TransitionType.Predicate:
                {
                    /*  Track traversing semantic predicates. If we traverse,
                    we cannot add a DFA state for this "reach" computation
                    because the DFA would not test the predicate again in the
                    future. Rather than creating collections of semantic predicates
                    like v3 and testing them on prediction, v4 will test them on the
                    fly all the time using the ATN not the DFA. This is slower but
                    semantically it's not used that often. One of the key elements to
                    this predicate mechanism is not adding DFA states that see
                    predicates immediately afterwards in the ATN. For example,
                    
                    a : ID {p1}? | ID {p2}? ;
                    
                    should create the start state for rule 'a' (to save start state
                    competition), but should not create target of ID state. The
                    collection of ATN states the following ID references includes
                    states reached by traversing predicates. Since this is when we
                    test them, we cannot cash the DFA state target of ID.
                    */
                    PredicateTransition pt = (PredicateTransition)t;
                    configs.MarkExplicitSemanticContext();
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        c = null;
                    }
                    break;
                }

                case TransitionType.Action:
                {
                    if (config.Context.HasEmpty)
                    {
                        // execute actions anywhere in the start rule for a token.
                        //
                        // TODO: if the entry rule is invoked recursively, some
                        // actions may be executed during the recursive call. The
                        // problem can appear when hasEmpty() is true but
                        // isEmpty() is false. In this case, the config needs to be
                        // split into two contexts - one with just the empty path
                        // and another with everything but the empty path.
                        // Unfortunately, the current algorithm does not allow
                        // getEpsilonTarget to return two configurations, so
                        // additional modifications are needed before we can support
                        // the split operation.
                        LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                        c = config.Transform(t.target, lexerActionExecutor, true);
                        break;
                    }
                    else
                    {
                        // ignore actions in referenced rules
                        c = config.Transform(t.target, true);
                        break;
                    }
                }

                case TransitionType.Epsilon:
                {
                    c = config.Transform(t.target, true);
                    break;
                }

                case TransitionType.Atom:
                case TransitionType.Range:
                case TransitionType.Set:
                {
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                        {
                            c = config.Transform(t.target, false);
                            break;
                        }
                    }
                    c = null;
                    break;
                }

                default:
                {
                    c = null;
                    break;
                }
            }
            return c;
        }
Exemple #15
0
        // side-effect: can alter configs.hasSemanticContext
        protected LexerATNConfig GetEpsilonTarget(ICharStream input,
											   LexerATNConfig config,
											   Transition t,
											   ATNConfigSet configs,
											   bool speculative,
											   bool treatEofAsEpsilon)
        {
            LexerATNConfig c = null;
            switch (t.TransitionType)
            {
                case TransitionType.RULE:
                    RuleTransition ruleTransition = (RuleTransition)t;
                    PredictionContext newContext = new SingletonPredictionContext(config.context, ruleTransition.followState.stateNumber);
                    c = new LexerATNConfig(config, t.target, newContext);
                    break;

                case TransitionType.PRECEDENCE:
                    throw new Exception("Precedence predicates are not supported in lexers.");

                case TransitionType.PREDICATE:
                    /*  Track traversing semantic predicates. If we traverse,
                     we cannot add a DFA state for this "reach" computation
                     because the DFA would not test the predicate again in the
                     future. Rather than creating collections of semantic predicates
                     like v3 and testing them on prediction, v4 will test them on the
                     fly all the time using the ATN not the DFA. This is slower but
                     semantically it's not used that often. One of the key elements to
                     this predicate mechanism is not adding DFA states that see
                     predicates immediately afterwards in the ATN. For example,

                     a : ID {p1}? | ID {p2}? ;

                     should create the start state for rule 'a' (to save start state
                     competition), but should not create target of ID state. The
                     collection of ATN states the following ID references includes
                     states reached by traversing predicates. Since this is when we
                     test them, we cannot cash the DFA state target of ID.
                 */
                    PredicateTransition pt = (PredicateTransition)t;
                    if (debug)
                    {
                        Console.WriteLine("EVAL rule " + pt.ruleIndex + ":" + pt.predIndex);
                    }
                    configs.hasSemanticContext = true;
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = new LexerATNConfig(config, t.target);
                    }
                    break;

                case TransitionType.ACTION:
                    if (config.context == null || config.context.HasEmptyPath)
                    {
                        // execute actions anywhere in the start rule for a token.
                        //
                        // TODO: if the entry rule is invoked recursively, some
                        // actions may be executed during the recursive call. The
                        // problem can appear when hasEmptyPath() is true but
                        // isEmpty() is false. In this case, the config needs to be
                        // split into two contexts - one with just the empty path
                        // and another with everything but the empty path.
                        // Unfortunately, the current algorithm does not allow
                        // getEpsilonTarget to return two configurations, so
                        // additional modifications are needed before we can support
                        // the split operation.
                        LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.getLexerActionExecutor(), atn.lexerActions[((ActionTransition)t).actionIndex]);
                        c = new LexerATNConfig(config, t.target, lexerActionExecutor);
                        break;
                    }
                    else {
                        // ignore actions in referenced rules
                        c = new LexerATNConfig(config, t.target);
                        break;
                    }

                case TransitionType.EPSILON:
                    c = new LexerATNConfig(config, t.target);
                    break;

                case TransitionType.ATOM:
                case TransitionType.RANGE:
                case TransitionType.SET:
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(IntStreamConstants.EOF, char.MinValue, char.MaxValue))
                        {
                            c = new LexerATNConfig(config, t.target);
                            break;
                        }
                    }

                    break;
            }

            return c;
        }
Exemple #16
0
 protected internal virtual ATNState GetReachableTarget(Transition trans, int t)
 {
     if (trans.Matches(t, char.MinValue, char.MaxValue))
     {
         return trans.target;
     }
     return null;
 }
Exemple #17
0
 protected internal virtual void GenerateRuleBypassTransitions(ATN atn)
 {
     atn.ruleToTokenType = new int[atn.ruleToStartState.Length];
     for (int i_10 = 0; i_10 < atn.ruleToStartState.Length; i_10++)
     {
         atn.ruleToTokenType[i_10] = atn.maxTokenType + i_10 + 1;
     }
     for (int i_13 = 0; i_13 < atn.ruleToStartState.Length; i_13++)
     {
         BasicBlockStartState bypassStart = new BasicBlockStartState();
         bypassStart.ruleIndex = i_13;
         atn.AddState(bypassStart);
         BlockEndState bypassStop = new BlockEndState();
         bypassStop.ruleIndex = i_13;
         atn.AddState(bypassStop);
         bypassStart.endState = bypassStop;
         atn.DefineDecisionState(bypassStart);
         bypassStop.startState = bypassStart;
         ATNState   endState;
         Transition excludeTransition = null;
         if (atn.ruleToStartState[i_13].isPrecedenceRule)
         {
             // wrap from the beginning of the rule to the StarLoopEntryState
             endState = null;
             foreach (ATNState state_3 in atn.states)
             {
                 if (state_3.ruleIndex != i_13)
                 {
                     continue;
                 }
                 if (!(state_3 is StarLoopEntryState))
                 {
                     continue;
                 }
                 ATNState maybeLoopEndState = state_3.Transition(state_3.NumberOfTransitions - 1).target;
                 if (!(maybeLoopEndState is LoopEndState))
                 {
                     continue;
                 }
                 if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.Transition(0).target is RuleStopState)
                 {
                     endState = state_3;
                     break;
                 }
             }
             if (endState == null)
             {
                 throw new NotSupportedException("Couldn't identify final state of the precedence rule prefix section.");
             }
             excludeTransition = ((StarLoopEntryState)endState).loopBackState.Transition(0);
         }
         else
         {
             endState = atn.ruleToStopState[i_13];
         }
         // all non-excluded transitions that currently target end state need to target blockEnd instead
         foreach (ATNState state_4 in atn.states)
         {
             foreach (Transition transition in state_4.transitions)
             {
                 if (transition == excludeTransition)
                 {
                     continue;
                 }
                 if (transition.target == endState)
                 {
                     transition.target = bypassStop;
                 }
             }
         }
         // all transitions leaving the rule start state need to leave blockStart instead
         while (atn.ruleToStartState[i_13].NumberOfTransitions > 0)
         {
             Transition transition = atn.ruleToStartState[i_13].Transition(atn.ruleToStartState[i_13].NumberOfTransitions - 1);
             atn.ruleToStartState[i_13].RemoveTransition(atn.ruleToStartState[i_13].NumberOfTransitions - 1);
             bypassStart.AddTransition(transition);
         }
         // link the new states
         atn.ruleToStartState[i_13].AddTransition(new EpsilonTransition(bypassStart));
         bypassStop.AddTransition(new EpsilonTransition(endState));
         ATNState matchState = new BasicState();
         atn.AddState(matchState);
         matchState.AddTransition(new AtomTransition(bypassStop, atn.ruleToTokenType[i_13]));
         bypassStart.AddTransition(new EpsilonTransition(matchState));
     }
     if (deserializationOptions.VerifyAtn)
     {
         // reverify after modification
         VerifyATN(atn);
     }
 }
Exemple #18
0
        protected ATNConfig GetEpsilonTarget(ATNConfig config,
										  Transition t,
										  bool collectPredicates,
										  bool inContext,
										  bool fullCtx,
										  bool treatEofAsEpsilon)
        {
            switch (t.TransitionType)
            {
                case TransitionType.RULE:
                    return RuleTransition(config, (RuleTransition)t);

                case TransitionType.PRECEDENCE:
                    return PrecedenceTransition(config, (PrecedencePredicateTransition)t, collectPredicates, inContext, fullCtx);

                case TransitionType.PREDICATE:
                    return PredTransition(config, (PredicateTransition)t,
                                          collectPredicates,
                                          inContext,
                                          fullCtx);

                case TransitionType.ACTION:
                    return ActionTransition(config, (ActionTransition)t);

                case TransitionType.EPSILON:
                    return new ATNConfig(config, t.target);

                case TransitionType.ATOM:
                case TransitionType.RANGE:
                case TransitionType.SET:
                    // EOF transitions act like epsilon transitions after the first EOF
                    // transition is traversed
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(TokenConstants.EOF, 0, 1))
                        {
                            return new ATNConfig(config, t.target);
                        }
                    }

                    return null;

                default:
                    return null;
            }
        }
Exemple #19
0
        protected internal virtual void ReadEdges(ATN atn, IList <IntervalSet> sets)
        {
            //
            // EDGES
            //
            int nedges = ReadInt();

            for (int i_9 = 0; i_9 < nedges; i_9++)
            {
                int            src      = ReadInt();
                int            trg      = ReadInt();
                TransitionType ttype    = (TransitionType)ReadInt();
                int            arg1     = ReadInt();
                int            arg2     = ReadInt();
                int            arg3     = ReadInt();
                Transition     trans    = EdgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets);
                ATNState       srcState = atn.states[src];
                srcState.AddTransition(trans);
            }
            // edges for rule stop states can be derived, so they aren't serialized
            foreach (ATNState state_1 in atn.states)
            {
                for (int i_10 = 0; i_10 < state_1.NumberOfTransitions; i_10++)
                {
                    Transition t = state_1.Transition(i_10);
                    if (!(t is RuleTransition))
                    {
                        continue;
                    }
                    RuleTransition ruleTransition            = (RuleTransition)t;
                    int            outermostPrecedenceReturn = -1;
                    if (atn.ruleToStartState[ruleTransition.target.ruleIndex].isPrecedenceRule)
                    {
                        if (ruleTransition.precedence == 0)
                        {
                            outermostPrecedenceReturn = ruleTransition.target.ruleIndex;
                        }
                    }
                    EpsilonTransition returnTransition = new EpsilonTransition(ruleTransition.followState, outermostPrecedenceReturn);
                    atn.ruleToStopState[ruleTransition.target.ruleIndex].AddTransition(returnTransition);
                }
            }
            foreach (ATNState state_2 in atn.states)
            {
                if (state_2 is BlockStartState)
                {
                    // we need to know the end state to set its start state
                    if (((BlockStartState)state_2).endState == null)
                    {
                        throw new InvalidOperationException();
                    }
                    // block end states can only be associated to a single block start state
                    if (((BlockStartState)state_2).endState.startState != null)
                    {
                        throw new InvalidOperationException();
                    }
                    ((BlockStartState)state_2).endState.startState = (BlockStartState)state_2;
                }
                else if (state_2 is PlusLoopbackState)
                {
                    PlusLoopbackState loopbackState = (PlusLoopbackState)state_2;
                    for (int i_10 = 0; i_10 < loopbackState.NumberOfTransitions; i_10++)
                    {
                        ATNState target = loopbackState.Transition(i_10).target;
                        if (target is PlusBlockStartState)
                        {
                            ((PlusBlockStartState)target).loopBackState = loopbackState;
                        }
                    }
                }
                else if (state_2 is StarLoopbackState)
                {
                    StarLoopbackState loopbackState = (StarLoopbackState)state_2;
                    for (int i_10 = 0; i_10 < loopbackState.NumberOfTransitions; i_10++)
                    {
                        ATNState target = loopbackState.Transition(i_10).target;
                        if (target is StarLoopEntryState)
                        {
                            ((StarLoopEntryState)target).loopBackState = loopbackState;
                        }
                    }
                }
            }
        }
 public ATNState GetReachableTargetHelper(ATNConfig source, Transition trans, int ttype)
 {
     return GetReachableTarget(source, trans, ttype);
 }
Exemple #21
0
        private static int InlineSetRules(ATN atn)
        {
            int inlinedCalls = 0;

            Transition[] ruleToInlineTransition = new Transition[atn.ruleToStartState.Length];
            for (int i = 0; i < atn.ruleToStartState.Length; i++)
            {
                RuleStartState startState  = atn.ruleToStartState[i];
                ATNState       middleState = startState;
                while (middleState.OnlyHasEpsilonTransitions && middleState.NumberOfOptimizedTransitions == 1 && middleState.GetOptimizedTransition(0).TransitionType == TransitionType.EPSILON)
                {
                    middleState = middleState.GetOptimizedTransition(0).target;
                }
                if (middleState.NumberOfOptimizedTransitions != 1)
                {
                    continue;
                }
                Transition matchTransition = middleState.GetOptimizedTransition(0);
                ATNState   matchTarget     = matchTransition.target;
                if (matchTransition.IsEpsilon || !matchTarget.OnlyHasEpsilonTransitions || matchTarget.NumberOfOptimizedTransitions != 1 || !(matchTarget.GetOptimizedTransition(0).target is RuleStopState))
                {
                    continue;
                }
                switch (matchTransition.TransitionType)
                {
                case TransitionType.ATOM:
                case TransitionType.RANGE:
                case TransitionType.SET:
                {
                    ruleToInlineTransition[i] = matchTransition;
                    break;
                }

                case TransitionType.NOT_SET:
                case TransitionType.WILDCARD:
                {
                    // not implemented yet
                    continue;
                }

                default:
                {
                    continue;
                }
                }
            }
            for (int stateNumber = 0; stateNumber < atn.states.Count; stateNumber++)
            {
                ATNState state = atn.states[stateNumber];
                if (state.ruleIndex < 0)
                {
                    continue;
                }
                IList <Transition> optimizedTransitions = null;
                for (int i_1 = 0; i_1 < state.NumberOfOptimizedTransitions; i_1++)
                {
                    Transition transition = state.GetOptimizedTransition(i_1);
                    if (!(transition is RuleTransition))
                    {
                        if (optimizedTransitions != null)
                        {
                            optimizedTransitions.Add(transition);
                        }
                        continue;
                    }
                    RuleTransition ruleTransition = (RuleTransition)transition;
                    Transition     effective      = ruleToInlineTransition[ruleTransition.target.ruleIndex];
                    if (effective == null)
                    {
                        if (optimizedTransitions != null)
                        {
                            optimizedTransitions.Add(transition);
                        }
                        continue;
                    }
                    if (optimizedTransitions == null)
                    {
                        optimizedTransitions = new List <Transition>();
                        for (int j = 0; j < i_1; j++)
                        {
                            optimizedTransitions.Add(state.GetOptimizedTransition(i_1));
                        }
                    }
                    inlinedCalls++;
                    ATNState target            = ruleTransition.followState;
                    ATNState intermediateState = new BasicState();
                    intermediateState.SetRuleIndex(target.ruleIndex);
                    atn.AddState(intermediateState);
                    optimizedTransitions.Add(new EpsilonTransition(intermediateState));
                    switch (effective.TransitionType)
                    {
                    case TransitionType.ATOM:
                    {
                        intermediateState.AddTransition(new AtomTransition(target, ((AtomTransition)effective).token));
                        break;
                    }

                    case TransitionType.RANGE:
                    {
                        intermediateState.AddTransition(new RangeTransition(target, ((RangeTransition)effective).from, ((RangeTransition)effective).to));
                        break;
                    }

                    case TransitionType.SET:
                    {
                        intermediateState.AddTransition(new SetTransition(target, effective.Label));
                        break;
                    }

                    default:
                    {
                        throw new NotSupportedException();
                    }
                    }
                }
                if (optimizedTransitions != null)
                {
                    if (state.IsOptimized)
                    {
                        while (state.NumberOfOptimizedTransitions > 0)
                        {
                            state.RemoveOptimizedTransition(state.NumberOfOptimizedTransitions - 1);
                        }
                    }
                    foreach (Transition transition in optimizedTransitions)
                    {
                        state.AddOptimizedTransition(transition);
                    }
                }
            }
            return(inlinedCalls);
        }
Exemple #22
0
        private static int InlineSetRules(ATN atn)
        {
            int inlinedCalls = 0;
            Transition[] ruleToInlineTransition = new Transition[atn.ruleToStartState.Length];
            for (int i = 0; i < atn.ruleToStartState.Length; i++)
            {
                RuleStartState startState = atn.ruleToStartState[i];
                ATNState middleState = startState;
                while (middleState.OnlyHasEpsilonTransitions && middleState.NumberOfOptimizedTransitions == 1 && middleState.GetOptimizedTransition(0).TransitionType == TransitionType.EPSILON)
                {
                    middleState = middleState.GetOptimizedTransition(0).target;
                }
                if (middleState.NumberOfOptimizedTransitions != 1)
                {
                    continue;
                }
                Transition matchTransition = middleState.GetOptimizedTransition(0);
                ATNState matchTarget = matchTransition.target;
                if (matchTransition.IsEpsilon || !matchTarget.OnlyHasEpsilonTransitions || matchTarget.NumberOfOptimizedTransitions != 1 || !(matchTarget.GetOptimizedTransition(0).target is RuleStopState))
                {
                    continue;
                }
                switch (matchTransition.TransitionType)
                {
                    case TransitionType.ATOM:
                    case TransitionType.RANGE:
                    case TransitionType.SET:
                    {
                        ruleToInlineTransition[i] = matchTransition;
                        break;
                    }

                    case TransitionType.NOT_SET:
                    case TransitionType.WILDCARD:
                    {
                        // not implemented yet
                        continue;
                    }

                    default:
                    {
                        continue;
                    }
                }
            }
            for (int stateNumber = 0; stateNumber < atn.states.Count; stateNumber++)
            {
                ATNState state = atn.states[stateNumber];
                if (state.ruleIndex < 0)
                {
                    continue;
                }
                IList<Transition> optimizedTransitions = null;
                for (int i_1 = 0; i_1 < state.NumberOfOptimizedTransitions; i_1++)
                {
                    Transition transition = state.GetOptimizedTransition(i_1);
                    if (!(transition is RuleTransition))
                    {
                        if (optimizedTransitions != null)
                        {
                            optimizedTransitions.Add(transition);
                        }
                        continue;
                    }
                    RuleTransition ruleTransition = (RuleTransition)transition;
                    Transition effective = ruleToInlineTransition[ruleTransition.target.ruleIndex];
                    if (effective == null)
                    {
                        if (optimizedTransitions != null)
                        {
                            optimizedTransitions.Add(transition);
                        }
                        continue;
                    }
                    if (optimizedTransitions == null)
                    {
                        optimizedTransitions = new List<Transition>();
                        for (int j = 0; j < i_1; j++)
                        {
                            optimizedTransitions.Add(state.GetOptimizedTransition(i_1));
                        }
                    }
                    inlinedCalls++;
                    ATNState target = ruleTransition.followState;
                    ATNState intermediateState = new BasicState();
                    intermediateState.SetRuleIndex(target.ruleIndex);
                    atn.AddState(intermediateState);
                    optimizedTransitions.Add(new EpsilonTransition(intermediateState));
                    switch (effective.TransitionType)
                    {
                        case TransitionType.ATOM:
                        {
                            intermediateState.AddTransition(new AtomTransition(target, ((AtomTransition)effective).token));
                            break;
                        }

                        case TransitionType.RANGE:
                        {
                            intermediateState.AddTransition(new RangeTransition(target, ((RangeTransition)effective).from, ((RangeTransition)effective).to));
                            break;
                        }

                        case TransitionType.SET:
                        {
                            intermediateState.AddTransition(new SetTransition(target, effective.Label));
                            break;
                        }

                        default:
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
                if (optimizedTransitions != null)
                {
                    if (state.IsOptimized)
                    {
                        while (state.NumberOfOptimizedTransitions > 0)
                        {
                            state.RemoveOptimizedTransition(state.NumberOfOptimizedTransitions - 1);
                        }
                    }
                    foreach (Transition transition in optimizedTransitions)
                    {
                        state.AddOptimizedTransition(transition);
                    }
                }
            }
            return inlinedCalls;
        }
 public virtual ATNState GetReachableTarget(Transition trans, int t)
 {
     if (trans.Matches(t, Lexer.MinCharValue, Lexer.MaxCharValue))
     {
         return trans.target;
     }
     return null;
 }