/// <summary> /// Convert NFATable to DFATable. /// </summary> /// <returns> A DFATable. </returns> public DFATable ToDFATable() { // Helper function to check if this DFAState is final. Func <DFAState, bool> IsFinal = x => { foreach (int s in x) { if (finals.Contains(s)) { return(true); } } return(false); }; DFATable dfa = new DFATable(map, revMap); // Map DFAState to the actual state ID in DFATable. Dictionary <DFAState, int> dict = new Dictionary <DFAState, int>(DFAState.CreateSetComparer()); Stack <DFAState> unmarked = new Stack <DFAState>(); // Initialize the first DFA state. DFAState closure = FindEpsilonClosure(new HashSet <int> { 0 }); dict.Add(closure, dfa.AddState()); unmarked.Push(closure); if (IsFinal(closure)) { dfa.SetStateFinal(dict[closure]); } // Build the DFA by simulating NFA. while (unmarked.Count() > 0) { DFAState T = unmarked.Pop(); for (int i = 0; i < revMap.Count(); ++i) { // Find move(T, i). DFAState move = new DFAState(); foreach (int s in T) { move.UnionWith(table[s][i]); } // U = epsilon-closure(move). DFAState U = FindEpsilonClosure(move); if (!dict.ContainsKey(U)) { // This is a new DFAState. dict.Add(U, dfa.AddState()); unmarked.Push(U); if (IsFinal(U)) { dfa.SetStateFinal(dict[U]); } } // Add transition from T to U with i. dfa.AddTransition(dict[T], dict[U], revMap[i]); } } return(dfa.Minimize()); }