示例#1
0
        public virtual IntervalSet GetExpectedTokens(int stateNumber, RuleContext context)
        {
            if (stateNumber < 0 || stateNumber >= states.Count)
            {
                throw new ArgumentException("Invalid state number.");
            }
            RuleContext ctx = context;

            ATNState    s         = states[stateNumber];
            IntervalSet following = NextTokens(s);

            if (!following.Contains(TokenConstants.EPSILON))
            {
                return(following);
            }
            IntervalSet expected = new IntervalSet();

            expected.AddAll(following);
            expected.Remove(TokenConstants.EPSILON);
            while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.EPSILON))
            {
                ATNState       invokingState = states[ctx.invokingState];
                RuleTransition rt            = (RuleTransition)invokingState.Transition(0);
                following = NextTokens(rt.followState);
                expected.AddAll(following);
                expected.Remove(TokenConstants.EPSILON);
                ctx = ctx.Parent;
            }
            if (following.Contains(TokenConstants.EPSILON))
            {
                expected.Add(TokenConstants.EOF);
            }
            return(expected);
        }
示例#2
0
 public SuggestionState(CaretToken caret, List <FollowList> expected)
 {
     Caret          = caret ?? throw new ArgumentNullException(nameof(caret));
     Expected       = expected ?? throw new ArgumentNullException(nameof(expected));
     ExpectedTokens = new IntervalSet();
     foreach (var item in Expected)
     {
         ExpectedTokens.AddAll(item.Tokens);
     }
 }
示例#3
0
        protected internal virtual IntervalSet GetErrorRecoverySet(Parser recognizer)
        {
            ATN atn = recognizer.Interpreter.atn;

            RuleContext ctx        = recognizer.RuleContext;
            IntervalSet recoverSet = new IntervalSet();

            while (ctx != null && ctx.invokingState >= 0)
            {
                // compute what follows who invoked us
                ATNState       invokingState = atn.states[ctx.invokingState];
                RuleTransition rt            = (RuleTransition)invokingState.Transition(0);
                IntervalSet    follow        = atn.NextTokens(rt.followState);
                recoverSet.AddAll(follow);
                ctx = ctx.Parent;
            }
            recoverSet.Remove(TokenConstants.Epsilon);
            //		System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
            return(recoverSet);
        }
