Antlr4.Tool.LeftRecursiveRule.GetRecursiveOpAlts C# (CSharp) Method

GetRecursiveOpAlts() public method

public GetRecursiveOpAlts ( ) : int[]
return int[]
        public virtual int[] GetRecursiveOpAlts()
        {
            if (recOpAlts.Count == 0)
                return null;
            int[] alts = new int[recOpAlts.Count + 1];
            int alt = 1;
            foreach (LeftRecursiveRuleAltInfo altInfo in recOpAlts.Values)
            {
                alts[alt] = altInfo.altNum;
                alt++; // recOpAlts has alts possibly with gaps
            }
            return alts;
        }

Usage Example

Example #1
0
        /** Override this method so that we can record which alternative
         *  was taken at each decision point. For non-left recursive rules,
         *  it's simple. Set decisionStatesThatSetOuterAltNumInContext
         *  indicates which decision states should set the outer alternative number.
         *
         *  <p>Left recursive rules are much more complicated to deal with:
         *  there is typically a decision for the primary alternatives and a
         *  decision to choose between the recursive operator alternatives.
         *  For example, the following left recursive rule has two primary and 2
         *  recursive alternatives.</p>
         *
         *   e : e '*' e
         | '-' INT
         | e '+' e
         | ID
         |     ;
         |
         *  <p>ANTLR rewrites that rule to be</p>
         *
         *   e[int precedence]
         *       : ('-' INT | ID)
         *       ( {...}? '*' e[5]
         | {...}? '+' e[3]
         |       )*
         |      ;
         |
         *
         *  <p>So, there are two decisions associated with picking the outermost alt.
         *  This complicates our tracking significantly. The outermost alternative number
         *  is a function of the decision (ATN state) within a left recursive rule and the
         *  predicted alternative coming back from adaptivePredict().</p>
         *
         *  We use stateToAltsMap as a cache to avoid expensive calls to
         *  getRecursiveOpAlts().
         */
        protected override int VisitDecisionState(DecisionState p)
        {
            int predictedAlt = base.VisitDecisionState(p);

            if (p.NumberOfTransitions > 1)
            {
                //			System.out.println("decision "+p.decision+": "+predictedAlt);
                if (p.decision == this.overrideDecision &&
                    this._input.Index == this.overrideDecisionInputIndex)
                {
                    overrideDecisionRoot = (GrammarInterpreterRuleContext)Context;
                }
            }

            GrammarInterpreterRuleContext ctx = (GrammarInterpreterRuleContext)_ctx;

            if (decisionStatesThatSetOuterAltNumInContext.Get(p.stateNumber))
            {
                ctx.OuterAlternative = predictedAlt;
                Rule r = g.GetRule(p.ruleIndex);
                if (atn.ruleToStartState[r.index].isPrecedenceRule)
                {
                    int[]             alts = stateToAltsMap[p.stateNumber];
                    LeftRecursiveRule lr   = (LeftRecursiveRule)g.GetRule(p.ruleIndex);
                    if (p.StateType == StateType.BlockStart)
                    {
                        if (alts == null)
                        {
                            alts = lr.GetPrimaryAlts();
                            stateToAltsMap[p.stateNumber] = alts; // cache it
                        }
                    }
                    else if (p.StateType == StateType.StarBlockStart)
                    {
                        if (alts == null)
                        {
                            alts = lr.GetRecursiveOpAlts();
                            stateToAltsMap[p.stateNumber] = alts; // cache it
                        }
                    }
                    ctx.OuterAlternative = alts[predictedAlt];
                }
            }

            return(predictedAlt);
        }