internal DFATable ToDFATable() { var dfa = new DFATable(); var mergedStates = new List <HashSet <Node> >(); foreach (var entry in this._relations) { if (entry.Value != Relation.Equivalent) { continue; } var pair = entry.Key; bool merged = false; foreach (var mergedState in mergedStates) { if (mergedState.Contains(pair.A) || mergedState.Contains(pair.B)) { mergedState.Add(pair.A); mergedState.Add(pair.B); merged = true; break; } } if (!merged) { mergedStates.Add(new HashSet <Node>() { pair.A, pair.B }); } } // Create new states. var mergedStateMap = new Dictionary <Node, Node>(); foreach (var mergedState in mergedStates) { var node = dfa.CreateNode(); foreach (var state in mergedState) { node.UnionTags(state.GetTags()); mergedStateMap[state] = node; } // Merged states will not have conflicting values for IsFinal. node.IsFinal = mergedState.First().IsFinal; } var symbols = this._dfa.GetAllPossibleSymbols(); foreach (var mergedState in mergedStates) { foreach (var symbol in symbols) { Debug.Assert(symbol != NFATable.Epsilon, $"DFATable cannot contain epsilon transition."); var resultingStates = this._dfa.ApplyTransition(mergedState, symbol); var source = mergedStateMap[mergedState.First()]; var destination = mergedStateMap[resultingStates.First()]; dfa.AddTransition(source, destination, symbol); } } dfa.StartState = mergedStateMap[this._dfa.StartState]; return(dfa); }
public DFAMinimizationTable(DFATable dFATable) { this._dfa = dFATable; this._relations = new Dictionary <NodePair, Relation>(); }