TODO: this is old comment: A tree of semantic predicates from the grammar AST if label==SEMPRED.
TODO: this is old comment: A tree of semantic predicates from the grammar AST if label==SEMPRED. In the ATN, labels will always be exactly one predicate, but the DFA may have to combine a bunch of them as it collects predicates from multiple ATN configurations into a single DFA state.
Inheritance: AbstractPredicateTransition
Example #1
0
        protected ATNConfig PredTransition(ATNConfig config,
										PredicateTransition pt,
										bool collectPredicates,
										bool inContext,
										bool fullCtx)
        {
            if (debug)
            {
                Console.WriteLine("PRED (collectPredicates=" + collectPredicates + ") " +
                        pt.ruleIndex + ":" + pt.predIndex +
                        ", ctx dependent=" + pt.isCtxDependent);
                if (parser != null)
                {
                    Console.WriteLine("context surrounding pred is " +
                                       parser.GetRuleInvocationStack());
                }
            }

            ATNConfig c = null;
            if (collectPredicates &&
                 (!pt.isCtxDependent || (pt.isCtxDependent && 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;
        }
Example #2
0
        protected internal virtual Transition EdgeFactory(ATN atn, TransitionType type, int src, int trg, int arg1, int arg2, int arg3, IList<IntervalSet> sets)
        {
            ATNState target = atn.states[trg];
            switch (type)
            {
                case TransitionType.EPSILON:
                {
                    return new EpsilonTransition(target);
                }

                case TransitionType.RANGE:
                {
                    if (arg3 != 0)
                    {
                        return new RangeTransition(target, TokenConstants.EOF, arg2);
                    }
                    else
                    {
                        return new RangeTransition(target, arg1, arg2);
                    }
                }

                case TransitionType.RULE:
                {
                    RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3, target);
                    return rt;
                }

                case TransitionType.PREDICATE:
                {
                    PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
                    return pt;
                }

                case TransitionType.PRECEDENCE:
                {
                    return new PrecedencePredicateTransition(target, arg1);
                }

                case TransitionType.ATOM:
                {
                    if (arg3 != 0)
                    {
                        return new AtomTransition(target, TokenConstants.EOF);
                    }
                    else
                    {
                        return new AtomTransition(target, arg1);
                    }
                }

                case TransitionType.ACTION:
                {
                    ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
                    return a;
                }

                case TransitionType.SET:
                {
                    return new SetTransition(target, sets[arg1]);
                }

                case TransitionType.NOT_SET:
                {
                    return new NotSetTransition(target, sets[arg1]);
                }

                case TransitionType.WILDCARD:
                {
                    return new WildcardTransition(target);
                }
            }
            throw new ArgumentException("The specified transition type is not valid.");
        }
Example #3
0
        protected internal virtual Transition EdgeFactory(ATN atn, TransitionType type, int src, int trg, int arg1, int arg2, int arg3, IList <IntervalSet> sets)
        {
            ATNState target = atn.states[trg];

            switch (type)
            {
            case TransitionType.EPSILON:
            {
                return(new EpsilonTransition(target));
            }

            case TransitionType.RANGE:
            {
                if (arg3 != 0)
                {
                    return(new RangeTransition(target, TokenConstants.EOF, arg2));
                }
                else
                {
                    return(new RangeTransition(target, arg1, arg2));
                }
            }

            case TransitionType.RULE:
            {
                RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3, target);
                return(rt);
            }

            case TransitionType.PREDICATE:
            {
                PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
                return(pt);
            }

            case TransitionType.PRECEDENCE:
            {
                return(new PrecedencePredicateTransition(target, arg1));
            }

            case TransitionType.ATOM:
            {
                if (arg3 != 0)
                {
                    return(new AtomTransition(target, TokenConstants.EOF));
                }
                else
                {
                    return(new AtomTransition(target, arg1));
                }
            }

            case TransitionType.ACTION:
            {
                ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
                return(a);
            }

            case TransitionType.SET:
            {
                return(new SetTransition(target, sets[arg1]));
            }

            case TransitionType.NOT_SET:
            {
                return(new NotSetTransition(target, sets[arg1]));
            }

            case TransitionType.WILDCARD:
            {
                return(new WildcardTransition(target));
            }
            }
            throw new ArgumentException("The specified transition type is not valid.");
        }
Example #4
0
        protected internal virtual Transition EdgeFactory(ATN atn, TransitionType type, int src, int trg, int arg1, int arg2, int arg3, IList<IntervalSet> sets)
        {
            ATNState target = atn.states[trg];
            switch (type)
            {
                case TransitionType.Epsilon:
                {
                    return new EpsilonTransition(target);
                }

                case TransitionType.Range:
                {
                    if (arg3 != 0)
                    {
                        return new RangeTransition(target, TokenConstants.Eof, arg2);
                    }
                    else
                    {
                        return new RangeTransition(target, arg1, arg2);
                    }
                }

                case TransitionType.Rule:
                {
                    RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3, target);
                    return rt;
                }

                case TransitionType.Predicate:
                {
                    PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
                    return pt;
                }

                case TransitionType.Precedence:
                {
                    return new PrecedencePredicateTransition(target, arg1);
                }

                case TransitionType.Atom:
                {
                    if (arg3 != 0)
                    {
                        return new AtomTransition(target, TokenConstants.Eof);
                    }
                    else
                    {
                        return new AtomTransition(target, arg1);
                    }
                }

                case TransitionType.Action:
                {
                    ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
                    return a;
                }

                case TransitionType.Set:
                {
                    return new SetTransition(target, sets[arg1]);
                }

                case TransitionType.NotSet:
                {
                    return new NotSetTransition(target, sets[arg1]);
                }

                case TransitionType.Wildcard:
                {
                    return new WildcardTransition(target);
                }
            }
            throw new ArgumentException("The specified transition type is not valid.");
        }
