예제 #1
0
        protected ATNConfigSet ComputeStartState(ICharStream input,
                                                 ATNState p)
        {
            PredictionContext initialContext = PredictionContext.EMPTY;
            ATNConfigSet      configs        = new OrderedATNConfigSet();

            for (int i = 0; i < p.NumberOfTransitions; i++)
            {
                ATNState       target = p.Transition(i).target;
                LexerATNConfig c      = new LexerATNConfig(target, i + 1, initialContext);
                Closure(input, c, configs, false, false, false);
            }
            return(configs);
        }
예제 #2
0
        public static PredictionContext FromRuleContext(ATN atn, RuleContext outerContext)
        {
            if (outerContext == null)
            {
                outerContext = ParserRuleContext.EMPTY;
            }
            if (outerContext.Parent == null || outerContext == ParserRuleContext.EMPTY)
            {
                return(PredictionContext.EMPTY);
            }
            PredictionContext parent     = PredictionContext.FromRuleContext(atn, outerContext.Parent);
            ATNState          state      = atn.states[outerContext.invokingState];
            RuleTransition    transition = (RuleTransition)state.Transition(0);

            return(parent.GetChild(transition.followState.stateNumber));
        }
예제 #3
0
 /// <summary>
 /// Analyze the
 /// <see cref="StarLoopEntryState"/>
 /// states in the specified ATN to set
 /// the
 /// <see cref="StarLoopEntryState.isPrecedenceDecision"/>
 /// field to the
 /// correct value.
 /// </summary>
 /// <param name="atn">The ATN.</param>
 protected internal virtual void MarkPrecedenceDecisions(ATN atn)
 {
     foreach (ATNState state in atn.states)
     {
         if (!(state is StarLoopEntryState))
         {
             continue;
         }
         if (atn.ruleToStartState[state.ruleIndex].isPrecedenceRule)
         {
             ATNState maybeLoopEndState = state.Transition(state.NumberOfTransitions - 1).target;
             if (maybeLoopEndState is LoopEndState)
             {
                 if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.Transition(0).target is RuleStopState)
                 {
                     ((StarLoopEntryState)state).isPrecedenceDecision = true;
                 }
             }
         }
     }
 }
예제 #4
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.EMPTY"/>
        /// 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.EMPTY"/>
        /// 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.EMPTY"/>
        /// 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.EMPTY"/>
        /// .
        /// </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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
 protected internal virtual void GenerateRuleBypassTransitions(ATN atn)
 {
     atn.ruleToTokenType = new int[atn.ruleToStartState.Length];
     for (int i_10 = 0; i_10 < atn.ruleToStartState.Length; i_10++)
     {
         atn.ruleToTokenType[i_10] = atn.maxTokenType + i_10 + 1;
     }
     for (int i_13 = 0; i_13 < atn.ruleToStartState.Length; i_13++)
     {
         BasicBlockStartState bypassStart = new BasicBlockStartState();
         bypassStart.ruleIndex = i_13;
         atn.AddState(bypassStart);
         BlockEndState bypassStop = new BlockEndState();
         bypassStop.ruleIndex = i_13;
         atn.AddState(bypassStop);
         bypassStart.endState = bypassStop;
         atn.DefineDecisionState(bypassStart);
         bypassStop.startState = bypassStart;
         ATNState   endState;
         Transition excludeTransition = null;
         if (atn.ruleToStartState[i_13].isPrecedenceRule)
         {
             // wrap from the beginning of the rule to the StarLoopEntryState
             endState = null;
             foreach (ATNState state_3 in atn.states)
             {
                 if (state_3.ruleIndex != i_13)
                 {
                     continue;
                 }
                 if (!(state_3 is StarLoopEntryState))
                 {
                     continue;
                 }
                 ATNState maybeLoopEndState = state_3.Transition(state_3.NumberOfTransitions - 1).target;
                 if (!(maybeLoopEndState is LoopEndState))
                 {
                     continue;
                 }
                 if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.Transition(0).target is RuleStopState)
                 {
                     endState = state_3;
                     break;
                 }
             }
             if (endState == null)
             {
                 throw new NotSupportedException("Couldn't identify final state of the precedence rule prefix section.");
             }
             excludeTransition = ((StarLoopEntryState)endState).loopBackState.Transition(0);
         }
         else
         {
             endState = atn.ruleToStopState[i_13];
         }
         // all non-excluded transitions that currently target end state need to target blockEnd instead
         foreach (ATNState state_4 in atn.states)
         {
             foreach (Transition transition in state_4.transitions)
             {
                 if (transition == excludeTransition)
                 {
                     continue;
                 }
                 if (transition.target == endState)
                 {
                     transition.target = bypassStop;
                 }
             }
         }
         // all transitions leaving the rule start state need to leave blockStart instead
         while (atn.ruleToStartState[i_13].NumberOfTransitions > 0)
         {
             Transition transition = atn.ruleToStartState[i_13].Transition(atn.ruleToStartState[i_13].NumberOfTransitions - 1);
             atn.ruleToStartState[i_13].RemoveTransition(atn.ruleToStartState[i_13].NumberOfTransitions - 1);
             bypassStart.AddTransition(transition);
         }
         // link the new states
         atn.ruleToStartState[i_13].AddTransition(new EpsilonTransition(bypassStart));
         bypassStop.AddTransition(new EpsilonTransition(endState));
         ATNState matchState = new BasicState();
         atn.AddState(matchState);
         matchState.AddTransition(new AtomTransition(bypassStop, atn.ruleToTokenType[i_13]));
         bypassStart.AddTransition(new EpsilonTransition(matchState));
     }
     if (deserializationOptions.VerifyAtn)
     {
         // reverify after modification
         VerifyATN(atn);
     }
 }
