コード例 #1
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);
        }
コード例 #2
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);
        }
コード例 #3
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);
        }