A tuple: (ATN state, predicted alt, syntactic, semantic context).
A tuple: (ATN state, predicted alt, syntactic, semantic context). The syntactic context is a graph-structured stack node whose path(s) to the root is the rule invocation(s) chain used to arrive at the state. The semantic context is the tree of semantic predicates encountered before reaching an ATN state.
예제 #1
0
        public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(PredictionContext context
                                                                  , PredictionContextCache contextCache)
        {
            PredictionContext appendedContext = Context.AppendContext(context, contextCache);

            Antlr4.Runtime.Atn.ATNConfig result = Transform(State, appendedContext);
            return(result);
        }
예제 #2
0
 protected internal ATNConfig(Antlr4.Runtime.Atn.ATNConfig c, ATNState state, PredictionContext
                              context)
 {
     this.state = state;
     this.altAndOuterContextDepth = c.altAndOuterContextDepth & unchecked ((int)(0x7FFFFFFF
                                                                                 ));
     this.context = context;
 }
예제 #3
0
 public virtual bool Equals(Antlr4.Runtime.Atn.ATNConfig other)
 {
     if (this == other)
     {
         return(true);
     }
     else
     {
         if (other == null)
         {
             return(false);
         }
     }
     return(this.State.stateNumber == other.State.stateNumber && this.Alt == other.Alt && this.ReachesIntoOuterContext == other.ReachesIntoOuterContext && this.Context.Equals(other.Context) && this.SemanticContext.Equals(other.SemanticContext) && this.PassedThroughNonGreedyDecision == other.PassedThroughNonGreedyDecision && EqualityComparer <LexerActionExecutor> .Default.Equals(this.ActionExecutor, other.ActionExecutor));
 }
예제 #4
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);
        }
예제 #5
0
 public virtual bool Equals(Antlr4.Runtime.Atn.ATNConfig other)
 {
     if (this == other)
     {
         return(true);
     }
     else
     {
         if (other == null)
         {
             return(false);
         }
     }
     return(this.State.stateNumber == other.State.stateNumber && this.Alt == other.Alt &&
            this.ReachesIntoOuterContext == other.ReachesIntoOuterContext && this.Context
            .Equals(other.Context) && this.SemanticContext.Equals(other.SemanticContext) &&
            this.ActionIndex == other.ActionIndex);
 }
예제 #6
0
        protected ATNConfigSet ComputeStartState(ATNState p,
											  RuleContext ctx,
											  bool fullCtx)
        {
            // always at least the implicit call to start rule
            PredictionContext initialContext = PredictionContext.FromRuleContext(atn, ctx);
            ATNConfigSet configs = new ATNConfigSet(fullCtx);

            for (int i = 0; i < p.NumberOfTransitions; i++)
            {
                ATNState target = p.Transition(i).target;
                ATNConfig c = new ATNConfig(target, i + 1, initialContext);
                HashSet<ATNConfig> closureBusy = new HashSet<ATNConfig>();
                Closure(c, configs, closureBusy, true, fullCtx, false);
            }

            return configs;
        }
예제 #7
0
        protected void ClosureCheckingStopState(ATNConfig config,
												ATNConfigSet configSet,
												HashSet<ATNConfig> closureBusy,
												bool collectPredicates,
												bool fullCtx,
												int depth,
												bool treatEofAsEpsilon)
        {
            if (debug)
                Console.WriteLine("closure(" + config.ToString(parser, true) + ")");

            if (config.state is RuleStopState)
            {
                // We hit rule end. If we have context info, use it
                // run thru all possible stack tops in ctx
                if (!config.context.IsEmpty)
                {
                    for (int i = 0; i < config.context.Size; i++)
                    {
                        if (config.context.GetReturnState(i) == PredictionContext.EMPTY_RETURN_STATE)
                        {
                            if (fullCtx)
                            {
                                configSet.Add(new ATNConfig(config, config.state, PredictionContext.EMPTY), mergeCache);
                                continue;
                            }
                            else {
                                // we have no context info, just chase follow links (if greedy)
                                if (debug) Console.WriteLine("FALLING off rule " +
                                                              GetRuleName(config.state.ruleIndex));
                                Closure_(config, configSet, closureBusy, collectPredicates,
                                         fullCtx, depth, treatEofAsEpsilon);
                            }
                            continue;
                        }
                        ATNState returnState = atn.states[config.context.GetReturnState(i)];
                        PredictionContext newContext = config.context.GetParent(i); // "pop" return state
                        ATNConfig c = new ATNConfig(returnState, config.alt, newContext, config.semanticContext);
                        // While we have context to pop back from, we may have
                        // gotten that context AFTER having falling off a rule.
                        // Make sure we track that we are now out of context.
                        //
                        // This assignment also propagates the
                        // isPrecedenceFilterSuppressed() value to the new
                        // configuration.
                        c.reachesIntoOuterContext = config.OuterContextDepth;
                        ClosureCheckingStopState(c, configSet, closureBusy, collectPredicates,
                                                 fullCtx, depth - 1, treatEofAsEpsilon);
                    }
                    return;
                }
                else if (fullCtx)
                {
                    // reached end of start rule
                    configSet.Add(config, mergeCache);
                    return;
                }
                else {
                    // else if we have no context info, just chase follow links (if greedy)
                    if (debug) Console.WriteLine("FALLING off rule " +
                                                  GetRuleName(config.state.ruleIndex));
                }
            }

            Closure_(config, configSet, closureBusy, collectPredicates,
                     fullCtx, depth, treatEofAsEpsilon);
        }
