예제 #1
0
        /**
         * Guard a rule's previous context from being reused.
         * <p>
         * This routine will check whether a given parser rule needs to be rerun, or if
         * we already have context that can be reused for this parse.
         */
        public IncrementalParserRuleContext guardRule(IncrementalParserRuleContext parentCtx, int state, int ruleIndex)
        {
            // If we have no previous parse data, the rule needs to be run.
            if (this.parseData == null)
            {
                return(null);
            }

            Console.WriteLine($"guardRule() state = {state.ToString()}, ruleIndex = {ruleIndex.ToString()}");
            // See if we have seen this state before at this starting point.
            IncrementalParserRuleContext existingCtx = this.parseData.tryGetContext(
                parentCtx != null ? parentCtx.Depth() + 1 : 1, State, ruleIndex,
                this._input.LT(1).TokenIndex);

            // We haven't see it, so we need to rerun this rule.
            if (existingCtx == null)
            {
                return(null);
            }
            // We have seen it, see if it was affected by the parse
            if (this.parseData.ruleAffectedByTokenChanges(existingCtx))
            {
                return(null);
            }
            // Everything checked out, reuse the rule context - we add it to the
            // parent context as enterRule would have;
            if (this._ctx != null)
            {
                IncrementalParserRuleContext parent = (IncrementalParserRuleContext)this._ctx;
                // add current context to parent if we have a parent
                parent?.AddChild(existingCtx);
            }
            return(existingCtx);
        }
예제 #2
0
 private String getKeyFromContext(IncrementalParserRuleContext ctx)
 {
     return(getKey(ctx.Depth(), ctx.invokingState, ctx.RuleIndex, ctx.Start.TokenIndex));
 }