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))); }
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(); } } } }