Esempio n. 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);
        }
Esempio n. 2
0
            /**
             * Process each rule context we see in top-down order, adjusting min-
             * max and start-stop tokens, as well as adding the context to the
             * rule start map.
             *
             * @param ctx Context to process
             */
            public void EnterEveryRule(ParserRuleContext ctx)
            {
                IncrementalParserRuleContext incCtx = (IncrementalParserRuleContext)ctx;

                // Don't bother adjusting rule contexts that we can't possibly
                // reuse. Also don't touch contexts without an epoch. They must
                // represent something the incremental parser never saw,
                // since it sets epochs on all contexts it touches.
                if (incCtx.epoch == -1)
                {
                    return;
                }
                bool mayNeedAdjustment = parent.tokenOffsets != null && parent.tokenOffsets.Count != 0;

                if (mayNeedAdjustment)
                {
                    adjustMinMax(incCtx);
                }
                if (!parent.ruleAffectedByTokenChanges(incCtx))
                {
                    if (mayNeedAdjustment)
                    {
                        adjustStartStop(incCtx);
                    }
                    String key = parent.getKeyFromContext(incCtx);
                    parent.ruleStartMap.Add(key, incCtx);
                }
            }
Esempio n. 3
0
            /**
             * Adjust the minimum/maximum token index that appears in a rule context. Like
             * other functions, this simply converts the token indexes from how they appear
             * in the old stream to how they would appear in the new stream.
             *
             * @param ctx Parser context to adjust.
             */
            private void adjustMinMax(IncrementalParserRuleContext ctx)
            {
                bool   changed  = false;
                int    newMin   = ctx.MinTokenIndex;
                IToken newToken = getAdjustedToken(newMin);

                if (newToken != null)
                {
                    newMin  = newToken.TokenIndex;
                    changed = true;
                }

                int newMax = ctx.MaxTokenIndex;

                newToken = getAdjustedToken(newMax);

                if (newToken != null)
                {
                    newMax  = newToken.TokenIndex;
                    changed = true;
                }

                if (changed)
                {
                    ctx.setMinMaxTokenIndex(Interval.Of(newMin, newMax));
                }
            }
Esempio n. 4
0
        /*
         * These two functions are parse of the ParseTreeListener API. We do not need to
         * call super methods
         */

        public void EnterEveryRule(ParserRuleContext ctx)
        {
            // During rule entry, we push a new min/max token state.
            pushCurrentTokenToMinMax();
            IncrementalParserRuleContext incCtx = (IncrementalParserRuleContext)ctx;

            incCtx.epoch = this.getParserEpoch();
        }
Esempio n. 5
0
        /**
         * Pop the min max stack the stream is using and union the interval into the
         * passed in context. Return the interval for the context
         *
         * @param ctx Context to union interval into.
         */
        private Interval popAndHandleMinMax(IncrementalParserRuleContext ctx)
        {
            Interval interval = popCurrentMinMax(ctx);

            ctx.setMinMaxTokenIndex(ctx.getMinMaxTokenIndex().Union(interval));
            // Returning interval is wrong because there may have been child
            // intervals already merged into this ctx.
            return(ctx.getMinMaxTokenIndex());
        }
Esempio n. 6
0
        /*
         * This is part of the regular Parser API. The super method must be called.
         */

        /**
         * The new recursion context is an unfortunate edge case for us. It reparents
         * the relationship between the contexts, so we need to merge intervals here.
         */

        public override void PushNewRecursionContext(ParserRuleContext localctx, int state, int ruleIndex)
        {
            // This context becomes the child
            IncrementalParserRuleContext previous = (IncrementalParserRuleContext)this._ctx;
            // The incoming context becomes the parent
            IncrementalParserRuleContext incLocalCtx = (IncrementalParserRuleContext)localctx;

            incLocalCtx.setMinMaxTokenIndex(incLocalCtx.getMinMaxTokenIndex().Union(previous.getMinMaxTokenIndex()));
            base.PushNewRecursionContext(localctx, state, ruleIndex);
        }
