/// <summary> /// Checks whether the ATNState is compatiple with the given stack. /// </summary> /// <param name="state"></param> /// <param name="parserStack"></param> /// <returns></returns> public static bool IsCompatibleWith(ATNState state, ParserStack parserStack) { var res = parserStack.Process(state); if (!res.Item1) { return(false); } if (state.epsilonOnlyTransitions) { return(state.Transitions.Any(it => IsCompatibleWith(it.target, res.Item2))); } else { return(true); } }
private void Process(ATNState state, MyTokenStream tokens, ICollection <Suggestion> collector, ParserStack parserStack, HashSet <int> alreadyPassed) { var atCaret = tokens.AtCaret(); var stackRes = parserStack.Process(state); if (!stackRes.Item1) { return; } foreach (var it in state.Transitions) { if (it.IsEpsilon) { var stateNo = it.target.StateNumber; if (!alreadyPassed.Contains(stateNo)) { Process(it.target, tokens, collector, stackRes.Item2, alreadyPassed); alreadyPassed.Add(stateNo); } } else if (it is AtomTransition) { var atomTransition = it as AtomTransition; var nextToken = tokens.Next(); if (atCaret) { if (ParserStack.IsCompatibleWith(it.target, parserStack)) { AddSymbol(collector, parserStack, atomTransition.label, nextToken); } } else { if (nextToken.Type == atomTransition.label) { Process(it.target, tokens.Move(), collector, stackRes.Item2, new HashSet <int>()); } } } else if (it is SetTransition) { var setTransition = it as SetTransition; var nextToken = tokens.Next(); foreach (var sym in setTransition.Label.ToList()) { if (atCaret) { if (ParserStack.IsCompatibleWith(it.target, parserStack)) { AddSymbol(collector, parserStack, sym, nextToken); } } else { if (nextToken.Type == sym) { Process(it.target, tokens.Move(), collector, stackRes.Item2, new HashSet <int>()); } } } } else { throw new InvalidOperationException(it.GetType().FullName); } } }