예제 #6
0
        /**
         * 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}, all other (potentially reachable) states for
         * this rule would have a lower priority.
         *
         * @return {@code true} if an accept state is reached, otherwise
         * {@code false}.
         */
        protected bool Closure(ICharStream input, LexerATNConfig config, ATNConfigSet configs, bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon)
        {
            if (debug)
            {
                ConsoleWriteLine("closure(" + config.ToString(recog, true) + ")");
            }

            if (config.state is RuleStopState)
            {
                if (debug)
                {
                    if (recog != null)
                    {
                        ConsoleWriteLine("closure at " + recog.RuleNames[config.state.ruleIndex] + " rule stop " + config);
                    }
                    else
                    {
                        ConsoleWriteLine("closure at rule stop " + config);
                    }
                }

                if (config.context == null || config.context.HasEmptyPath)
                {
                    if (config.context == null || config.context.IsEmpty)
                    {
                        configs.Add(config);
                        return(true);
                    }
                    else
                    {
                        configs.Add(new LexerATNConfig(config, config.state, PredictionContext.EMPTY));
                        currentAltReachedAcceptState = true;
                    }
                }

                if (config.context != null && !config.context.IsEmpty)
                {
                    for (int i = 0; i < config.context.Size; i++)
                    {
                        if (config.context.GetReturnState(i) != PredictionContext.EMPTY_RETURN_STATE)
                        {
                            PredictionContext newContext  = config.context.GetParent(i);                            // "pop" return state
                            ATNState          returnState = atn.states[config.context.GetReturnState(i)];
                            LexerATNConfig    c           = new LexerATNConfig(config, returnState, newContext);
                            currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
                        }
                    }
                }

                return(currentAltReachedAcceptState);
            }

            // optimization
            if (!config.state.OnlyHasEpsilonTransitions)
            {
                if (!currentAltReachedAcceptState || !config.hasPassedThroughNonGreedyDecision())
                {
                    configs.Add(config);
                }
            }

            ATNState p = config.state;

            for (int i = 0; i < p.NumberOfTransitions; i++)
            {
                Transition     t = p.Transition(i);
                LexerATNConfig c = GetEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon);
                if (c != null)
                {
                    currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
                }
            }

            return(currentAltReachedAcceptState);
        }