private static void CheckStateStability <TLabel>(IDfa <TLabel, char> dfa) { foreach (var state in ReachableStates(dfa)) { bool expectedStability = true; foreach (var(_, nextState) in dfa.Transitions(state)) { if (nextState != state) { expectedStability = false; break; } } Assert.AreEqual(expectedStability, dfa.IsStable(state), "Stability of the state is incorrect"); } }
private static IReadOnlyCollection <ParseAction <TLabel> > GetAllParseActions( CompiledGrammar <TLabel> grammar, IState state, IDfa <Optional <Rule <TLabel> >, TLabel> dfa, TLabel label, IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > follow, IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > firstPlus) { var actions = new List <ParseAction <TLabel> >(); var stateLabel = dfa.Label(state); var dfaAndState = new DfaAndState <TLabel>() { Dfa = dfa, State = state }; if (stateLabel.IsSome() && follow.ContainsKey(label) && follow[label].Contains(dfaAndState)) { actions.Add( new ParseAction <TLabel>() { Kind = ParseAction <TLabel> .ActionKind.Reduce, Label = stateLabel.Get().Lhs }); } var transitions = dfa.Transitions(state); if (transitions.ContainsKey(label)) { var nextState = transitions[label]; if (!dfa.IsStable(nextState) || dfa.Label(nextState).IsSome()) { actions.Add( new ParseAction <TLabel>() { Kind = ParseAction <TLabel> .ActionKind.Shift, Label = label }); } } if (firstPlus.ContainsKey(label)) { var firstPlusStates = firstPlus[label]; foreach (var transitionLabel in transitions.Keys) { var nextState = transitions[transitionLabel]; if ((!dfa.IsStable(nextState) || dfa.Label(nextState).IsSome()) && grammar.Rules.ContainsKey(transitionLabel)) { var subDfa = grammar.Rules[transitionLabel]; var subDfaAndStartState = new DfaAndState <TLabel>() { Dfa = subDfa, State = subDfa.StartingState() }; if (firstPlusStates.Contains(subDfaAndStartState)) { actions.Add( new ParseAction <TLabel>() { Kind = ParseAction <TLabel> .ActionKind.Call, Label = transitionLabel }); } } } } return(actions); }