Antlr4.Runtime.Atn.ATNDeserializer.GenerateRuleBypassTransitions C# (CSharp) Method

GenerateRuleBypassTransitions() protected method

protected GenerateRuleBypassTransitions ( ATN atn ) : void
atn ATN
return void
        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);
            }
        }