Esempio n. 7
0
        /**
         * Index a given parse tree and adjust the min/max ranges
         *
         * @param tree Parser context to adjust
         */
        private void indexAndAdjustParseTree(IncrementalParserRuleContext tree)
        {
            // This is a quick way of indexing the parse tree by start. We actually
            // could walk the old parse tree as the parse proceeds. This is left as
            // a future optimization. We also could just allow passing in
            // constructed maps if this turns out to be slow.
            tokenStream.Fill();
            IParseTreeListener listener = new ParseTreeProcessor(this);

            ParseTreeWalker.Default.Walk(listener, tree);
        }
Esempio n. 8
0
 public IncrementalParserData(IncrementalTokenStream tokenStream, List <TokenChange> tokenChanges,
                              IncrementalParserRuleContext oldTree)
 {
     this.tokenChanges = tokenChanges;
     if (tokenChanges != null)
     {
         this.tokenStream = tokenStream;
         computeTokenOffsetRanges(oldTree.MaxTokenIndex);
         indexAndAdjustParseTree(oldTree);
     }
 }
Esempio n. 9
0
        public void ExitEveryRule(ParserRuleContext ctx)
        {
            // On exit, we need to merge the min max into the current context,
            // and then merge the current context interval into our parent.

            // First merge with the interval on the top of the stack.
            IncrementalParserRuleContext incCtx = (IncrementalParserRuleContext)ctx;
            Interval interval = popAndHandleMinMax(incCtx);

            // Now merge with our parent interval.
            if (incCtx.Parent != null)
            {
                IncrementalParserRuleContext parentIncCtx = (IncrementalParserRuleContext)incCtx.Parent;
                parentIncCtx.setMinMaxTokenIndex(parentIncCtx.getMinMaxTokenIndex().Union(interval));
            }
        }
Esempio n. 10
0
            /**
             * Adjust the start/stop token indexes of a rule to take into account position
             * changes in the token stream.
             *
             * @param ctx The rule context to adjust the start/stop tokens of.
             */
            private void adjustStartStop(IncrementalParserRuleContext ctx)
            {
                IToken newToken = getAdjustedToken(ctx.Start.TokenIndex);

                if (newToken != null)
                {
                    ctx.Start = newToken;
                }

                if (ctx.Stop != null)
                {
                    newToken = getAdjustedToken(ctx.Stop.TokenIndex);
                    if (newToken != null)
                    {
                        ctx.Stop = newToken;
                    }
                }
            }
Esempio n. 11
0
        /**
         * Determine whether a given parser rule is affected by changes to the token
         * stream.
         *
         * @param ctx Current parser context coming into a rule.
         */
        public bool ruleAffectedByTokenChanges(IncrementalParserRuleContext ctx)
        {
            // If we never got passed data, reparse everything.
            if (this.tokenChanges == null)
            {
                return(true);
            }
            // However if there are no changes, the rule is fine
            if (this.tokenChanges.Count == 0)
            {
                return(false);
            }

            // See if any changed token exists in our upper, lower bounds.
            int start = ctx.MinTokenIndex;
            int end   = ctx.MaxTokenIndex;
            // See if the set has anything in the range we are asking about
            bool result = false;
            // Get a view of all elements >= start token to start.
            // SortedSet<int> tailSet = this.changedTokens.tailSet(start, true);
            SortedSet <int> tailSet = this.changedTokens.GetViewBetween(start, this.changedTokens.Max);

            // If *any* are in range, the rule is modified.
            // Since the set is ordered, once we go past the end of the [start, end] range,
            // we can stop.
            foreach (int elem in tailSet)
            {
                if (elem <= end)
                {
                    result = true;
                    break;
                }
                else if (elem > end)
                {
                    break;
                }
            }
            if (result)
            {
                return(true);
            }

            return(false);
        }
Esempio n. 12
0
        // Pop the min max stack the stream is using and return the interval.
        private Interval popCurrentMinMax(IncrementalParserRuleContext ctx)
        {
            IncrementalTokenStream incStream = (IncrementalTokenStream)InputStream;

            return(incStream.popMinMax());
        }
Esempio n. 13
0
 private String getKeyFromContext(IncrementalParserRuleContext ctx)
 {
     return(getKey(ctx.Depth(), ctx.invokingState, ctx.RuleIndex, ctx.Start.TokenIndex));
 }
Esempio n. 14
0
 public IncrementalParserRuleContext(IncrementalParserRuleContext parent, int invokingStateNumber)
     : base(parent, invokingStateNumber)
 {
     // super(parent, invokingStateNumber);
 }