示例#4
0
        public IntervalSet Compute(Parser parser, CommonTokenStream token_stream, int line, int col)
        {
            _input        = new List <IToken>();
            _parser       = parser;
            _token_stream = token_stream;
            _stop_states  = new HashSet <ATNState>();
            foreach (var s in parser.Atn.ruleToStopState.Select(t => parser.Atn.states[t.stateNumber]))
            {
                _stop_states.Add(s);
            }
            _start_states = new HashSet <ATNState>();
            foreach (var s in parser.Atn.ruleToStartState.Select(t => parser.Atn.states[t.stateNumber]))
            {
                _start_states.Add(s);
            }
            var currentIndex = _token_stream.Index;

            _token_stream.Seek(0);
            var offset = 1;

            while (true)
            {
                var token = _token_stream.LT(offset++);
                _input.Add(token);
                _cursor = token.TokenIndex;
                if (token.Type == TokenConstants.EOF)
                {
                    break;
                }
                if (token.Line >= line && token.Column >= col)
                {
                    break;
                }
            }
            _token_stream.Seek(currentIndex);

            List <List <Edge> > all_parses = EnterState(new Edge()
            {
                _index = 0,
                _index_at_transition = 0,
                _to   = _parser.Atn.states[0],
                _type = TransitionType.EPSILON
            });

            // Remove last token on input.
            _input.RemoveAt(_input.Count - 1);
            // Eliminate all paths that don't consume all input.
            List <List <Edge> > temp = new List <List <Edge> >();

            if (all_parses != null)
            {
                foreach (var p in all_parses)
                {
                    //System.Console.Error.WriteLine(PrintSingle(p));
                    if (Validate(p, _input))
                    {
                        temp.Add(p);
                    }
                }
            }
            all_parses = temp;
            if (all_parses != null && this._log_closure)
            {
                foreach (var p in all_parses)
                {
                    System.Console.Error.WriteLine("Path " + PrintSingle(p));
                }
            }
            var result = new IntervalSet();

            if (all_parses != null)
            {
                foreach (var p in all_parses)
                {
                    HashSet <ATNState> set = ComputeSingle(p);
                    if (this._log_closure)
                    {
                        System.Console.Error.WriteLine("All states for path "
                                                       + String.Join(" ", set.ToList()));
                    }
                    foreach (var s in set)
                    {
                        foreach (var t in s.TransitionsArray)
                        {
                            switch (t.TransitionType)
                            {
                            case TransitionType.RULE:
                                break;

                            case TransitionType.PREDICATE:
                                break;

                            case TransitionType.WILDCARD:
                                break;

                            default:
                                if (!t.IsEpsilon)
                                {
                                    result.AddAll(t.Label);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            return(result);
        }
示例#5
0
        private static int OptimizeSets(ATN atn, bool preserveOrder)
        {
            if (preserveOrder)
            {
                // this optimization currently doesn't preserve edge order.
                return(0);
            }
            int removedPaths = 0;
            IList <DecisionState> decisions = atn.decisionToState;

            foreach (DecisionState decision in decisions)
            {
                IntervalSet setTransitions = new IntervalSet();
                for (int i = 0; i < decision.NumberOfOptimizedTransitions; i++)
                {
                    Transition epsTransition = decision.GetOptimizedTransition(i);
                    if (!(epsTransition is EpsilonTransition))
                    {
                        continue;
                    }
                    if (epsTransition.target.NumberOfOptimizedTransitions != 1)
                    {
                        continue;
                    }
                    Transition transition = epsTransition.target.GetOptimizedTransition(0);
                    if (!(transition.target is BlockEndState))
                    {
                        continue;
                    }
                    if (transition is NotSetTransition)
                    {
                        // TODO: not yet implemented
                        continue;
                    }
                    if (transition is AtomTransition || transition is RangeTransition || transition is SetTransition)
                    {
                        setTransitions.Add(i);
                    }
                }
                if (setTransitions.Count <= 1)
                {
                    continue;
                }
                IList <Transition> optimizedTransitions = new List <Transition>();
                for (int i_1 = 0; i_1 < decision.NumberOfOptimizedTransitions; i_1++)
                {
                    if (!setTransitions.Contains(i_1))
                    {
                        optimizedTransitions.Add(decision.GetOptimizedTransition(i_1));
                    }
                }
                ATNState    blockEndState = decision.GetOptimizedTransition(setTransitions.MinElement).target.GetOptimizedTransition(0).target;
                IntervalSet matchSet      = new IntervalSet();
                for (int i_2 = 0; i_2 < setTransitions.GetIntervals().Count; i_2++)
                {
                    Interval interval = setTransitions.GetIntervals()[i_2];
                    for (int j = interval.a; j <= interval.b; j++)
                    {
                        Transition matchTransition = decision.GetOptimizedTransition(j).target.GetOptimizedTransition(0);
                        if (matchTransition is NotSetTransition)
                        {
                            throw new NotSupportedException("Not yet implemented.");
                        }
                        else
                        {
                            matchSet.AddAll(matchTransition.Label);
                        }
                    }
                }
                Transition newTransition;
                if (matchSet.GetIntervals().Count == 1)
                {
                    if (matchSet.Count == 1)
                    {
                        newTransition = new AtomTransition(blockEndState, matchSet.MinElement);
                    }
                    else
                    {
                        Interval matchInterval = matchSet.GetIntervals()[0];
                        newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval.b);
                    }
                }
                else
                {
                    newTransition = new SetTransition(blockEndState, matchSet);
                }
                ATNState setOptimizedState = new BasicState();
                setOptimizedState.SetRuleIndex(decision.ruleIndex);
                atn.AddState(setOptimizedState);
                setOptimizedState.AddTransition(newTransition);
                optimizedTransitions.Add(new EpsilonTransition(setOptimizedState));
                removedPaths += decision.NumberOfOptimizedTransitions - optimizedTransitions.Count;
                if (decision.IsOptimized)
                {
                    while (decision.NumberOfOptimizedTransitions > 0)
                    {
                        decision.RemoveOptimizedTransition(decision.NumberOfOptimizedTransitions - 1);
                    }
                }
                foreach (Transition transition_1 in optimizedTransitions)
                {
                    decision.AddOptimizedTransition(transition_1);
                }
            }
            return(removedPaths);
        }
示例#6
0
        public IntervalSet Compute(Parser parser, CommonTokenStream token_stream, int line, int col)
        {
            _input        = new List <IToken>();
            _parser       = parser;
            _token_stream = token_stream;
            _stop_states  = new HashSet <ATNState>();
            foreach (var s in parser.Atn.ruleToStopState.Select(t => parser.Atn.states[t.stateNumber]))
            {
                _stop_states.Add(s);
            }
            _start_states = new HashSet <ATNState>();
            foreach (var s in parser.Atn.ruleToStartState.Select(t => parser.Atn.states[t.stateNumber]))
            {
                _start_states.Add(s);
            }
            var currentIndex = _token_stream.Index;

            _token_stream.Seek(0);
            var offset = 1;

            while (true)
            {
                var token = _token_stream.LT(offset++);
                _input.Add(token);
                _cursor = token.TokenIndex;
                if (token.Type == TokenConstants.EOF)
                {
                    break;
                }
                if (token.Line >= line && token.Column >= col)
                {
                    break;
                }
            }

            var all_parses = EnterState(null);
            var result     = new IntervalSet();

            if (all_parses != null)
            {
                foreach (var p in all_parses)
                {
                    HashSet <ATNState> set = ComputeSingle(p);
                    if (this._log_closure)
                    {
                        System.Console.Error.WriteLine("All states for path "
                                                       + String.Join(" ", set.ToList()));
                    }
                    foreach (var s in set)
                    {
                        foreach (var t in s.TransitionsArray)
                        {
                            switch (t.TransitionType)
                            {
                            case TransitionType.RULE:
                                break;

                            case TransitionType.PREDICATE:
                                break;

                            case TransitionType.WILDCARD:
                                break;

                            default:
                                if (!t.IsEpsilon)
                                {
                                    result.AddAll(t.Label);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            return(result);
        }
示例#7
0
        /// <summary>
        /// Walks the ATN for a single rule only. It returns the token stream position for each path that could be matched in this rule.
        /// The result can be empty in case we hit only non-epsilon transitions that didn't match the current input or if we
        /// hit the caret position.
        /// </summary>
        private ISet <int> ProcessRule(ATNState startState, int tokenIndex, LinkedList <int> callStack, string indentation)
        {
            // Start with rule specific handling before going into the ATN walk.

            // Check first if we've taken this path with the same input before.
            if (!this.shortcutMap.TryGetValue(startState.ruleIndex, out var positionMap))
            {
                positionMap = new Dictionary <int, ISet <int> >();
                this.shortcutMap[startState.ruleIndex] = positionMap;
            }
            else
            {
                if (positionMap.ContainsKey(tokenIndex))
                {
                    return(positionMap[tokenIndex]);
                }
            }

            var result = new HashSet <int>();

            // For rule start states we determine and cache the follow set, which gives us 3 advantages:
            // 1) We can quickly check if a symbol would be matched when we follow that rule. We can so check in advance
            //    and can save us all the intermediate steps if there is no match.
            // 2) We'll have all symbols that are collectable already together when we are at the caret when entering a rule.
            // 3) We get this lookup for free with any 2nd or further visit of the same rule, which often happens
            //    in non trivial grammars, especially with (recursive) expressions and of course when invoking code completion
            //    multiple times.
            if (!this.followSetsByATN.TryGetValue(this.parser.GetType().Name, out var setsPerState))
            {
                setsPerState = new FollowSetsPerState();
                this.followSetsByATN[this.parser.GetType().Name] = setsPerState;
            }

            if (!setsPerState.TryGetValue(startState.stateNumber, out var followSets))
            {
                followSets = new FollowSetsHolder();
                setsPerState[startState.stateNumber] = followSets;

                var stop = this.atn.ruleToStopState[startState.ruleIndex];
                followSets.Sets = this.DetermineFollowSets(startState, stop).ToList();

                // Sets are split by path to allow translating them to preferred rules. But for quick hit tests
                // it is also useful to have a set with all symbols combined.
                var combined = new IntervalSet();
                foreach (var set in followSets.Sets)
                {
                    combined.AddAll(set.Intervals);
                }
                followSets.Combined = combined;
            }

            callStack.AddLast(startState.ruleIndex);
            var currentSymbol = this.tokens[tokenIndex].Type;

            if (tokenIndex >= this.tokens.Count - 1)
            {
                // At caret?
                if (this.preferredRules.Contains(startState.ruleIndex))
                {
                    // No need to go deeper when collecting entries and we reach a rule that we want to collect anyway.
                    this.TranslateToRuleIndex(callStack.ToList());
                }
                else
                {
                    // Convert all follow sets to either single symbols or their associated preferred rule and add
                    // the result to our candidates list.
                    foreach (var set in followSets.Sets)
                    {
                        var fullPath = new LinkedList <int>(callStack);
                        foreach (var item in set.Path)
                        {
                            fullPath.AddLast(item);
                        }

                        if (!this.TranslateToRuleIndex(fullPath.ToList()))
                        {
                            foreach (var symbol in set.Intervals.ToList())
                            {
                                if (!this.ignoredTokens.Contains(symbol))
                                {
                                    if (!this.candidates.Tokens.ContainsKey(symbol))
                                    {
                                        // Following is empty if there is more than one entry in the set.
                                        this.candidates.Tokens[symbol] = set.Following;
                                    }
                                    else
                                    {
                                        // More than one following list for the same symbol.
                                        if (!this.candidates.Tokens[symbol].SequenceEqual(set.Following))
                                        {
                                            this.candidates.Tokens[symbol] = new List <int>();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                callStack.RemoveLast();
                return(result);
            }
            else
            {
                // Process the rule if we either could pass it without consuming anything (epsilon transition)
                // or if the current input symbol will be matched somewhere after this entry point.
                // Otherwise stop here.
                if (!followSets.Combined.Contains(TokenConstants.Epsilon) && !followSets.Combined.Contains(currentSymbol))
                {
                    callStack.RemoveLast();
                    return(result);
                }
            }

            // The current state execution pipeline contains all yet-to-be-processed ATN states in this rule.
            // For each such state we store the token index + a list of rules that lead to it.
            var statePipeline = new LinkedList <PipelineEntry>();

            // Bootstrap the pipeline.
            statePipeline.AddLast(new PipelineEntry(startState, tokenIndex));

            PipelineEntry currentEntry;

            while (statePipeline.Count() > 0)
            {
                currentEntry = statePipeline.Last();
                statePipeline.RemoveLast();
                ++this.statesProcessed;

                currentSymbol = this.tokens[currentEntry.TokenIndex].Type;

                var atCaret = currentEntry.TokenIndex >= this.tokens.Count - 1;

                switch (currentEntry.State.StateType)
                {
                // Happens only for the first state in this rule, not subrules.
                case StateType.RuleStart:
                    indentation += "  ";
                    break;

                // Record the token index we are at, to report it to the caller.
                case StateType.RuleStop:
                    result.Add(currentEntry.TokenIndex);
                    continue;

                default:
                    break;
                }

                var transitions = currentEntry.State.Transitions;
                foreach (var transition in transitions)
                {
                    switch (transition.TransitionType)
                    {
                    case TransitionType.Rule:
                    {
                        var endStatus = this.ProcessRule(transition.target, currentEntry.TokenIndex, callStack, indentation);
                        foreach (var position in endStatus)
                        {
                            statePipeline.AddLast(new PipelineEntry(((RuleTransition)transition).followState, position));
                        }
                        break;
                    }

                    case TransitionType.Predicate:
                    {
                        if (this.CheckPredicate((PredicateTransition)transition))
                        {
                            statePipeline.AddLast(new PipelineEntry(transition.target, currentEntry.TokenIndex));
                        }
                        break;
                    }

                    case TransitionType.Wildcard:
                    {
                        if (atCaret)
                        {
                            if (!this.TranslateToRuleIndex(callStack.ToList()))
                            {
                                foreach (var token in IntervalSet.Of(TokenConstants.MinUserTokenType, this.atn.maxTokenType).ToList())
                                {
                                    if (!this.ignoredTokens.Contains(token))
                                    {
                                        this.candidates.Tokens[token] = new List <int>();
                                    }
                                }
                            }
                        }
                        else
                        {
                            statePipeline.AddLast(new PipelineEntry(transition.target, currentEntry.TokenIndex + 1));
                        }
                        break;
                    }

                    default:
                    {
                        if (transition.IsEpsilon)
                        {
                            // Jump over simple states with a single outgoing epsilon transition.
                            statePipeline.AddLast(new PipelineEntry(transition.target, currentEntry.TokenIndex));
                            continue;
                        }

                        var set = transition.Label;
                        if (set != null && set.Count > 0)
                        {
                            if (transition.TransitionType == TransitionType.NotSet)
                            {
                                set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, this.atn.maxTokenType));
                            }

                            if (atCaret)
                            {
                                if (!this.TranslateToRuleIndex(callStack.ToList()))
                                {
                                    var list           = set.ToList();
                                    var isAddFollowing = list.Count == 1;

                                    foreach (var symbol in list)
                                    {
                                        if (!this.ignoredTokens.Contains(symbol))
                                        {
                                            if (isAddFollowing)
                                            {
                                                this.candidates.Tokens[symbol] = this.GetFollowingTokens(transition);
                                            }
                                            else
                                            {
                                                this.candidates.Tokens[symbol] = new List <int>();
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (set.Contains(currentSymbol))
                                {
                                    statePipeline.AddLast(new PipelineEntry(transition.target, currentEntry.TokenIndex + 1));
                                }
                            }
                        }
                    }
                    break;
                    }
                }
            }

            callStack.RemoveLast();

            // Cache the result, for later lookup to avoid duplicate walks.
            positionMap[tokenIndex] = result;

            return(result);
        }
示例#8
0
        /// <summary>
        /// Compute set of tokens that can follow
        /// <code>s</code>
        /// in the ATN in the
        /// specified
        /// <code>ctx</code>
        /// .
        /// <p/>
        /// If
        /// <code>ctx</code>
        /// is
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// and
        /// <code>stopState</code>
        /// or the end of the rule containing
        /// <code>s</code>
        /// is reached,
        /// <see cref="TokenConstants.Epsilon"/>
        /// is added to the result set. If
        /// <code>ctx</code>
        /// is not
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// and
        /// <code>addEOF</code>
        /// is
        /// <code>true</code>
        /// and
        /// <code>stopState</code>
        /// or the end of the outermost rule is reached,
        /// <see cref="TokenConstants.Eof"/>
        /// is added to the result set.
        /// </summary>
        /// <param name="s">the ATN state.</param>
        /// <param name="stopState">
        /// the ATN state to stop at. This can be a
        /// <see cref="BlockEndState">BlockEndState</see>
        /// to detect epsilon paths through a closure.
        /// </param>
        /// <param name="ctx">
        /// The outer context, or
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// if
        /// the outer context should not be used.
        /// </param>
        /// <param name="look">The result lookahead set.</param>
        /// <param name="lookBusy">
        /// A set used for preventing epsilon closures in the ATN
        /// from causing a stack overflow. Outside code should pass
        /// <code>new HashSet&lt;ATNConfig&gt;</code>
        /// for this argument.
        /// </param>
        /// <param name="calledRuleStack">
        /// A set used for preventing left recursion in the
        /// ATN from causing a stack overflow. Outside code should pass
        /// <code>new BitSet()</code>
        /// for this argument.
        /// </param>
        /// <param name="seeThruPreds">
        ///
        /// <code>true</code>
        /// to true semantic predicates as
        /// implicitly
        /// <code>true</code>
        /// and "see through them", otherwise
        /// <code>false</code>
        /// to treat semantic predicates as opaque and add
        /// <see cref="HitPred">HitPred</see>
        /// to the
        /// result if one is encountered.
        /// </param>
        /// <param name="addEOF">
        /// Add
        /// <see cref="TokenConstants.Eof"/>
        /// to the result if the end of the
        /// outermost context is reached. This parameter has no effect if
        /// <code>ctx</code>
        /// is
        /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
        /// .
        /// </param>
        protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext
                                             ctx, IntervalSet look, HashSet <ATNConfig> lookBusy, BitSet calledRuleStack,
                                             bool seeThruPreds, bool addEOF)
        {
            //		System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
            ATNConfig c = ATNConfig.Create(s, 0, ctx);

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

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

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

            for (int i_1 = 0; i_1 < n; i_1++)
            {
                Transition t = s.Transition(i_1);
                if (t is RuleTransition)
                {
                    RuleTransition ruleTransition = (RuleTransition)t;
                    if (calledRuleStack.Get(ruleTransition.ruleIndex))
                    {
                        continue;
                    }
                    PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber);
                    try
                    {
                        calledRuleStack.Set(ruleTransition.target.ruleIndex);
                        Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                    }
                    finally
                    {
                        calledRuleStack.Clear(ruleTransition.target.ruleIndex);
                    }
                }
                else
                {
                    if (t is AbstractPredicateTransition)
                    {
                        if (seeThruPreds)
                        {
                            Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                        }
                        else
                        {
                            look.Add(HitPred);
                        }
                    }
                    else
                    {
                        if (t.IsEpsilon)
                        {
                            Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                        }
                        else
                        {
                            if (t is WildcardTransition)
                            {
                                look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                            }
                            else
                            {
                                IntervalSet set = t.Label;
                                if (set != null)
                                {
                                    if (t is NotSetTransition)
                                    {
                                        set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                                    }
                                    look.AddAll(set);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#10
0
        public IntervalSet Compute(Parser parser, CommonTokenStream token_stream)
        {
            _input        = new List <IToken>();
            _parser       = parser;
            _token_stream = token_stream;
            //_cursor = _token_stream.GetTokens().Select(t => t.Text == "." ? t.TokenIndex : 0).Max();
            _stop_states = new HashSet <ATNState>();
            foreach (ATNState s in parser.Atn.ruleToStopState.Select(t => parser.Atn.states[t.stateNumber]))
            {
                _stop_states.Add(s);
            }
            _start_states = new HashSet <ATNState>();
            foreach (ATNState s in parser.Atn.ruleToStartState.Select(t => parser.Atn.states[t.stateNumber]))
            {
                _start_states.Add(s);
            }
            int currentIndex = _token_stream.Index;

            _token_stream.Seek(0);
            int offset = 1;

            while (true)
            {
                IToken token = _token_stream.LT(offset++);
                _input.Add(token);
                if (token.Type == TokenConstants.EOF)
                {
                    break;
                }
                _cursor = token.TokenIndex;
            }
            List <List <Edge> > all_parses = EnterState(null);

            IntervalSet result = new IntervalSet();

            foreach (List <Edge> p in all_parses)
            {
                HashSet <ATNState> set = ComputeSingle(p);
                foreach (ATNState s in set)
                {
                    foreach (Transition t in s.TransitionsArray)
                    {
                        switch (t.TransitionType)
                        {
                        case TransitionType.RULE:
                            break;

                        case TransitionType.PREDICATE:
                            break;

                        case TransitionType.WILDCARD:
                            break;

                        default:
                            if (!t.IsEpsilon)
                            {
                                result.AddAll(t.Label);
                            }

                            break;
                        }
                    }
                }
            }
            return(result);
        }