Пример #1
0
            public static bool IsCompatible(ATNState state, ParserStack stack)
            {
                var processResult = stack.Process(state);

                if (!processResult.isValid)
                {
                    return(false);
                }

                return(!state.epsilonOnlyTransitions ||
                       state.Transitions.Any(transition => IsCompatible(transition.target, processResult.parserStack)));
            }
Пример #2
0
        private void Suggest(ParserStack stack, ATNState state, int suggestionIndex)
        {
            var stackRes = stack.Process(state);

            if (!stackRes.isValid)
            {
                return;
            }

            foreach (var transition in state.Transitions)
            {
                if (transition.IsEpsilon && !_alreadyPassed.Contains(transition.target.stateNumber))
                {
                    _alreadyPassed.Add(transition.target.stateNumber);
                    Suggest(stackRes.parserStack, transition.target, suggestionIndex);
                }
                else
                {
                    switch (transition)
                    {
                    case AtomTransition atomTransition when(_allTokens.Count == 0 || _currentIndex >= _allTokens.Count) && _currentIndex == suggestionIndex:
                    {
                        if (ParserStack.IsCompatible(transition.target, stack))
                        {
                            _suggestions.Add(atomTransition.label);
                        }
                        break;
                    }

                    case AtomTransition atomTransition:
                    {
                        var nextToken = _allTokens[_currentIndex];
                        if (_currentIndex == suggestionIndex && ParserStack.IsCompatible(transition.target, stack))
                        {
                            _suggestions.Add(atomTransition.label);
                        }
                        else if (nextToken.Type == atomTransition.label)
                        {
                            if (_currentIndex + 1 > _allTokens.Count)
                            {
                                return;
                            }
                            _currentIndex++;
                            Suggest(stackRes.parserStack, transition.target, suggestionIndex);
                        }

                        break;
                    }

                    case SetTransition setTransition when(_allTokens.Count == 0 || _currentIndex >= _allTokens.Count) && _currentIndex == suggestionIndex:
                    {
                        foreach (var tokenType in setTransition.Label.ToIntegerList())
                        {
                            if (ParserStack.IsCompatible(transition.target, stack))
                            {
                                _suggestions.Add(tokenType);
                            }
                        }

                        break;
                    }

                    case SetTransition setTransition:
                    {
                        var nextToken = _allTokens[_currentIndex];
                        foreach (var tokenType in setTransition.Label.ToIntegerList())
                        {
                            if (_currentIndex == suggestionIndex &&
                                ParserStack.IsCompatible(transition.target, stack))
                            {
                                _suggestions.Add(tokenType);
                            }
                            else if (nextToken.Type == tokenType)
                            {
                                if (_currentIndex + 1 > _allTokens.Count)
                                {
                                    return;
                                }

                                _currentIndex++;
                                Suggest(stackRes.parserStack, transition.target, suggestionIndex);
                            }
                        }

                        break;
                    }

                    default:
                        throw new NotSupportedException();
                    }
                }
            }
        }