Example #5
0
        // side-effect: can alter configs.hasSemanticContext

        protected LexerATNConfig GetEpsilonTarget(ICharStream input,
                                                  LexerATNConfig config,
                                                  Transition t,
                                                  ATNConfigSet configs,
                                                  bool speculative,
                                                  bool treatEofAsEpsilon)
        {
            LexerATNConfig c = null;

            switch (t.TransitionType)
            {
            case TransitionType.RULE:
                RuleTransition    ruleTransition = (RuleTransition)t;
                PredictionContext newContext     = new SingletonPredictionContext(config.context, ruleTransition.followState.stateNumber);
                c = new LexerATNConfig(config, t.target, newContext);
                break;

            case TransitionType.PRECEDENCE:
                throw new Exception("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;
                if (debug)
                {
                    Console.WriteLine("EVAL rule " + pt.ruleIndex + ":" + pt.predIndex);
                }
                configs.hasSemanticContext = true;
                if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
                {
                    c = new LexerATNConfig(config, t.target);
                }
                break;

            case TransitionType.ACTION:
                if (config.context == null || config.context.HasEmptyPath)
                {
                    // 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 hasEmptyPath() 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.getLexerActionExecutor(), atn.lexerActions[((ActionTransition)t).actionIndex]);
                    c = new LexerATNConfig(config, t.target, lexerActionExecutor);
                    break;
                }
                else
                {
                    // ignore actions in referenced rules
                    c = new LexerATNConfig(config, t.target);
                    break;
                }

            case TransitionType.EPSILON:
                c = new LexerATNConfig(config, t.target);
                break;

            case TransitionType.ATOM:
            case TransitionType.RANGE:
            case TransitionType.SET:
                if (treatEofAsEpsilon)
                {
                    if (t.Matches(IntStreamConstants.EOF, char.MinValue, char.MaxValue))
                    {
                        c = new LexerATNConfig(config, t.target);
                        break;
                    }
                }

                break;
            }

            return(c);
        }
Example #6
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);
        }