예제 #8
0
 protected internal override bool CanMerge(ATNConfig left, long leftKey, ATNConfig right)
 {
     return left.Equals(right);
 }
예제 #9
0
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig
             config, Transition t, ATNConfigSet configs, bool speculative)
        {
            ATNConfig c;
            switch (t.TransitionType)
            {
                case TransitionType.Rule:
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                    {
                        c = config.Transform(t.target);
                    }
                    else
                    {
                        PredictionContext newContext = config.Context.GetChild(ruleTransition.followState
                            .stateNumber);
                        c = config.Transform(t.target, newContext);
                    }
                    break;
                }

                case TransitionType.Precedence:
                {
                    throw new NotSupportedException("Precedence predicates are not supported in lexers."
                        );
                }

                case TransitionType.Predicate:
                {
                    PredicateTransition pt = (PredicateTransition)t;
                    configs.MarkExplicitSemanticContext();
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = config.Transform(t.target);
                    }
                    else
                    {
                        c = null;
                    }
                    break;
                }

                case TransitionType.Action:
                {
                    // ignore actions; just exec one per rule upon accept
                    c = config.Transform(t.target, ((ActionTransition)t).actionIndex);
                    break;
                }

                case TransitionType.Epsilon:
                {
                    c = config.Transform(t.target);
                    break;
                }

                default:
                {
                    c = null;
                    break;
                }
            }
            return c;
        }
예제 #10
0
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition t, ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;
            switch (t.TransitionType)
            {
                case TransitionType.Rule:
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                        c = config.Transform(t.target, newContext, true);
                    }
                    break;
                }

                case TransitionType.Precedence:
                {
                    throw new NotSupportedException("Precedence predicates are not supported in lexers.");
                }

                case TransitionType.Predicate:
                {
                    /*  Track traversing semantic predicates. If we traverse,
                    we cannot add a DFA state for this "reach" computation
                    because the DFA would not test the predicate again in the
                    future. Rather than creating collections of semantic predicates
                    like v3 and testing them on prediction, v4 will test them on the
                    fly all the time using the ATN not the DFA. This is slower but
                    semantically it's not used that often. One of the key elements to
                    this predicate mechanism is not adding DFA states that see
                    predicates immediately afterwards in the ATN. For example,
                    
                    a : ID {p1}? | ID {p2}? ;
                    
                    should create the start state for rule 'a' (to save start state
                    competition), but should not create target of ID state. The
                    collection of ATN states the following ID references includes
                    states reached by traversing predicates. Since this is when we
                    test them, we cannot cash the DFA state target of ID.
                    */
                    PredicateTransition pt = (PredicateTransition)t;
                    configs.MarkExplicitSemanticContext();
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        c = null;
                    }
                    break;
                }

                case TransitionType.Action:
                {
                    if (config.Context.HasEmpty)
                    {
                        // execute actions anywhere in the start rule for a token.
                        //
                        // TODO: if the entry rule is invoked recursively, some
                        // actions may be executed during the recursive call. The
                        // problem can appear when hasEmpty() is true but
                        // isEmpty() is false. In this case, the config needs to be
                        // split into two contexts - one with just the empty path
                        // and another with everything but the empty path.
                        // Unfortunately, the current algorithm does not allow
                        // getEpsilonTarget to return two configurations, so
                        // additional modifications are needed before we can support
                        // the split operation.
                        LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                        c = config.Transform(t.target, lexerActionExecutor, true);
                        break;
                    }
                    else
                    {
                        // ignore actions in referenced rules
                        c = config.Transform(t.target, true);
                        break;
                    }
                }

                case TransitionType.Epsilon:
                {
                    c = config.Transform(t.target, true);
                    break;
                }

                case TransitionType.Atom:
                case TransitionType.Range:
                case TransitionType.Set:
                {
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                        {
                            c = config.Transform(t.target, false);
                            break;
                        }
                    }
                    c = null;
                    break;
                }

                default:
                {
                    c = null;
                    break;
                }
            }
            return c;
        }
