internal CharacterSet/*!*/ Intersect(CharacterSet/*!*/ set) { if (IsEmpty || set.IsEmpty) { return Empty; } if (_negated) { if (set._negated) { // ^A and ^B == ^(A or B) return Complement().Union(set.Complement()).Complement(); } else { // ^A and B = B \ A return set.Subtract(Complement()); } } else if (set._negated) { // A and ^B = A \ B return Subtract(set.Complement()); } // (a \ B) and (c \ D) == a \ ^(c \ (B or D)) // // Proof: // (a \ B) and (c \ D) == // (a and ^B) and (c and ^D) == // a \ ^(c and ^B and ^D) == // a \ ^(c \ (B or D)) QED return new CharacterSet(_include, new CharacterSet(true, set._include, _exclude.Union(set._exclude))); }
private int BuildDFAState(HashSet <int> nfaList) { NfaState state = new NfaState(); foreach (var num in nfaList) { state.NFAStates.UnionWith(m_nfa[num].NFAClosure); } int index = DFAStateNumber(state); if (index == -1) { index = AddDFAState(state); foreach (var num in state.NFAStates) { foreach (var item in m_nfa[num].AcceptList) { state.AcceptList.Add(item); } } var set2 = new List <int>(); var list = new List <Edge>(); foreach (var num in state.NFAStates) { foreach (var edge in m_nfa[num].Edges) { list.Add(edge); set2.Add(edge.Target); } } if (set2.Count >= 1) { var buildArray = new List <CharacterSet>(set2.Count); foreach (int target in set2) { var build = new CharacterSet(); foreach (var edge in list) { if (edge.Target == target) { build.Add(edge.Characters); } } foreach (var edge in list) { if (edge.Target != target) { build.Subtract(edge.Characters); } } buildArray.Add(build); } CharacterSet build5 = new CharacterSet(); foreach (var edge in list) { build5.Add(edge.Characters); } foreach (var set in buildArray) { build5.Subtract(set); } for (int i = 0; i < set2.Count; ++i) { if (buildArray[i].Count >= 1) { var setList = new HashSet <int> { set2[i] }; state.AddEdge(BuildDFAState(setList), buildArray[i]); } } foreach (var number in build5) { var setList = new HashSet <int>(); foreach (var edge in list) { if (ReferenceEquals(edge.Characters, null)) { continue; } if (edge.Characters.Contains(number)) { setList.Add(edge.Target); } } if (setList.Count > 0) { var build = new CharacterSet(); build.Add(number); state.AddEdge(BuildDFAState(setList), build); } } } } return(index); }