Example #7
0
        /// <summary>
        /// Serialize state descriptors, edge descriptors, and decision→state map
        /// into list of ints:
        /// grammar-type, (ANTLRParser.LEXER, ...)
        /// max token type,
        /// num states,
        /// state-0-type ruleIndex, state-1-type ruleIndex, ...
        /// </summary>
        /// <remarks>
        /// Serialize state descriptors, edge descriptors, and decision→state map
        /// into list of ints:
        /// grammar-type, (ANTLRParser.LEXER, ...)
        /// max token type,
        /// num states,
        /// state-0-type ruleIndex, state-1-type ruleIndex, ... state-i-type ruleIndex optional-arg ...
        /// num rules,
        /// rule-1-start-state rule-1-args, rule-2-start-state  rule-2-args, ...
        /// (args are token type,actionIndex in lexer else 0,0)
        /// num modes,
        /// mode-0-start-state, mode-1-start-state, ... (parser has 0 modes)
        /// num sets
        /// set-0-interval-count intervals, set-1-interval-count intervals, ...
        /// num total edges,
        /// src, trg, edge-type, edge arg1, optional edge arg2 (present always), ...
        /// num decisions,
        /// decision-0-start-state, decision-1-start-state, ...
        /// Convenient to pack into unsigned shorts to make as Java string.
        /// </remarks>
        public virtual List <int> Serialize()
        {
            List <int> data = new List <int>();

            data.Add(ATNDeserializer.SerializedVersion);
            SerializeUUID(data, ATNDeserializer.SerializedUuid);
            // convert grammar type to ATN const to avoid dependence on ANTLRParser
            data.Add((int)(atn.grammarType));
            data.Add(atn.maxTokenType);
            int nedges = 0;
            IDictionary <IntervalSet, int> setIndices = new Dictionary <IntervalSet, int>();
            IList <IntervalSet>            sets       = new List <IntervalSet>();
            // dump states, count edges and collect sets while doing so
            List <int> nonGreedyStates  = new List <int>();
            List <int> sllStates        = new List <int>();
            List <int> precedenceStates = new List <int>();

            data.Add(atn.states.Count);
            foreach (ATNState s in atn.states)
            {
                if (s == null)
                {
                    // might be optimized away
                    data.Add((int)(StateType.InvalidType));
                    continue;
                }
                StateType stateType = s.StateType;
                if (s is DecisionState)
                {
                    DecisionState decisionState = (DecisionState)s;
                    if (decisionState.nonGreedy)
                    {
                        nonGreedyStates.Add(s.stateNumber);
                    }
                    if (decisionState.sll)
                    {
                        sllStates.Add(s.stateNumber);
                    }
                }
                if (s is RuleStartState && ((RuleStartState)s).isPrecedenceRule)
                {
                    precedenceStates.Add(s.stateNumber);
                }
                data.Add((int)(stateType));
                if (s.ruleIndex == -1)
                {
                    data.Add(char.MaxValue);
                }
                else
                {
                    data.Add(s.ruleIndex);
                }
                if (s.StateType == StateType.LoopEnd)
                {
                    data.Add(((LoopEndState)s).loopBackState.stateNumber);
                }
                else
                {
                    if (s is BlockStartState)
                    {
                        data.Add(((BlockStartState)s).endState.stateNumber);
                    }
                }
                if (s.StateType != StateType.RuleStop)
                {
                    // the deserializer can trivially derive these edges, so there's no need to serialize them
                    nedges += s.NumberOfTransitions;
                }
                for (int i = 0; i < s.NumberOfTransitions; i++)
                {
                    Transition     t        = s.Transition(i);
                    TransitionType edgeType = t.TransitionType;
                    if (edgeType == TransitionType.Set || edgeType == TransitionType.NotSet)
                    {
                        SetTransition st = (SetTransition)t;
                        if (!setIndices.ContainsKey(st.set))
                        {
                            sets.Add(st.set);
                            setIndices[st.set] = sets.Count - 1;
                        }
                    }
                }
            }
            // non-greedy states
            data.Add(nonGreedyStates.Count);
            for (int i_1 = 0; i_1 < nonGreedyStates.Count; i_1++)
            {
                data.Add(nonGreedyStates[i_1]);
            }
            // SLL decisions
            data.Add(sllStates.Count);
            for (int i_2 = 0; i_2 < sllStates.Count; i_2++)
            {
                data.Add(sllStates[i_2]);
            }
            // precedence states
            data.Add(precedenceStates.Count);
            for (int i_3 = 0; i_3 < precedenceStates.Count; i_3++)
            {
                data.Add(precedenceStates[i_3]);
            }
            int nrules = atn.ruleToStartState.Length;

            data.Add(nrules);
            for (int r = 0; r < nrules; r++)
            {
                ATNState ruleStartState = atn.ruleToStartState[r];
                data.Add(ruleStartState.stateNumber);
                bool leftFactored = ruleNames[ruleStartState.ruleIndex].IndexOf(ATNSimulator.RuleVariantDelimiter) >= 0;
                data.Add(leftFactored ? 1 : 0);
                if (atn.grammarType == ATNType.Lexer)
                {
                    if (atn.ruleToTokenType[r] == TokenConstants.Eof)
                    {
                        data.Add(char.MaxValue);
                    }
                    else
                    {
                        data.Add(atn.ruleToTokenType[r]);
                    }
                }
            }
            int nmodes = atn.modeToStartState.Count;

            data.Add(nmodes);
            if (nmodes > 0)
            {
                foreach (ATNState modeStartState in atn.modeToStartState)
                {
                    data.Add(modeStartState.stateNumber);
                }
            }
            int nsets = sets.Count;

            data.Add(nsets);
            foreach (IntervalSet set in sets)
            {
                bool containsEof = set.Contains(TokenConstants.Eof);
                if (containsEof && set.GetIntervals()[0].b == TokenConstants.Eof)
                {
                    data.Add(set.GetIntervals().Count - 1);
                }
                else
                {
                    data.Add(set.GetIntervals().Count);
                }
                data.Add(containsEof ? 1 : 0);
                foreach (Interval I in set.GetIntervals())
                {
                    if (I.a == TokenConstants.Eof)
                    {
                        if (I.b == TokenConstants.Eof)
                        {
                            continue;
                        }
                        else
                        {
                            data.Add(0);
                        }
                    }
                    else
                    {
                        data.Add(I.a);
                    }
                    data.Add(I.b);
                }
            }
            data.Add(nedges);
            foreach (ATNState s_1 in atn.states)
            {
                if (s_1 == null)
                {
                    // might be optimized away
                    continue;
                }
                if (s_1.StateType == StateType.RuleStop)
                {
                    continue;
                }
                for (int i = 0; i < s_1.NumberOfTransitions; i++)
                {
                    Transition t = s_1.Transition(i);
                    if (atn.states[t.target.stateNumber] == null)
                    {
                        throw new InvalidOperationException("Cannot serialize a transition to a removed state.");
                    }
                    int            src      = s_1.stateNumber;
                    int            trg      = t.target.stateNumber;
                    TransitionType edgeType = t.TransitionType;
                    int            arg1     = 0;
                    int            arg2     = 0;
                    int            arg3     = 0;
                    switch (edgeType)
                    {
                    case TransitionType.Rule:
                    {
                        trg  = ((RuleTransition)t).followState.stateNumber;
                        arg1 = ((RuleTransition)t).target.stateNumber;
                        arg2 = ((RuleTransition)t).ruleIndex;
                        arg3 = ((RuleTransition)t).precedence;
                        break;
                    }

                    case TransitionType.Precedence:
                    {
                        PrecedencePredicateTransition ppt = (PrecedencePredicateTransition)t;
                        arg1 = ppt.precedence;
                        break;
                    }

                    case TransitionType.Predicate:
                    {
                        PredicateTransition pt = (PredicateTransition)t;
                        arg1 = pt.ruleIndex;
                        arg2 = pt.predIndex;
                        arg3 = pt.isCtxDependent ? 1 : 0;
                        break;
                    }

                    case TransitionType.Range:
                    {
                        arg1 = ((RangeTransition)t).from;
                        arg2 = ((RangeTransition)t).to;
                        if (arg1 == TokenConstants.Eof)
                        {
                            arg1 = 0;
                            arg3 = 1;
                        }
                        break;
                    }

                    case TransitionType.Atom:
                    {
                        arg1 = ((AtomTransition)t).label;
                        if (arg1 == TokenConstants.Eof)
                        {
                            arg1 = 0;
                            arg3 = 1;
                        }
                        break;
                    }

                    case TransitionType.Action:
                    {
                        ActionTransition at = (ActionTransition)t;
                        arg1 = at.ruleIndex;
                        arg2 = at.actionIndex;
                        if (arg2 == -1)
                        {
                            arg2 = unchecked ((int)(0xFFFF));
                        }
                        arg3 = at.isCtxDependent ? 1 : 0;
                        break;
                    }

                    case TransitionType.Set:
                    {
                        arg1 = setIndices[((SetTransition)t).set];
                        break;
                    }

                    case TransitionType.NotSet:
                    {
                        arg1 = setIndices[((SetTransition)t).set];
                        break;
                    }

                    case TransitionType.Wildcard:
                    {
                        break;
                    }
                    }
                    data.Add(src);
                    data.Add(trg);
                    data.Add((int)(edgeType));
                    data.Add(arg1);
                    data.Add(arg2);
                    data.Add(arg3);
                }
            }
            int ndecisions = atn.decisionToState.Count;

            data.Add(ndecisions);
            foreach (DecisionState decStartState in atn.decisionToState)
            {
                data.Add(decStartState.stateNumber);
            }
            //
            // LEXER ACTIONS
            //
            if (atn.grammarType == ATNType.Lexer)
            {
                data.Add(atn.lexerActions.Length);
                foreach (ILexerAction action in atn.lexerActions)
                {
                    data.Add((int)(action.ActionType));
                    switch (action.ActionType)
                    {
                    case LexerActionType.Channel:
                    {
                        int channel = ((LexerChannelAction)action).Channel;
                        data.Add(channel != -1 ? channel : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.Custom:
                    {
                        int ruleIndex   = ((LexerCustomAction)action).RuleIndex;
                        int actionIndex = ((LexerCustomAction)action).ActionIndex;
                        data.Add(ruleIndex != -1 ? ruleIndex : unchecked ((int)(0xFFFF)));
                        data.Add(actionIndex != -1 ? actionIndex : unchecked ((int)(0xFFFF)));
                        break;
                    }

                    case LexerActionType.Mode:
                    {
                        int mode = ((LexerModeAction)action).Mode;
                        data.Add(mode != -1 ? mode : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.More:
                    {
                        data.Add(0);
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.PopMode:
                    {
                        data.Add(0);
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.PushMode:
                    {
                        int mode = ((LexerPushModeAction)action).Mode;
                        data.Add(mode != -1 ? mode : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.Skip:
                    {
                        data.Add(0);
                        data.Add(0);
                        break;
                    }

                    case LexerActionType.Type:
                    {
                        int type = ((LexerTypeAction)action).Type;
                        data.Add(type != -1 ? type : unchecked ((int)(0xFFFF)));
                        data.Add(0);
                        break;
                    }

                    default:
                    {
                        string message = string.Format(CultureInfo.CurrentCulture, "The specified lexer action type {0} is not valid.", action.ActionType);
                        throw new ArgumentException(message);
                    }
                    }
                }
            }
            // don't adjust the first value since that's the version number
            for (int i_4 = 1; i_4 < data.Count; i_4++)
            {
                if (data[i_4] < char.MinValue || data[i_4] > char.MaxValue)
                {
                    throw new NotSupportedException("Serialized ATN data element " + data[i_4] + " element " + i_4 + " out of range " + (int)char.MinValue + ".." + (int)char.MaxValue);
                }
                int value = (data[i_4] + 2) & unchecked ((int)(0xFFFF));
                data[i_4] = value;
            }
            return(data);
        }
Example #8
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);
        }
Example #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);
        }