예제 #11
0
        protected internal virtual ATNConfig GetEpsilonTarget([NotNull] ICharStream input, [NotNull] ATNConfig config, [NotNull] Transition t, [NotNull] ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;

            switch (t.TransitionType)
            {
            case TransitionType.Rule:
            {
                RuleTransition ruleTransition = (RuleTransition)t;
                if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                {
                    c = config.Transform(t.target, true);
                }
                else
                {
                    PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                    c = config.Transform(t.target, newContext, true);
                }
                break;
            }

            case TransitionType.Precedence:
            {
                throw new NotSupportedException("Precedence predicates are not supported in lexers.");
            }

            case TransitionType.Predicate:
            {
                /*  Track traversing semantic predicates. If we traverse,
                 *  we cannot add a DFA state for this "reach" computation
                 *      because the DFA would not test the predicate again in the
                 *      future. Rather than creating collections of semantic predicates
                 *      like v3 and testing them on prediction, v4 will test them on the
                 *      fly all the time using the ATN not the DFA. This is slower but
                 *      semantically it's not used that often. One of the key elements to
                 *      this predicate mechanism is not adding DFA states that see
                 *      predicates immediately afterwards in the ATN. For example,
                 *
                 *      a : ID {p1}? | ID {p2}? ;
                 *
                 *      should create the start state for rule 'a' (to save start state
                 *      competition), but should not create target of ID state. The
                 *      collection of ATN states the following ID references includes
                 *      states reached by traversing predicates. Since this is when we
                 *      test them, we cannot cash the DFA state target of ID.
                 */
                PredicateTransition pt = (PredicateTransition)t;
                configs.MarkExplicitSemanticContext();
                if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                {
                    c = config.Transform(t.target, true);
                }
                else
                {
                    c = null;
                }
                break;
            }

            case TransitionType.Action:
            {
                if (config.Context.HasEmpty)
                {
                    // execute actions anywhere in the start rule for a token.
                    //
                    // TODO: if the entry rule is invoked recursively, some
                    // actions may be executed during the recursive call. The
                    // problem can appear when hasEmpty() is true but
                    // isEmpty() is false. In this case, the config needs to be
                    // split into two contexts - one with just the empty path
                    // and another with everything but the empty path.
                    // Unfortunately, the current algorithm does not allow
                    // getEpsilonTarget to return two configurations, so
                    // additional modifications are needed before we can support
                    // the split operation.
                    LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                    c = config.Transform(t.target, lexerActionExecutor, true);
                    break;
                }
                else
                {
                    // ignore actions in referenced rules
                    c = config.Transform(t.target, true);
                    break;
                }
            }

            case TransitionType.Epsilon:
            {
                c = config.Transform(t.target, true);
                break;
            }

            case TransitionType.Atom:
            case TransitionType.Range:
            case TransitionType.Set:
            {
                if (treatEofAsEpsilon)
                {
                    if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                    {
                        c = config.Transform(t.target, false);
                        break;
                    }
                }
                c = null;
                break;
            }

            default:
            {
                c = null;
                break;
            }
            }
            return(c);
        }
예제 #12
0
파일: ATNConfig.cs 프로젝트: KhaledSMQ/aml
 public ATNConfig(ATNConfig c, ATNState state,
                  PredictionContext context)
     : this(c, state, context, c.semanticContext)
 {
 }
 public ATNState GetReachableTargetHelper(ATNConfig source, Transition trans, int ttype)
 {
     return GetReachableTarget(source, trans, ttype);
 }
예제 #14
0
        protected ATNConfig RuleTransition(ATNConfig config, RuleTransition t)
        {
            if (debug)
            {
                Console.WriteLine("CALL rule " + GetRuleName(t.target.ruleIndex) +
                                   ", ctx=" + config.context);
            }

            ATNState returnState = t.followState;
            PredictionContext newContext =
                SingletonPredictionContext.Create(config.context, returnState.stateNumber);
            return new ATNConfig(config, t.target, newContext);
        }
예제 #15
0
 public ActionSemanticContextATNConfig(int actionIndex, SemanticContext semanticContext
                                       , ATNConfig c, ATNState state, PredictionContext context) : base(semanticContext
                                                                                                        , c, state, context)
 {
     this.actionIndex = actionIndex;
 }
예제 #16
0
파일: ATNConfig.cs 프로젝트: KhaledSMQ/aml
 public ATNConfig(ATNConfig c, ATNState state,
                  SemanticContext semanticContext)
     : this(c, state, c.context, semanticContext)
 {
 }
예제 #17
0
 public ActionSemanticContextATNConfig(int actionIndex, SemanticContext semanticContext
     , ATNConfig c, ATNState state, PredictionContext context) : base(semanticContext
     , c, state, context)
 {
     this.actionIndex = actionIndex;
 }
예제 #18
0
 protected internal ActionATNConfig(int actionIndex, ATNConfig c, ATNState state, 
     PredictionContext context) : base(c, state, context)
 {
     if (c.SemanticContext != SemanticContext.None)
     {
         throw new NotSupportedException();
     }
     this.actionIndex = actionIndex;
 }
예제 #19
0
 protected ATNConfig ActionTransition(ATNConfig config, ActionTransition t)
 {
     if (debug) Console.WriteLine("ACTION edge " + t.ruleIndex + ":" + t.actionIndex);
     return new ATNConfig(config, t.target);
 }
