예제 #1
0
        public virtual string ToDotString()
        {
#if COMPACT
            throw new NotImplementedException("The current platform does not provide RuntimeHelpers.GetHashCode(object).");
#else
            StringBuilder builder = new StringBuilder();
            builder.Append("digraph G {\n");
            builder.Append("rankdir=LR;\n");
            HashSet <PredictionContext> visited  = new HashSet <PredictionContext>();
            Stack <PredictionContext>   workList = new Stack <PredictionContext>();
            workList.Push(Context);
            visited.Add(Context);
            while (workList.Count > 0)
            {
                PredictionContext current = workList.Pop();
                for (int i = 0; i < current.Size; i++)
                {
                    builder.Append("  s").Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(current));
                    builder.Append("->");
                    builder.Append("s").Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(current.GetParent(i)));
                    builder.Append("[label=\"").Append(current.GetReturnState(i)).Append("\"];\n");
                    if (visited.Add(current.GetParent(i)))
                    {
                        workList.Push(current.GetParent(i));
                    }
                }
            }
            builder.Append("}\n");
            return(builder.ToString());
#endif
        }
예제 #2
0
        public static Antlr4.Runtime.Atn.PredictionContext GetCachedContext(Antlr4.Runtime.Atn.PredictionContext context, ConcurrentDictionary <Antlr4.Runtime.Atn.PredictionContext, Antlr4.Runtime.Atn.PredictionContext> contextCache, PredictionContext.IdentityHashMap visited)
        {
            if (context.IsEmpty)
            {
                return(context);
            }
            Antlr4.Runtime.Atn.PredictionContext existing;
            if (visited.TryGetValue(context, out existing))
            {
                return(existing);
            }
            if (contextCache.TryGetValue(context, out existing))
            {
                visited[context] = existing;
                return(existing);
            }
            bool changed = false;

            Antlr4.Runtime.Atn.PredictionContext[] parents = new Antlr4.Runtime.Atn.PredictionContext[context.Size];
            for (int i = 0; i < parents.Length; i++)
            {
                Antlr4.Runtime.Atn.PredictionContext parent = GetCachedContext(context.GetParent(i), contextCache, visited);
                if (changed || parent != context.GetParent(i))
                {
                    if (!changed)
                    {
                        parents = new Antlr4.Runtime.Atn.PredictionContext[context.Size];
                        for (int j = 0; j < context.Size; j++)
                        {
                            parents[j] = context.GetParent(j);
                        }
                        changed = true;
                    }
                    parents[i] = parent;
                }
            }
            if (!changed)
            {
                existing         = contextCache.GetOrAdd(context, context);
                visited[context] = existing;
                return(context);
            }
            // We know parents.length>0 because context.isEmpty() is checked at the beginning of the method.
            Antlr4.Runtime.Atn.PredictionContext updated;
            if (parents.Length == 1)
            {
                updated = new SingletonPredictionContext(parents[0], context.GetReturnState(0));
            }
            else
            {
                ArrayPredictionContext arrayPredictionContext = (ArrayPredictionContext)context;
                updated = new ArrayPredictionContext(parents, arrayPredictionContext.returnStates, context.cachedHashCode);
            }
            existing         = contextCache.GetOrAdd(updated, updated);
            visited[updated] = existing;
            visited[context] = existing;
            return(updated);
        }
