Antlr4.Runtime.Atn.ParserATNSimulator.ExecATN C# (CSharp) Method

ExecATN() protected method

protected ExecATN ( DFA dfa, DFAState s0, ITokenStream input, int startIndex, ParserRuleContext outerContext ) : int
dfa Antlr4.Runtime.Dfa.DFA
s0 Antlr4.Runtime.Dfa.DFAState
input ITokenStream
startIndex int
outerContext ParserRuleContext
return int
        protected int ExecATN(DFA dfa, DFAState s0,
						   ITokenStream input, int startIndex,
						   ParserRuleContext outerContext)
        {
            if (debug || debug_list_atn_decisions)
            {
                Console.WriteLine("execATN decision " + dfa.decision +
                                   " exec LA(1)==" + GetLookaheadName(input) +
                                   " line " + input.LT(1).Line + ":" + input.LT(1).Column);
            }

            DFAState previousD = s0;

            if (debug) Console.WriteLine("s0 = " + s0);

            int t = input.LA(1);

            while (true)
            { // while more work
                DFAState D = GetExistingTargetState(previousD, t);
                if (D == null)
                {
                    D = ComputeTargetState(dfa, previousD, t);
                }

                if (D == ERROR)
                {
                    // if any configs in previous dipped into outer context, that
                    // means that input up to t actually finished entry rule
                    // at least for SLL decision. Full LL doesn't dip into outer
                    // so don't need special case.
                    // We will get an error no matter what so delay until after
                    // decision; better error message. Also, no reachable target
                    // ATN states in SLL implies LL will also get nowhere.
                    // If conflict in states that dip out, choose min since we
                    // will get error no matter what.
                    NoViableAltException e = NoViableAlt(input, outerContext, previousD.configSet, startIndex);
                    input.Seek(startIndex);
                    int alt = GetSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configSet, outerContext);
                    if (alt != ATN.INVALID_ALT_NUMBER)
                    {
                        return alt;
                    }
                    throw e;
                }

                if (D.requiresFullContext && mode != PredictionMode.SLL)
                {
                    // IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error)
                    BitSet conflictingAlts = D.configSet.conflictingAlts;
                    if (D.predicates != null)
                    {
                        if (debug) Console.WriteLine("DFA state has preds in DFA sim LL failover");
                        int conflictIndex = input.Index;
                        if (conflictIndex != startIndex)
                        {
                            input.Seek(startIndex);
                        }

                        conflictingAlts = EvalSemanticContext(D.predicates, outerContext, true);
                        if (conflictingAlts.Cardinality() == 1)
                        {
                            if (debug) Console.WriteLine("Full LL avoided");
                            return conflictingAlts.NextSetBit(0);
                        }

                        if (conflictIndex != startIndex)
                        {
                            // restore the index so reporting the fallback to full
                            // context occurs with the index at the correct spot
                            input.Seek(conflictIndex);
                        }
                    }

                    if (dfa_debug) Console.WriteLine("ctx sensitive state " + outerContext + " in " + D);
                    bool fullCtx = true;
                    ATNConfigSet s0_closure =
                        ComputeStartState(dfa.atnStartState, outerContext, fullCtx);
                    ReportAttemptingFullContext(dfa, conflictingAlts, D.configSet, startIndex, input.Index);
                    int alt = ExecATNWithFullContext(dfa, D, s0_closure,
                                                     input, startIndex,
                                                     outerContext);
                    return alt;
                }

                if (D.isAcceptState)
                {
                    if (D.predicates == null)
                    {
                        return D.prediction;
                    }

                    int stopIndex = input.Index;
                    input.Seek(startIndex);
                    BitSet alts = EvalSemanticContext(D.predicates, outerContext, true);
                    switch (alts.Cardinality())
                    {
                        case 0:
                            throw NoViableAlt(input, outerContext, D.configSet, startIndex);

                        case 1:
                            return alts.NextSetBit(0);

                        default:
                            // report ambiguity after predicate evaluation to make sure the correct
                            // set of ambig alts is reported.
                            ReportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configSet);
                            return alts.NextSetBit(0);
                    }
                }

                previousD = D;

                if (t != IntStreamConstants.EOF)
                {
                    input.Consume();
                    t = input.LA(1);
                }
            }
        }