예제 #20
0
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition t, ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;
            switch (t.TransitionType)
            {
                case TransitionType.Rule:
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                        c = config.Transform(t.target, newContext, true);
                    }
                    break;
                }

                case TransitionType.Precedence:
                {
                    throw new NotSupportedException("Precedence predicates are not supported in lexers.");
                }

                case TransitionType.Predicate:
                {
                    PredicateTransition pt = (PredicateTransition)t;
                    configs.MarkExplicitSemanticContext();
                    if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                    {
                        c = config.Transform(t.target, true);
                    }
                    else
                    {
                        c = null;
                    }
                    break;
                }

                case TransitionType.Action:
                {
                    if (config.Context.HasEmpty)
                    {
                        // execute actions anywhere in the start rule for a token.
                        //
                        // TODO: if the entry rule is invoked recursively, some
                        // actions may be executed during the recursive call. The
                        // problem can appear when hasEmpty() is true but
                        // isEmpty() is false. In this case, the config needs to be
                        // split into two contexts - one with just the empty path
                        // and another with everything but the empty path.
                        // Unfortunately, the current algorithm does not allow
                        // getEpsilonTarget to return two configurations, so
                        // additional modifications are needed before we can support
                        // the split operation.
                        LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                        c = config.Transform(t.target, lexerActionExecutor, true);
                        break;
                    }
                    else
                    {
                        // ignore actions in referenced rules
                        c = config.Transform(t.target, true);
                        break;
                    }
                }

                case TransitionType.Epsilon:
                {
                    c = config.Transform(t.target, true);
                    break;
                }

                case TransitionType.Atom:
                case TransitionType.Range:
                case TransitionType.Set:
                {
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                        {
                            c = config.Transform(t.target, false);
                            break;
                        }
                    }
                    c = null;
                    break;
                }

                default:
                {
                    c = null;
                    break;
                }
            }
            return c;
        }
예제 #21
0
 private static bool CheckNonGreedyDecision(Antlr4.Runtime.Atn.ATNConfig source, ATNState target)
 {
     return(source.PassedThroughNonGreedyDecision || target is DecisionState && ((DecisionState)target).nonGreedy);
 }
예제 #22
0
파일: LL1Analyzer.cs 프로젝트: antlr/antlr4
 /// <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);
                         }
                     }
                 }
             }
         }
     }
 }
예제 #23
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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #24
0
 public SemanticContextATNConfig(Antlr4.Runtime.Atn.SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context)
     : base(c, state, context)
 {
     this.semanticContext = semanticContext;
 }
예제 #25
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;
 }
예제 #26
0
 protected internal ActionATNConfig(LexerActionExecutor lexerActionExecutor, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
     : base(c, state, context)
 {
     if (c.SemanticContext != SemanticContext.None)
     {
         throw new NotSupportedException();
     }
     this.lexerActionExecutor = lexerActionExecutor;
     this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
 }
예제 #27
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;
 }