예제 #3
0
        /// <summary>
        /// Since the alternatives within any lexer decision are ordered by
        /// preference, this method stops pursuing the closure as soon as an accept
        /// state is reached.
        /// </summary>
        /// <remarks>
        /// Since the alternatives within any lexer decision are ordered by
        /// preference, this method stops pursuing the closure as soon as an accept
        /// state is reached. After the first accept state is reached by depth-first
        /// search from
        /// <code>config</code>
        /// , all other (potentially reachable) states for
        /// this rule would have a lower priority.
        /// </remarks>
        /// <returns>
        ///
        /// <code>true</code>
        /// if an accept state is reached, otherwise
        /// <code>false</code>
        /// .
        /// </returns>
        protected internal virtual bool Closure(ICharStream input, ATNConfig config, ATNConfigSet
                                                configs, bool speculative)
        {
            if (config.State is RuleStopState)
            {
                PredictionContext context = config.Context;
                if (context.IsEmpty)
                {
                    configs.AddItem(config);
                    return(true);
                }
                else
                {
                    if (context.HasEmpty)
                    {
                        configs.AddItem(config.Transform(config.State, PredictionContext.EmptyFull));
                        return(true);
                    }
                }
                for (int i = 0; i < context.Size; i++)
                {
                    int returnStateNumber = context.GetReturnState(i);
                    if (returnStateNumber == PredictionContext.EmptyFullStateKey)
                    {
                        continue;
                    }
                    PredictionContext newContext = context.GetParent(i);
                    // "pop" return state
                    ATNState  returnState = atn.states[returnStateNumber];
                    ATNConfig c           = ATNConfig.Create(returnState, config.Alt, newContext);
                    if (Closure(input, c, configs, speculative))
                    {
                        return(true);
                    }
                }
                return(false);
            }
            // optimization
            if (!config.State.OnlyHasEpsilonTransitions)
            {
                configs.AddItem(config);
            }
            ATNState p = config.State;

            for (int i_1 = 0; i_1 < p.NumberOfOptimizedTransitions; i_1++)
            {
                Transition t = p.GetOptimizedTransition(i_1);
                ATNConfig  c = GetEpsilonTarget(input, config, t, configs, speculative);
                if (c != null)
                {
                    if (Closure(input, c, configs, speculative))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #4
0
        /// <summary>
        /// Since the alternatives within any lexer decision are ordered by
        /// preference, this method stops pursuing the closure as soon as an accept
        /// state is reached.
        /// </summary>
        /// <remarks>
        /// Since the alternatives within any lexer decision are ordered by
        /// preference, this method stops pursuing the closure as soon as an accept
        /// state is reached. After the first accept state is reached by depth-first
        /// search from
        /// <paramref name="config"/>
        /// , all other (potentially reachable) states for
        /// this rule would have a lower priority.
        /// </remarks>
        /// <returns>
        ///
        /// <see langword="true"/>
        /// if an accept state is reached, otherwise
        /// <see langword="false"/>
        /// .
        /// </returns>
        protected internal virtual bool Closure(ICharStream input, ATNConfig config, ATNConfigSet configs, bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon)
        {
            if (config.State is RuleStopState)
            {
                PredictionContext context = config.Context;
                if (context.IsEmpty)
                {
                    configs.Add(config);
                    return(true);
                }
                else
                {
                    if (context.HasEmpty)
                    {
                        configs.Add(config.Transform(config.State, PredictionContext.EmptyFull, true));
                        currentAltReachedAcceptState = true;
                    }
                }
                for (int i = 0; i < context.Size; i++)
                {
                    int returnStateNumber = context.GetReturnState(i);
                    if (returnStateNumber == PredictionContext.EmptyFullStateKey)
                    {
                        continue;
                    }
                    PredictionContext newContext = context.GetParent(i);
                    // "pop" return state
                    ATNState  returnState = atn.states[returnStateNumber];
                    ATNConfig c           = config.Transform(returnState, newContext, false);
                    currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
                }
                return(currentAltReachedAcceptState);
            }
            // optimization
            if (!config.State.OnlyHasEpsilonTransitions)
            {
                if (!currentAltReachedAcceptState || !config.PassedThroughNonGreedyDecision)
                {
                    configs.Add(config);
                }
            }
            ATNState p = config.State;

            for (int i_1 = 0; i_1 < p.NumberOfOptimizedTransitions; i_1++)
            {
                Transition t = p.GetOptimizedTransition(i_1);
                ATNConfig  c = GetEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon);
                if (c != null)
                {
                    currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
                }
            }
            return(currentAltReachedAcceptState);
        }
예제 #5
0
        public virtual bool Contains(Antlr4.Runtime.Atn.ATNConfig subconfig)
        {
            if (this.State.stateNumber != subconfig.State.stateNumber || this.Alt != subconfig
                .Alt || !this.SemanticContext.Equals(subconfig.SemanticContext))
            {
                return(false);
            }
            Stack <PredictionContext> leftWorkList  = new Stack <PredictionContext>();
            Stack <PredictionContext> rightWorkList = new Stack <PredictionContext>();

            leftWorkList.Push(Context);
            rightWorkList.Push(subconfig.Context);
            while (leftWorkList.Count > 0)
            {
                PredictionContext left  = leftWorkList.Pop();
                PredictionContext right = rightWorkList.Pop();
                if (left == right)
                {
                    return(true);
                }
                if (left.Size < right.Size)
                {
                    return(false);
                }
                if (right.IsEmpty)
                {
                    return(left.HasEmpty);
                }
                else
                {
                    for (int i = 0; i < right.Size; i++)
                    {
                        int index = left.FindReturnState(right.GetReturnState(i));
                        if (index < 0)
                        {
                            // assumes invokingStates has no duplicate entries
                            return(false);
                        }
                        leftWorkList.Push(left.GetParent(index));
                        rightWorkList.Push(right.GetParent(i));
                    }
                }
            }
            return(false);
        }
예제 #6
0
        public virtual string[] ToStrings(IRecognizer recognizer, Antlr4.Runtime.Atn.PredictionContext
                                          stop, int currentState)
        {
            List <string> result = new List <string>();

            for (int perm = 0; ; perm++)
            {
                int  offset = 0;
                bool last   = true;
                Antlr4.Runtime.Atn.PredictionContext p = this;
                int           stateNumber = currentState;
                StringBuilder localBuffer = new StringBuilder();
                localBuffer.Append("[");
                while (!p.IsEmpty && p != stop)
                {
                    int index = 0;
                    if (p.Size > 0)
                    {
                        int bits = 1;
                        while ((1 << bits) < p.Size)
                        {
                            bits++;
                        }
                        int mask = (1 << bits) - 1;
                        index = (perm >> offset) & mask;
                        last &= index >= p.Size - 1;
                        if (index >= p.Size)
                        {
                            goto outer_continue;
                        }
                        offset += bits;
                    }
                    if (recognizer != null)
                    {
                        if (localBuffer.Length > 1)
                        {
                            // first char is '[', if more than that this isn't the first rule
                            localBuffer.Append(' ');
                        }
                        ATN      atn      = recognizer.Atn;
                        ATNState s        = atn.states[stateNumber];
                        string   ruleName = recognizer.RuleNames[s.ruleIndex];
                        localBuffer.Append(ruleName);
                    }
                    else
                    {
                        if (p.GetReturnState(index) != EmptyFullStateKey)
                        {
                            if (!p.IsEmpty)
                            {
                                if (localBuffer.Length > 1)
                                {
                                    // first char is '[', if more than that this isn't the first rule
                                    localBuffer.Append(' ');
                                }
                                localBuffer.Append(p.GetReturnState(index));
                            }
                        }
                    }
                    stateNumber = p.GetReturnState(index);
                    p           = p.GetParent(index);
                }
                localBuffer.Append("]");
                result.Add(localBuffer.ToString());
                if (last)
                {
                    break;
                }
                outer_continue :;
            }

            return(result.ToArray());
        }
예제 #7
0
        internal static Antlr4.Runtime.Atn.PredictionContext Join(Antlr4.Runtime.Atn.PredictionContext
                                                                  context0, Antlr4.Runtime.Atn.PredictionContext context1, PredictionContextCache
                                                                  contextCache)
        {
            if (context0 == context1)
            {
                return(context0);
            }
            if (context0.IsEmpty)
            {
                return(IsEmptyLocal(context0) ? context0 : AddEmptyContext(context1));
            }
            else
            {
                if (context1.IsEmpty)
                {
                    return(IsEmptyLocal(context1) ? context1 : AddEmptyContext(context0));
                }
            }
            int context0size = context0.Size;
            int context1size = context1.Size;

            if (context0size == 1 && context1size == 1 && context0.GetReturnState(0) == context1
                .GetReturnState(0))
            {
                Antlr4.Runtime.Atn.PredictionContext merged = contextCache.Join(context0.GetParent
                                                                                    (0), context1.GetParent(0));
                if (merged == context0.GetParent(0))
                {
                    return(context0);
                }
                else
                {
                    if (merged == context1.GetParent(0))
                    {
                        return(context1);
                    }
                    else
                    {
                        return(merged.GetChild(context0.GetReturnState(0)));
                    }
                }
            }
            int count = 0;

            Antlr4.Runtime.Atn.PredictionContext[] parentsList = new Antlr4.Runtime.Atn.PredictionContext
                                                                 [context0size + context1size];
            int[] returnStatesList = new int[parentsList.Length];
            int   leftIndex        = 0;
            int   rightIndex       = 0;
            bool  canReturnLeft    = true;
            bool  canReturnRight   = true;

            while (leftIndex < context0size && rightIndex < context1size)
            {
                if (context0.GetReturnState(leftIndex) == context1.GetReturnState(rightIndex))
                {
                    parentsList[count] = contextCache.Join(context0.GetParent(leftIndex), context1.GetParent
                                                               (rightIndex));
                    returnStatesList[count] = context0.GetReturnState(leftIndex);
                    canReturnLeft           = canReturnLeft && parentsList[count] == context0.GetParent(leftIndex
                                                                                                        );
                    canReturnRight = canReturnRight && parentsList[count] == context1.GetParent(rightIndex
                                                                                                );
                    leftIndex++;
                    rightIndex++;
                }
                else
                {
                    if (context0.GetReturnState(leftIndex) < context1.GetReturnState(rightIndex))
                    {
                        parentsList[count]      = context0.GetParent(leftIndex);
                        returnStatesList[count] = context0.GetReturnState(leftIndex);
                        canReturnRight          = false;
                        leftIndex++;
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(context1.GetReturnState(rightIndex) < context0.GetReturnState
                                                            (leftIndex));
                        parentsList[count]      = context1.GetParent(rightIndex);
                        returnStatesList[count] = context1.GetReturnState(rightIndex);
                        canReturnLeft           = false;
                        rightIndex++;
                    }
                }
                count++;
            }
            while (leftIndex < context0size)
            {
                parentsList[count]      = context0.GetParent(leftIndex);
                returnStatesList[count] = context0.GetReturnState(leftIndex);
                leftIndex++;
                canReturnRight = false;
                count++;
            }
            while (rightIndex < context1size)
            {
                parentsList[count]      = context1.GetParent(rightIndex);
                returnStatesList[count] = context1.GetReturnState(rightIndex);
                rightIndex++;
                canReturnLeft = false;
                count++;
            }
            if (canReturnLeft)
            {
                return(context0);
            }
            else
            {
                if (canReturnRight)
                {
                    return(context1);
                }
            }
            if (count < parentsList.Length)
            {
                parentsList      = Arrays.CopyOf(parentsList, count);
                returnStatesList = Arrays.CopyOf(returnStatesList, count);
            }
            if (parentsList.Length == 0)
            {
                // if one of them was EMPTY_LOCAL, it would be empty and handled at the beginning of the method
                return(EmptyFull);
            }
            else
            {
                if (parentsList.Length == 1)
                {
                    return(new SingletonPredictionContext(parentsList[0], returnStatesList[0]));
                }
                else
                {
                    return(new ArrayPredictionContext(parentsList, returnStatesList));
                }
            }
        }
예제 #8
0
        private static PredictionContext AppendContext(PredictionContext context, PredictionContext suffix, PredictionContext.IdentityHashMap visited)
        {
            if (suffix.IsEmpty)
            {
                if (IsEmptyLocal(suffix))
                {
                    if (context.HasEmpty)
                    {
                        return(EmptyLocal);
                    }
                    throw new NotSupportedException("what to do here?");
                }
                return(context);
            }
            if (suffix.Size != 1)
            {
                throw new NotSupportedException("Appending a tree suffix is not yet supported.");
            }
            PredictionContext result;

            if (!visited.TryGetValue(context, out result))
            {
                if (context.IsEmpty)
                {
                    result = suffix;
                }
                else
                {
                    int parentCount = context.Size;
                    if (context.HasEmpty)
                    {
                        parentCount--;
                    }
                    PredictionContext[] updatedParents = new PredictionContext[parentCount];
                    int[] updatedReturnStates          = new int[parentCount];
                    for (int i = 0; i < parentCount; i++)
                    {
                        updatedReturnStates[i] = context.GetReturnState(i);
                    }
                    for (int i_1 = 0; i_1 < parentCount; i_1++)
                    {
                        updatedParents[i_1] = AppendContext(context.GetParent(i_1), suffix, visited);
                    }
                    if (updatedParents.Length == 1)
                    {
                        result = new SingletonPredictionContext(updatedParents[0], updatedReturnStates[0]);
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(updatedParents.Length > 1);
                        result = new Antlr4.Runtime.Atn.ArrayPredictionContext(updatedParents, updatedReturnStates);
                    }
                    if (context.HasEmpty)
                    {
                        result = PredictionContext.Join(result, suffix);
                    }
                }
                visited[context] = result;
            }
            return(result);
        }
예제 #9
0
        /// <summary>
        /// Compute set of tokens that can follow
        /// <code>s</code>
        /// in the ATN in the
        /// specified
        /// <code>ctx</code>
        /// .
        /// <p/>
        /// If
        /// <code>ctx</code>
        /// is
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// and
        /// <code>stopState</code>
        /// or the end of the rule containing
        /// <code>s</code>
        /// is reached,
        /// <see cref="TokenConstants.Epsilon"/>
        /// is added to the result set. If
        /// <code>ctx</code>
        /// is not
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// and
        /// <code>addEOF</code>
        /// is
        /// <code>true</code>
        /// and
        /// <code>stopState</code>
        /// or the end of the outermost rule is reached,
        /// <see cref="TokenConstants.Eof"/>
        /// is added to the result set.
        /// </summary>
        /// <param name="s">the ATN state.</param>
        /// <param name="stopState">
        /// the ATN state to stop at. This can be a
        /// <see cref="BlockEndState">BlockEndState</see>
        /// to detect epsilon paths through a closure.
        /// </param>
        /// <param name="ctx">
        /// The outer context, or
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// if
        /// the outer context should not be used.
        /// </param>
        /// <param name="look">The result lookahead set.</param>
        /// <param name="lookBusy">
        /// A set used for preventing epsilon closures in the ATN
        /// from causing a stack overflow. Outside code should pass
        /// <code>new HashSet&lt;ATNConfig&gt;</code>
        /// for this argument.
        /// </param>
        /// <param name="calledRuleStack">
        /// A set used for preventing left recursion in the
        /// ATN from causing a stack overflow. Outside code should pass
        /// <code>new BitSet()</code>
        /// for this argument.
        /// </param>
        /// <param name="seeThruPreds">
        ///
        /// <code>true</code>
        /// to true semantic predicates as
        /// implicitly
        /// <code>true</code>
        /// and "see through them", otherwise
        /// <code>false</code>
        /// to treat semantic predicates as opaque and add
        /// <see cref="HitPred">HitPred</see>
        /// to the
        /// result if one is encountered.
        /// </param>
        /// <param name="addEOF">
        /// Add
        /// <see cref="TokenConstants.Eof"/>
        /// to the result if the end of the
        /// outermost context is reached. This parameter has no effect if
        /// <code>ctx</code>
        /// is
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// .
        /// </param>
        protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext
                                             ctx, IntervalSet look, HashSet <ATNConfig> lookBusy, BitSet calledRuleStack,
                                             bool seeThruPreds, bool addEOF)
        {
            //		System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
            ATNConfig c = ATNConfig.Create(s, 0, ctx);

            if (!lookBusy.Add(c))
            {
                return;
            }
            if (s == stopState)
            {
                if (PredictionContext.IsEmptyLocal(ctx))
                {
                    look.Add(TokenConstants.Epsilon);
                    return;
                }
                else
                {
                    if (ctx.IsEmpty && addEOF)
                    {
                        look.Add(TokenConstants.Eof);
                        return;
                    }
                }
            }
            if (s is RuleStopState)
            {
                if (PredictionContext.IsEmptyLocal(ctx))
                {
                    look.Add(TokenConstants.Epsilon);
                    return;
                }
                else
                {
                    if (ctx.IsEmpty && addEOF)
                    {
                        look.Add(TokenConstants.Eof);
                        return;
                    }
                }
                for (int i = 0; i < ctx.Size; i++)
                {
                    if (ctx.GetReturnState(i) != PredictionContext.EmptyFullStateKey)
                    {
                        ATNState returnState = atn.states[ctx.GetReturnState(i)];
                        //					System.out.println("popping back to "+retState);
                        for (int j = 0; j < ctx.Size; j++)
                        {
                            bool removed = calledRuleStack.Get(returnState.ruleIndex);
                            try
                            {
                                calledRuleStack.Clear(returnState.ruleIndex);
                                Look(returnState, stopState, ctx.GetParent(j), look, lookBusy, calledRuleStack, seeThruPreds
                                     , addEOF);
                            }
                            finally
                            {
                                if (removed)
                                {
                                    calledRuleStack.Set(returnState.ruleIndex);
                                }
                            }
                        }
                        return;
                    }
                }
            }
            int n = s.NumberOfTransitions;

            for (int i_1 = 0; i_1 < n; i_1++)
            {
                Transition t = s.Transition(i_1);
                if (t.GetType() == typeof(RuleTransition))
                {
                    if (calledRuleStack.Get(((RuleTransition)t).target.ruleIndex))
                    {
                        continue;
                    }
                    PredictionContext newContext = ctx.GetChild(((RuleTransition)t).followState.stateNumber
                                                                );
                    try
                    {
                        calledRuleStack.Set(((RuleTransition)t).target.ruleIndex);
                        Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds
                             , addEOF);
                    }
                    finally
                    {
                        calledRuleStack.Clear(((RuleTransition)t).target.ruleIndex);
                    }
                }
                else
                {
                    if (t is AbstractPredicateTransition)
                    {
                        if (seeThruPreds)
                        {
                            Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF
                                 );
                        }
                        else
                        {
                            look.Add(HitPred);
                        }
                    }
                    else
                    {
                        if (t.IsEpsilon)
                        {
                            Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF
                                 );
                        }
                        else
                        {
                            if (t.GetType() == typeof(WildcardTransition))
                            {
                                look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                            }
                            else
                            {
                                //				System.out.println("adding "+ t);
                                IntervalSet set = t.Label;
                                if (set != null)
                                {
                                    if (t is NotSetTransition)
                                    {
                                        set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType
                                                                            ));
                                    }
                                    look.AddAll(set);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Compute set of tokens that can follow
        /// <paramref name="s"/>
        /// in the ATN in the
        /// specified
        /// <paramref name="ctx"/>
        /// .
        /// <p/>
        /// If
        /// <paramref name="ctx"/>
        /// is
        /// <see cref="PredictionContext.EmptyLocal"/>
        /// and
        /// <paramref name="stopState"/>
        /// or the end of the rule containing
        /// <paramref name="s"/>
        /// is reached,
        /// <see cref="TokenConstants.EPSILON"/>
        /// is added to the result set. If
        /// <paramref name="ctx"/>
        /// is not
        /// <see cref="PredictionContext.EmptyLocal"/>
        /// and
        /// <paramref name="addEOF"/>
        /// is
        /// <see langword="true"/>
        /// and
        /// <paramref name="stopState"/>
        /// or the end of the outermost rule is reached,
        /// <see cref="TokenConstants.EOF"/>
        /// is added to the result set.
        /// </summary>
        /// <param name="s">the ATN state.</param>
        /// <param name="stopState">
        /// the ATN state to stop at. This can be a
        /// <see cref="BlockEndState"/>
        /// to detect epsilon paths through a closure.
        /// </param>
        /// <param name="ctx">
        /// The outer context, or
        /// <see cref="PredictionContext.EmptyLocal"/>
        /// if
        /// the outer context should not be used.
        /// </param>
        /// <param name="look">The result lookahead set.</param>
        /// <param name="lookBusy">
        /// A set used for preventing epsilon closures in the ATN
        /// from causing a stack overflow. Outside code should pass
        /// <c>new HashSet&lt;ATNConfig&gt;</c>
        /// for this argument.
        /// </param>
        /// <param name="calledRuleStack">
        /// A set used for preventing left recursion in the
        /// ATN from causing a stack overflow. Outside code should pass
        /// <c>new BitSet()</c>
        /// for this argument.
        /// </param>
        /// <param name="seeThruPreds">
        ///
        /// <see langword="true"/>
        /// to true semantic predicates as
        /// implicitly
        /// <see langword="true"/>
        /// and "see through them", otherwise
        /// <see langword="false"/>
        /// to treat semantic predicates as opaque and add
        /// <see cref="HitPred"/>
        /// to the
        /// result if one is encountered.
        /// </param>
        /// <param name="addEOF">
        /// Add
        /// <see cref="TokenConstants.EOF"/>
        /// to the result if the end of the
        /// outermost context is reached. This parameter has no effect if
        /// <paramref name="ctx"/>
        /// is
        /// <see cref="PredictionContext.EmptyLocal"/>
        /// .
        /// </param>
        protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext ctx, IntervalSet look, HashSet <ATNConfig> lookBusy, BitSet calledRuleStack, bool seeThruPreds, bool addEOF)
        {
            //		System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
            ATNConfig c = new ATNConfig(s, 0, ctx);

            if (!lookBusy.Add(c))
            {
                return;
            }
            if (s == stopState)
            {
                if (ctx == null)
                {
                    look.Add(TokenConstants.EPSILON);
                    return;
                }
                else if (ctx.IsEmpty && addEOF)
                {
                    look.Add(TokenConstants.EOF);
                    return;
                }
            }
            if (s is RuleStopState)
            {
                if (ctx == null)
                {
                    look.Add(TokenConstants.EPSILON);
                    return;
                }
                else if (ctx.IsEmpty && addEOF)
                {
                    look.Add(TokenConstants.EOF);
                    return;
                }
                if (ctx != PredictionContext.EMPTY)
                {
                    for (int i = 0; i < ctx.Size; i++)
                    {
                        ATNState returnState = atn.states[ctx.GetReturnState(i)];
                        bool     removed     = calledRuleStack.Get(returnState.ruleIndex);
                        try
                        {
                            calledRuleStack.Clear(returnState.ruleIndex);
                            Look(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                        }
                        finally
                        {
                            if (removed)
                            {
                                calledRuleStack.Set(returnState.ruleIndex);
                            }
                        }
                    }
                    return;
                }
            }
            int n = s.NumberOfTransitions;

            for (int i_1 = 0; i_1 < n; i_1++)
            {
                Transition t = s.Transition(i_1);
                if (t is RuleTransition)
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (calledRuleStack.Get(ruleTransition.ruleIndex))
                    {
                        continue;
                    }
                    PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber);
                    try
                    {
                        calledRuleStack.Set(ruleTransition.target.ruleIndex);
                        Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                    }
                    finally
                    {
                        calledRuleStack.Clear(ruleTransition.target.ruleIndex);
                    }
                }
                else
                {
                    if (t is AbstractPredicateTransition)
                    {
                        if (seeThruPreds)
                        {
                            Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                        }
                        else
                        {
                            look.Add(HitPred);
                        }
                    }
                    else
                    {
                        if (t.IsEpsilon)
                        {
                            Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                        }
                        else
                        {
                            if (t is WildcardTransition)
                            {
                                look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                            }
                            else
                            {
                                IntervalSet set = t.Label;
                                if (set != null)
                                {
                                    if (t is NotSetTransition)
                                    {
                                        set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                                    }
                                    look.AddAll(set);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
        public static PredictionContext GetCachedContext(PredictionContext context, PredictionContextCache contextCache, PredictionContext.IdentityHashMap visited)
        {
            if (context.IsEmpty)
            {
                return(context);
            }

            PredictionContext existing = visited.Get(context);

            if (existing != null)
            {
                return(existing);
            }

            existing = contextCache.Get(context);
            if (existing != null)
            {
                visited.Put(context, existing);
                return(existing);
            }

            bool changed = false;

            PredictionContext[] parents = new PredictionContext[context.Size];
            for (int i = 0; i < parents.Length; i++)
            {
                PredictionContext parent = GetCachedContext(context.GetParent(i), contextCache, visited);
                if (changed || parent != context.GetParent(i))
                {
                    if (!changed)
                    {
                        parents = new PredictionContext[context.Size];
                        for (int j = 0; j < context.Size; j++)
                        {
                            parents[j] = context.GetParent(j);
                        }

                        changed = true;
                    }

                    parents[i] = parent;
                }
            }

            if (!changed)
            {
                contextCache.Add(context);
                visited.Put(context, context);
                return(context);
            }

            PredictionContext updated;

            if (parents.Length == 0)
            {
                updated = EMPTY;
            }
            else if (parents.Length == 1)
            {
                updated = SingletonPredictionContext.Create(parents[0], context.GetReturnState(0));
            }
            else
            {
                ArrayPredictionContext arrayPredictionContext = (ArrayPredictionContext)context;
                updated = new ArrayPredictionContext(parents, arrayPredictionContext.returnStates);
            }

            contextCache.Add(updated);
            visited.Put(updated, updated);
            visited.Put(context, updated);

            return(updated);
        }