public static IReadOnlyCollection <IState> GetAllStates <TLabel, Symbol>(this IDfa <TLabel, Symbol> dfa) { var visited = new HashSet <IState>(); var queue = new Queue <IState>(); queue.Enqueue(dfa.StartingState()); visited.Add(dfa.StartingState()); while (queue.Count > 0) { var s = queue.Dequeue(); var transitions = dfa.Transitions(s); foreach (var nextState in transitions.Values) { if (!visited.Contains(nextState)) { queue.Enqueue(nextState); visited.Add(nextState); } } } return(visited); }
private static Dictionary <IState, Dictionary <TLabel, HashSet <IState> > > GetReverseTransitions(IDfa <Optional <Rule <TLabel> >, TLabel> dfa) { var allStates = dfa.GetAllStates(); var reverseTransitions = new Dictionary <IState, Dictionary <TLabel, HashSet <IState> > >(); foreach (IState state in allStates) { reverseTransitions.Add(state, new Dictionary <TLabel, HashSet <IState> >()); } foreach (IState state in allStates) { foreach (var transition in dfa.Transitions(state)) { var symbol = transition.Key; var newState = transition.Value; if (!reverseTransitions[newState].ContainsKey(symbol)) { reverseTransitions[newState].Add(symbol, new HashSet <IState>()); } reverseTransitions[transition.Value][transition.Key].Add(state); } } return(reverseTransitions); }
private void Call(IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state, TLabel actionLabel) { this.statesStack.Pop(); this.statesStack.Push(dfa.Transitions(state)[actionLabel]); this.dfaStack.Push(this.rules[actionLabel]); this.statesStack.Push(this.rules[actionLabel].StartingState()); this.nodesStack.Push(new List <ParseTree <TLabel> >()); }
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 TLabel GetTargetLabel <TLabel>(IDfa <TLabel, char> dfa, string s, TLabel defaultLabel) { var state = dfa.StartingState(); foreach (var ch in s) { var transitions = dfa.Transitions(state); if (!transitions.ContainsKey(ch)) { return(defaultLabel); } state = transitions[ch]; } return(dfa.Label(state)); }
public static bool AreEquivalent(IDfa <TLabel, Symbol> firstDfa, IDfa <TLabel, Symbol> secondDfa) { var reached = new HashSet <Tuple <IState, IState> >(); var queue = new Queue <Tuple <IState, IState> >(); queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState())); reached.Add(queue.Peek()); while (queue.Count > 0) { var(firstState, secondState) = queue.Dequeue(); if (!firstDfa.Label(firstState).Equals(secondDfa.Label(secondState))) { return(false); } var firstStateTransitions = firstDfa.Transitions(firstState); var secondStateTransitions = secondDfa.Transitions(secondState); if (!firstStateTransitions.Count.Equals(secondStateTransitions.Count)) { return(false); } foreach (var(c, firstNextState) in firstStateTransitions) { if (!secondStateTransitions.ContainsKey(c)) { return(false); } var secondNextState = secondStateTransitions[c]; var pair = Tuple.Create(firstNextState, secondNextState); if (!reached.Contains(pair)) { reached.Add(pair); queue.Enqueue(pair); } } } return(true); }
private static List <HashSet <IState> > MooresStep(IDfa <TLabel, Symbol> dfa, List <HashSet <IState> > partition) { var stateClassId = new Dictionary <IState, int>(); for (int i = 0; i < partition.Count; ++i) { foreach (var state in partition[i]) { stateClassId[state] = i; } } var stateDerivatives = new List <Tuple <IState, List <int> > >(); foreach (var equivalenceClass in partition) { foreach (var state in equivalenceClass) { var derivative = new List <int> { stateClassId[state] }; derivative.AddRange(dfa.Transitions(state).OrderBy(t => t.Key).Select(t => stateClassId[t.Value])); stateDerivatives.Add(Tuple.Create(state, derivative)); } } var newPartition = new List <HashSet <IState> >(); var groups = stateDerivatives.GroupBy(d => string.Join(" ", d.Item2.Select(t => Convert.ToString(t)))); foreach (var group in groups) { var partitionGroup = new HashSet <IState>(); foreach (var(state, _) in group) { partitionGroup.Add(state); } newPartition.Add(partitionGroup); } return(newPartition); }
private void Shift( ParseTree <TLabel> currentToken, IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state, TLabel currentCategory, IEnumerator enumerator) { this.nodesStack.Peek().Add(currentToken); this.statesStack.Pop(); this.statesStack.Push(dfa.Transitions(state)[currentCategory]); if (!enumerator.MoveNext()) { this.diagnostics.Add(new Diagnostic( DiagnosticStatus.Error, PrematureEofDiagnosticType, "Parsing finished before reading all tokens", new List <Range>())); throw new ParseException("Premature EOF"); } }
private static HashSet <IState> ReachableStates <TLabel>(IDfa <TLabel, char> dfa) { var reachedStates = new HashSet <IState>(); var queue = new Queue <IState>(new[] { dfa.StartingState() }); while (queue.Count > 0) { var state = queue.Dequeue(); foreach (var(_, value) in dfa.Transitions(state)) { if (!reachedStates.Contains(value)) { reachedStates.Add(value); queue.Enqueue(value); } } } return(reachedStates); }
private static void CheckAutomatonEquivalence <TLabel>(IDfa <TLabel, char> firstDfa, IDfa <TLabel, char> secondDfa) { var reached = new HashSet <Tuple <IState, IState> >(); var queue = new Queue <Tuple <IState, IState> >(); queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState())); reached.Add(queue.Peek()); while (queue.Count > 0) { var(firstState, secondState) = queue.Dequeue(); Assert.AreEqual(firstDfa.Label(firstState), secondDfa.Label(secondState), "Labels should be equal"); var firstStateTransitions = firstDfa.Transitions(firstState); var secondStateTransitions = secondDfa.Transitions(secondState); var firstTransitionCount = firstStateTransitions.Count; var secondTransitionCount = secondStateTransitions.Count; Assert.AreEqual( firstTransitionCount, secondTransitionCount, $"States {firstState} and {secondState} have different number of transitions: {firstTransitionCount} != {secondTransitionCount}"); foreach (var(c, firstNextState) in firstStateTransitions) { Assert.IsTrue( secondStateTransitions.ContainsKey(c), $"States have different sets of transitions, {secondTransitionCount} : {string.Join(",", firstStateTransitions.Select((x, y) => ((int)x.Key).ToString()).ToList())}"); var secondNextState = secondStateTransitions[c]; var pair = Tuple.Create(firstNextState, secondNextState); if (!reached.Contains(pair)) { reached.Add(pair); queue.Enqueue(pair); } } } }
private static HashSet <IState> ReachableStates(IDfa <TLabel, Symbol> dfa) { var reachedStates = new HashSet <IState>(); var queue = new Queue <IState>(); queue.Enqueue(dfa.StartingState()); reachedStates.Add(dfa.StartingState()); while (queue.Count > 0) { IState state = queue.Dequeue(); foreach (KeyValuePair <Symbol, IState> transition in dfa.Transitions(state)) { if (!reachedStates.Contains(transition.Value)) { reachedStates.Add(transition.Value); queue.Enqueue(transition.Value); } } } return(reachedStates); }
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); }