예제 #28
0
 public ActionSemanticContextATNConfig(LexerActionExecutor lexerActionExecutor, SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
     : base(semanticContext, c, state, context)
 {
     this.lexerActionExecutor = lexerActionExecutor;
     this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
 }
예제 #29
0
 protected internal override long GetKey(ATNConfig e)
 {
     return e.GetHashCode();
 }
예제 #30
0
 public bool Add(ATNConfig config)
 {
     return(Add(config, null));
 }
예제 #31
0
        /* TODO: If we are doing predicates, there is no point in pursuing
             closure operations if we reach a DFA state that uniquely predicts
             alternative. We will not be caching that DFA state and it is a
             waste to pursue the closure. Might have to advance when we do
             ambig detection thought :(
              */
        protected void Closure(ATNConfig config,
							   ATNConfigSet configs,
							   HashSet<ATNConfig> closureBusy,
							   bool collectPredicates,
							   bool fullCtx,
							   bool treatEofAsEpsilon)
        {
            int initialDepth = 0;
            ClosureCheckingStopState(config, configs, closureBusy, collectPredicates,
                                     fullCtx,
                                     initialDepth, treatEofAsEpsilon);
        }
예제 #32
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([NotNull] ATNState s, [Nullable] ATNState stopState, [NotNull] PredictionContext ctx, [NotNull] IntervalSet look, [NotNull] HashSet <ATNConfig> lookBusy, [NotNull] 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)
                    {
                        if (addEOF)
                        {
                            look.Add(TokenConstants.Eof);
                        }
                        return;
                    }
                }
            }
            if (s is RuleStopState)
            {
                if (ctx.IsEmpty && !PredictionContext.IsEmptyLocal(ctx))
                {
                    if (addEOF)
                    {
                        look.Add(TokenConstants.Eof);
                    }
                    return;
                }
                bool removed = calledRuleStack.Get(s.ruleIndex);
                try
                {
                    calledRuleStack.Clear(s.ruleIndex);
                    for (int i = 0; i < ctx.Size; i++)
                    {
                        if (ctx.GetReturnState(i) == PredictionContext.EmptyFullStateKey)
                        {
                            continue;
                        }
                        ATNState returnState = atn.states[ctx.GetReturnState(i)];
                        //					System.out.println("popping back to "+retState);
                        Look(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                    }
                }
                finally
                {
                    if (removed)
                    {
                        calledRuleStack.Set(s.ruleIndex);
                    }
                }
            }
            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 = ctx.GetChild(ruleTransition.followState.stateNumber);
                    try
                    {
                        calledRuleStack.Set(ruleTransition.ruleIndex);
                        Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                    }
                    finally
                    {
                        calledRuleStack.Clear(ruleTransition.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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #33
0
        /** Do the actual work of walking epsilon edges */
        protected void Closure_(ATNConfig config,
								ATNConfigSet configs,
								HashSet<ATNConfig> closureBusy,
								bool collectPredicates,
								bool fullCtx,
								int depth,
								bool treatEofAsEpsilon)
        {
            ATNState p = config.state;
            // optimization
            if (!p.OnlyHasEpsilonTransitions)
            {
                configs.Add(config, mergeCache);
                // make sure to not return here, because EOF transitions can act as
                // both epsilon transitions and non-epsilon transitions.
                //            if ( debug ) Console.WriteLine("added config "+configs);
            }

            for (int i = 0; i < p.NumberOfTransitions; i++)
            {
                if (i == 0 && CanDropLoopEntryEdgeInLeftRecursiveRule(config)) continue;

                Transition t = p.Transition(i);
                bool continueCollecting =
                    !(t is ActionTransition) && collectPredicates;
                ATNConfig c = GetEpsilonTarget(config, t, continueCollecting,
                                               depth == 0, fullCtx, treatEofAsEpsilon);
                if (c != null)
                {
                    if (!t.IsEpsilon && !closureBusy.Add(c))
                    {
                        // avoid infinite recursion for EOF* and EOF+
                        continue;
                    }

                    int newDepth = depth;
                    if (config.state is RuleStopState)
                    {
                        // target fell off end of rule; mark resulting c as having dipped into outer context
                        // We can't get here if incoming config was rule stop and we had context
                        // track how far we dip into outer context.  Might
                        // come in handy and we avoid evaluating context dependent
                        // preds if this is > 0.

                        if (!closureBusy.Add(c))
                        {
                            // avoid infinite recursion for right-recursive rules
                            continue;
                        }

                        if (thisDfa != null && thisDfa.IsPrecedenceDfa)
                        {
                            int outermostPrecedenceReturn = ((EpsilonTransition)t).OutermostPrecedenceReturn;
                            if (outermostPrecedenceReturn == thisDfa.atnStartState.ruleIndex)
                            {
                                c.SetPrecedenceFilterSuppressed(true);
                            }
                        }

                        c.reachesIntoOuterContext++;
                        configs.dipsIntoOuterContext = true; // TODO: can remove? only care when we add to set per middle of this method
                        newDepth--;
                        if (debug)
                            Console.WriteLine("dips into outer ctx: " + c);
                    }
                    else if (t is RuleTransition)
                    {
                        // latch when newDepth goes negative - once we step out of the entry context we can't return
                        if (newDepth >= 0)
                        {
                            newDepth++;
                        }
                    }

                    ClosureCheckingStopState(c, configs, closureBusy, continueCollecting,
                                             fullCtx, newDepth, treatEofAsEpsilon);
                }
            }
        }
예제 #34
0
 public SemanticContextATNConfig(Antlr4.Runtime.Atn.SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context)
     : base(c, state, context)
 {
     this.semanticContext = semanticContext;
 }
예제 #35
0
        protected ATNConfig GetEpsilonTarget(ATNConfig config,
										  Transition t,
										  bool collectPredicates,
										  bool inContext,
										  bool fullCtx,
										  bool treatEofAsEpsilon)
        {
            switch (t.TransitionType)
            {
                case TransitionType.RULE:
                    return RuleTransition(config, (RuleTransition)t);

                case TransitionType.PRECEDENCE:
                    return PrecedenceTransition(config, (PrecedencePredicateTransition)t, collectPredicates, inContext, fullCtx);

                case TransitionType.PREDICATE:
                    return PredTransition(config, (PredicateTransition)t,
                                          collectPredicates,
                                          inContext,
                                          fullCtx);

                case TransitionType.ACTION:
                    return ActionTransition(config, (ActionTransition)t);

                case TransitionType.EPSILON:
                    return new ATNConfig(config, t.target);

                case TransitionType.ATOM:
                case TransitionType.RANGE:
                case TransitionType.SET:
                    // EOF transitions act like epsilon transitions after the first EOF
                    // transition is traversed
                    if (treatEofAsEpsilon)
                    {
                        if (t.Matches(TokenConstants.EOF, 0, 1))
                        {
                            return new ATNConfig(config, t.target);
                        }
                    }

                    return null;

                default:
                    return null;
            }
        }
예제 #36
0
 protected internal ActionATNConfig(LexerActionExecutor lexerActionExecutor, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
     : base(c, state, context)
 {
     if (c.SemanticContext != SemanticContext.None)
     {
         throw new NotSupportedException();
     }
     this.lexerActionExecutor            = lexerActionExecutor;
     this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
 }
예제 #37
0
        public ATNConfig PrecedenceTransition(ATNConfig config,
										PrecedencePredicateTransition pt,
										bool collectPredicates,
										bool inContext,
										bool fullCtx)
        {
            if (debug)
            {
                Console.WriteLine("PRED (collectPredicates=" + collectPredicates + ") " +
                        pt.precedence + ">=_p" +
                        ", ctx dependent=true");
                if (parser != null)
                {
                    Console.WriteLine("context surrounding pred is " +
                                       parser.GetRuleInvocationStack());
                }
            }

            ATNConfig c = null;
            if (collectPredicates && inContext)
            {
                if (fullCtx)
                {
                    // In full context mode, we can evaluate predicates on-the-fly
                    // during closure, which dramatically reduces the size of
                    // the config sets. It also obviates the need to test predicates
                    // later during conflict resolution.
                    int currentPosition = input.Index;
                    input.Seek(startIndex);
                    bool predSucceeds = EvalSemanticContext(pt.Predicate, context, config.alt, fullCtx);
                    input.Seek(currentPosition);
                    if (predSucceeds)
                    {
                        c = new ATNConfig(config, pt.target); // no pred context
                    }
                }
                else {
                    SemanticContext newSemCtx = SemanticContext.AndOp(config.semanticContext, pt.Predicate);
                    c = new ATNConfig(config, pt.target, newSemCtx);
                }
            }
            else {
                c = new ATNConfig(config, pt.target);
            }

            if (debug) Console.WriteLine("config from pred transition=" + c);
            return c;
        }
예제 #38
0
 public ActionSemanticContextATNConfig(LexerActionExecutor lexerActionExecutor, SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
     : base(semanticContext, c, state, context)
 {
     this.lexerActionExecutor            = lexerActionExecutor;
     this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
 }
예제 #39
0
        /** Implements first-edge (loop entry) elimination as an optimization
         *  during closure operations.  See antlr/antlr4#1398.
         *
         * The optimization is to avoid adding the loop entry config when
         * the exit path can only lead back to the same
         * StarLoopEntryState after popping context at the rule end state
         * (traversing only epsilon edges, so we're still in closure, in
         * this same rule).
         *
         * We need to detect any state that can reach loop entry on
         * epsilon w/o exiting rule. We don't have to look at FOLLOW
         * links, just ensure that all stack tops for config refer to key
         * states in LR rule.
         *
         * To verify we are in the right situation we must first check
         * closure is at a StarLoopEntryState generated during LR removal.
         * Then we check that each stack top of context is a return state
         * from one of these cases:
         *
         *   1. 'not' expr, '(' type ')' expr. The return state points at loop entry state
         *   2. expr op expr. The return state is the block end of internal block of (...)*
         *   3. 'between' expr 'and' expr. The return state of 2nd expr reference.
         *      That state points at block end of internal block of (...)*.
         *   4. expr '?' expr ':' expr. The return state points at block end,
         *      which points at loop entry state.
         *
         * If any is true for each stack top, then closure does not add a
         * config to the current config set for edge[0], the loop entry branch.
         *
         *  Conditions fail if any context for the current config is:
         *
         *   a. empty (we'd fall out of expr to do a global FOLLOW which could
         *      even be to some weird spot in expr) or,
         *   b. lies outside of expr or,
         *   c. lies within expr but at a state not the BlockEndState
         *   generated during LR removal
         *
         * Do we need to evaluate predicates ever in closure for this case?
         *
         * No. Predicates, including precedence predicates, are only
         * evaluated when computing a DFA start state. I.e., only before
         * the lookahead (but not parser) consumes a token.
         *
         * There are no epsilon edges allowed in LR rule alt blocks or in
         * the "primary" part (ID here). If closure is in
         * StarLoopEntryState any lookahead operation will have consumed a
         * token as there are no epsilon-paths that lead to
         * StarLoopEntryState. We do not have to evaluate predicates
         * therefore if we are in the generated StarLoopEntryState of a LR
         * rule. Note that when making a prediction starting at that
         * decision point, decision d=2, compute-start-state performs
         * closure starting at edges[0], edges[1] emanating from
         * StarLoopEntryState. That means it is not performing closure on
         * StarLoopEntryState during compute-start-state.
         *
         * How do we know this always gives same prediction answer?
         *
         * Without predicates, loop entry and exit paths are ambiguous
         * upon remaining input +b (in, say, a+b). Either paths lead to
         * valid parses. Closure can lead to consuming + immediately or by
         * falling out of this call to expr back into expr and loop back
         * again to StarLoopEntryState to match +b. In this special case,
         * we choose the more efficient path, which is to take the bypass
         * path.
         *
         * The lookahead language has not changed because closure chooses
         * one path over the other. Both paths lead to consuming the same
         * remaining input during a lookahead operation. If the next token
         * is an operator, lookahead will enter the choice block with
         * operators. If it is not, lookahead will exit expr. Same as if
         * closure had chosen to enter the choice block immediately.
         *
         * Closure is examining one config (some loopentrystate, some alt,
         * context) which means it is considering exactly one alt. Closure
         * always copies the same alt to any derived configs.
         *
         * How do we know this optimization doesn't mess up precedence in
         * our parse trees?
         *
         * Looking through expr from left edge of stat only has to confirm
         * that an input, say, a+b+c; begins with any valid interpretation
         * of an expression. The precedence actually doesn't matter when
         * making a decision in stat seeing through expr. It is only when
         * parsing rule expr that we must use the precedence to get the
         * right interpretation and, hence, parse tree.
         *
         * @since 4.6
         */
        protected bool CanDropLoopEntryEdgeInLeftRecursiveRule(ATNConfig config)
        {
            ATNState p = config.state;
            // First check to see if we are in StarLoopEntryState generated during
            // left-recursion elimination. For efficiency, also check if
            // the context has an empty stack case. If so, it would mean
            // global FOLLOW so we can't perform optimization
            if (p.StateType != StateType.StarLoopEntry ||
                !((StarLoopEntryState)p).isPrecedenceDecision || // Are we the special loop entry/exit state?
                 config.context.IsEmpty ||                      // If SLL wildcard
                 config.context.HasEmptyPath)
            {
                return false;
            }

            // Require all return states to return back to the same rule
            // that p is in.
            int numCtxs = config.context.Size;
            for (int i = 0; i < numCtxs; i++)
            { // for each stack context
                ATNState returnState = atn.states[config.context.GetReturnState(i)];
                if (returnState.ruleIndex != p.ruleIndex) return false;
            }

            BlockStartState decisionStartState = (BlockStartState)p.Transition(0).target;
            int blockEndStateNum = decisionStartState.endState.stateNumber;
            BlockEndState blockEndState = (BlockEndState)atn.states[blockEndStateNum];

            // Verify that the top of each stack context leads to loop entry/exit
            // state through epsilon edges and w/o leaving rule.
            for (int i = 0; i < numCtxs; i++)
            {                           // for each stack context
                int returnStateNumber = config.context.GetReturnState(i);
                ATNState returnState = atn.states[returnStateNumber];
                // all states must have single outgoing epsilon edge
                if (returnState.NumberOfTransitions != 1 ||
                    !returnState.Transition(0).IsEpsilon)
                {
                    return false;
                }
                // Look for prefix op case like 'not expr', (' type ')' expr
                ATNState returnStateTarget = returnState.Transition(0).target;
                if (returnState.StateType == StateType.BlockEnd && returnStateTarget == p)
                {
                    continue;
                }
                // Look for 'expr op expr' or case where expr's return state is block end
                // of (...)* internal block; the block end points to loop back
                // which points to p but we don't need to check that
                if (returnState == blockEndState)
                {
                    continue;
                }
                // Look for ternary expr ? expr : expr. The return state points at block end,
                // which points at loop entry state
                if (returnStateTarget == blockEndState)
                {
                    continue;
                }
                // Look for complex prefix 'between expr and expr' case where 2nd expr's
                // return state points at block end state of (...)* internal block
                if (returnStateTarget.StateType == StateType.BlockEnd &&
                     returnStateTarget.NumberOfTransitions == 1 &&
                     returnStateTarget.Transition(0).IsEpsilon &&
                     returnStateTarget.Transition(0).target == p)
                {
                    continue;
                }

                // anything else ain't conforming
                return false;
            }

            return true;
        }
예제 #40
0
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition t, ATNConfigSet configs, bool speculative, bool treatEofAsEpsilon)
        {
            ATNConfig c;

            switch (t.TransitionType)
            {
            case TransitionType.Rule:
            {
                RuleTransition ruleTransition = (RuleTransition)t;
                if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                {
                    c = config.Transform(t.target, true);
                }
                else
                {
                    PredictionContext newContext = config.Context.GetChild(ruleTransition.followState.stateNumber);
                    c = config.Transform(t.target, newContext, true);
                }
                break;
            }

            case TransitionType.Precedence:
            {
                throw new NotSupportedException("Precedence predicates are not supported in lexers.");
            }

            case TransitionType.Predicate:
            {
                PredicateTransition pt = (PredicateTransition)t;
                configs.MarkExplicitSemanticContext();
                if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                {
                    c = config.Transform(t.target, true);
                }
                else
                {
                    c = null;
                }
                break;
            }

            case TransitionType.Action:
            {
                if (config.Context.HasEmpty)
                {
                    // execute actions anywhere in the start rule for a token.
                    //
                    // TODO: if the entry rule is invoked recursively, some
                    // actions may be executed during the recursive call. The
                    // problem can appear when hasEmpty() is true but
                    // isEmpty() is false. In this case, the config needs to be
                    // split into two contexts - one with just the empty path
                    // and another with everything but the empty path.
                    // Unfortunately, the current algorithm does not allow
                    // getEpsilonTarget to return two configurations, so
                    // additional modifications are needed before we can support
                    // the split operation.
                    LexerActionExecutor lexerActionExecutor = LexerActionExecutor.Append(config.ActionExecutor, atn.lexerActions[((ActionTransition)t).actionIndex]);
                    c = config.Transform(t.target, lexerActionExecutor, true);
                    break;
                }
                else
                {
                    // ignore actions in referenced rules
                    c = config.Transform(t.target, true);
                    break;
                }
            }

            case TransitionType.Epsilon:
            {
                c = config.Transform(t.target, true);
                break;
            }

            case TransitionType.Atom:
            case TransitionType.Range:
            case TransitionType.Set:
            {
                if (treatEofAsEpsilon)
                {
                    if (t.Matches(IntStreamConstants.Eof, char.MinValue, char.MaxValue))
                    {
                        c = config.Transform(t.target, false);
                        break;
                    }
                }
                c = null;
                break;
            }

            default:
            {
                c = null;
                break;
            }
            }
            return(c);
        }
        protected override ATNState GetReachableTarget(ATNConfig source, Transition trans, int ttype)
        {
            if (ttype == AntlrV4.CaretToken.CaretTokenType)
            {
                ATNState target = null;
                AtomTransition atomTransition = trans as AtomTransition;
                if (atomTransition != null)
                {
                    if (GetWordlikeTokenTypes().Contains(atomTransition.label))
                        target = atomTransition.target;
                }
                else
                {
                    SetTransition setTransition = trans as SetTransition;
                    if (setTransition != null)
                    {
                        bool not = trans is NotSetTransition;
                        foreach (int t in GetWordlikeTokenTypes().ToArray())
                        {
                            if (!not && setTransition.set.Contains(t) || not && !setTransition.set.Contains(t))
                            {
                                target = setTransition.target;
                                break;
                            }
                        }
                    }
                    else
                    {
                        RangeTransition rangeTransition = trans as RangeTransition;
                        if (rangeTransition != null)
                        {
                            // TODO: there must be a better algorithm here
                            int[] wordlikeTokenTypes = GetWordlikeTokenTypes().ToArray();
                            int lowerBound = Array.BinarySearch(wordlikeTokenTypes, rangeTransition.from);
                            int upperBound = Array.BinarySearch(wordlikeTokenTypes, rangeTransition.to);
                            if (lowerBound >= 0 || upperBound >= 0 || lowerBound != upperBound)
                                target = rangeTransition.target;
                        }
                        else
                        {
                            WildcardTransition wildcardTransition = trans as WildcardTransition;
                            if (wildcardTransition != null)
                            {
                                target = trans.target;
                            }
                        }
                    }
                }

                if (_caretTransitions == null)
                    _caretTransitions = new Dictionary<ATNConfig, IList<Transition>>();

                IList<Transition> configTransitions;
                if (!_caretTransitions.TryGetValue(source, out configTransitions))
                {
                    configTransitions = new List<Transition>();
                    _caretTransitions[source] = configTransitions;
                }

                configTransitions.Add(trans);
                return target;
            }

            return base.GetReachableTarget(source, trans, ttype);
        }
예제 #42
0
 protected internal override long GetKey(ATNConfig e)
 {
     return(e.GetHashCode());
 }
예제 #43
0
 protected internal override bool CanMerge(ATNConfig left, long leftKey, ATNConfig right)
 {
     return(left.Equals(right));
 }
예제 #44
0
        protected internal virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig
                                                              config, Transition t, ATNConfigSet configs, bool speculative)
        {
            ATNConfig c;

            switch (t.TransitionType)
            {
            case TransitionType.Rule:
            {
                RuleTransition ruleTransition = (RuleTransition)t;
                if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.Context.HasEmpty)
                {
                    c = config.Transform(t.target);
                }
                else
                {
                    PredictionContext newContext = config.Context.GetChild(ruleTransition.followState
                                                                           .stateNumber);
                    c = config.Transform(t.target, newContext);
                }
                break;
            }

            case TransitionType.Precedence:
            {
                throw new NotSupportedException("Precedence predicates are not supported in lexers."
                                                );
            }

            case TransitionType.Predicate:
            {
                PredicateTransition pt = (PredicateTransition)t;
                configs.MarkExplicitSemanticContext();
                if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                {
                    c = config.Transform(t.target);
                }
                else
                {
                    c = null;
                }
                break;
            }

            case TransitionType.Action:
            {
                // ignore actions; just exec one per rule upon accept
                c = config.Transform(t.target, ((ActionTransition)t).actionIndex);
                break;
            }

            case TransitionType.Epsilon:
            {
                c = config.Transform(t.target);
                break;
            }

            default:
            {
                c = null;
                break;
            }
            }
            return(c);
        }