public Set Unnest() { Set b = new Set(); foreach (Surf.Tuple obj in this) { if (!(obj is Tuple)) { throw new System.Exception("Invalid relation."); } Tuple tuple = (Tuple)obj; if (tuple.Count != 2) { throw new System.Exception("Invalid relation."); } object key = tuple[0]; Surf.Set value = (Surf.Set)tuple[1]; foreach (object v in value) { b.Add(new Tuple(new object[] { key, v })); } } return(b); }
public static Surf.Set First(Bamboo.Parsing.Grammars.Grammar grammar) { Surf.Set FIRST = new Surf.Set(); foreach (string symbol in grammar.Terminals) { FIRST.Add(new Surf.Tuple(new object[] { symbol, new Surf.Set(new object[] { symbol }) })); } foreach (string symbol in grammar.Nonterminals) { FIRST.Add(new Surf.Tuple(new object[] { symbol, new Surf.Set() })); } List <Bamboo.Parsing.Grammars.Production> remaining = Copy(grammar.Productions); while (remaining.Count > 0) { for (int i = 0; i < remaining.Count; i++) { Bamboo.Parsing.Grammars.Production production = remaining[i]; if (CanResolve(production.Expression, remaining)) { First(production.Nonterminal, production.Expression, FIRST); remaining.Remove(production); break; } } } return(FIRST); }
private static Surf.Set Split(Surf.Set S, char character, Surf.Set transitions, Surf.Set P2) { //System.Console.WriteLine("START Split2 " + System.DateTime.Now.ToString()); Surf.Set f_nP = PartitionMap(P2); Surf.Set partition_map = new Surf.Set(); foreach (int fromState in S) { object key = new Surf.Tuple(new object[] { fromState, character }); if (transitions.IsDefined(key)) { object value = transitions.Apply(key); int toState = (int)value; int partition = (int)f_nP.Apply(toState); partition_map.Add(new Surf.Tuple(new object[] { partition, fromState })); } else { partition_map.Add(new Surf.Tuple(new object[] { -1, fromState })); } } //System.Console.WriteLine("END Split2 " + System.DateTime.Now.ToString()); return(partition_map.Nest().Range()); }
private static Surf.Set Move(Surf.Set states, char ch, Dictionary <string, int> transitions) { //System.Console.WriteLine("START Move " + System.DateTime.Now.ToString()); Surf.Set move = new Surf.Set(); foreach (int state in states) { if (transitions.ContainsKey("" + state + "::" + ch)) { move.Add(transitions["" + state + "::" + ch]); } //foreach (Surf.Tuple transition in transitions) //{ // Surf.Tuple input = (Surf.Tuple)transition[0]; // if (input.Count == 2 && (int)input[0] == state && (char)input[1] == ch) // { // move.Add(transition[1]); // } //} } //System.Console.WriteLine("END Move " + System.DateTime.Now.ToString()); return(move); }
private void RecalculateDependencies(string name) { Surf.Set dependents = this._dependencies.Unnest().Transpose().Nest(); Surf.Set recalculationList = new Surf.Set(); RecalculationList(name, dependents, recalculationList); Surf.Set dependencyGraph = new Surf.Set(); DependencyGraph(this._dependencies, recalculationList, dependencyGraph); if (dependencyGraph.Count > 0) { Surf.Tuple topologicalSort = new Surf.Tuple(); TopologicalSort(name, dependencyGraph, topologicalSort); foreach (string identifier in topologicalSort) { object value = Evaluate((Node)this._definitions.Apply(identifier)); if (value != null) { this._variables.Define(identifier, value); } } } }
private static void Union(Surf.Set a, Surf.Set b) { foreach (object item in b) { a.Add(item); } }
private static Surf.Set Split(Surf.Set S, Surf.Set transitions, Surf.Set P2) { //System.Console.WriteLine("START Split " + System.DateTime.Now.ToString()); Surf.Set alphabet = new Surf.Set(); foreach (int state in S) { foreach (Surf.Tuple transition in transitions) { Surf.Tuple input = (Surf.Tuple)transition[0]; int fromState = (int)input[0]; char character = (char)input[1]; int toState = (int)transition[1]; if (fromState == state) { alphabet.Add(character); } } } foreach (char character in alphabet) { Surf.Set s = Split(S, character, transitions, P2); if (s.Count > 1) { //System.Console.WriteLine("END Split " + System.DateTime.Now.ToString()); return(s); } } //System.Console.WriteLine("END Split " + System.DateTime.Now.ToString()); return(new Surf.Set(new object[] { S })); }
private static Surf.Tuple Tuple(Surf.Set a) { Surf.Tuple b = new Surf.Tuple(); foreach (object item in a) { b.Add(item); } return(b); }
private static Surf.Set SplitFinalStates(Token[] tokens) { Surf.Set fn = new Surf.Set(); foreach (Token token in tokens) { fn.Add(new Surf.Tuple(new object[] { token.Name, token.Number })); } return(fn.Nest().Range()); }
protected override object EvaluateSet(Node node) { Surf.Set set = new Surf.Set(); System.Collections.ArrayList items = (System.Collections.ArrayList)Evaluate(node.Nodes[1]); foreach (object item in items) { set.Add(item); } return(set); }
private static void Dependencies(Node node, Surf.Set dependencies) { if (node.Type == NodeType.IDENTIFIER) { dependencies.Add(node.Value); } foreach (Node node2 in node.Nodes) { Dependencies(node2, dependencies); } }
private static void DependencyGraph(Surf.Set dependencies, Surf.Set recalculationList, Surf.Set dependencyGraph) { foreach (string identifier in recalculationList) { if (dependencies.IsDefined(identifier)) { Surf.Set dependencyList = ((Surf.Set)dependencies.Apply(identifier)).Intersection(recalculationList); if (dependencyList.Count > 0) { dependencyGraph.Define(identifier, dependencyList); } } } }
private static void RecalculationList(string name, Surf.Set dependents, Surf.Set recalculationList) { if (recalculationList.Contains(name)) { throw new System.Exception("Cycle detected."); } recalculationList.Add(name); if (dependents.IsDefined(name)) { foreach (string dependent in (Surf.Set)dependents.Apply(name)) { RecalculationList(dependent, dependents, recalculationList); } } }
private static Surf.Set PartitionMap(Surf.Set T) { // Label the partition. Surf.Set R = new Surf.Set(); int i = 0; foreach (Surf.Set t in T) { if (t.Count > 0) { R.Add(new Surf.Tuple(new object[] { i, t })); i++; } } return(R.Unnest().Transpose()); }
private static void GetToStates(int fromState, Transition[] transitions, Surf.Set stateMap, Counter counter) { if (stateMap.IsDefined(fromState)) { return; } stateMap.Add(new Surf.Tuple(new object[] { fromState, counter.Next() })); foreach (Transition transition in transitions) { if (fromState == transition.FromState) { GetToStates(transition.ToState, transitions, stateMap, counter); } } }
public Set Range() { Surf.Set range = new Surf.Set(); foreach (object obj in this) { if (!(obj is Tuple)) { throw new System.Exception("Invalid relation."); } Tuple tuple = (Tuple)obj; if (tuple.Count != 2) { throw new System.Exception("Invalid relation."); } range.Add(tuple[1]); } return(range); }
public Set Domain() { Surf.Set domain = new Surf.Set(); foreach (object obj in this) { if (!(obj is Tuple)) { throw new System.Exception("Invalid relation."); } Tuple tuple = (Tuple)obj; if (tuple.Count != 2) { throw new System.Exception("Invalid relation."); } domain.Add(tuple[0]); } return(domain); }
private static FiniteAutomaton Reorder(Bamboo.Parsing.FiniteAutomata.FiniteAutomaton fa) { System.Console.WriteLine("START Reorder " + System.DateTime.Now.ToString()); Surf.Set stateMap = new Surf.Set(); GetToStates(fa.StartState, fa.Transitions, stateMap, new Counter()); Surf.Set states = new Surf.Set(); Surf.Set alphabet = new Surf.Set(); Surf.Set transitions = new Surf.Set(); int startState; Surf.Set finalStates = new Surf.Set(); Surf.Set tokens = new Surf.Set(); for (int i = 0; i < fa.States.Length; i++) { states.Add(stateMap.Apply(fa.States[i])); } alphabet = new Surf.Set(fa.Alphabet); for (int i = 0; i < fa.Transitions.Length; i++) { if (fa.Transitions[i].Epsilon) { transitions.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { stateMap.Apply(fa.Transitions[i].FromState) }), stateMap.Apply(fa.Transitions[i].ToState) })); } else { transitions.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { stateMap.Apply(fa.Transitions[i].FromState), fa.Transitions[i].Character }), stateMap.Apply(fa.Transitions[i].ToState) })); } } startState = (int)stateMap.Apply(fa.StartState); for (int i = 0; i < fa.FinalStates.Length; i++) { finalStates.Add(stateMap.Apply(fa.FinalStates[i])); tokens.Add(new Surf.Tuple(new object[] { stateMap.Apply(fa.FinalStates[i]), Lookup(fa.Tokens, fa.FinalStates[i]) })); } System.Console.WriteLine("END Reorder " + System.DateTime.Now.ToString()); return(new FiniteAutomaton(states, alphabet, transitions, startState, finalStates, tokens)); }
private static Surf.Set EpsilonClosure(Surf.Set states, Surf.Set transitions, Surf.Set epsilonCache) { Surf.Tuple key = Tuple(states); if (epsilonCache.IsDefined(key)) { return((Surf.Set)epsilonCache.Apply(key)); } //System.Console.WriteLine("START EpsilonClosure " + System.DateTime.Now.ToString()); Surf.Set epsilonClosure = new Surf.Set(); Stack <int> worklist = new Stack <int>(); foreach (int state in states) { epsilonClosure.Add(state); worklist.Push(state); } while (worklist.Count > 0) { int state = worklist.Pop(); foreach (Surf.Tuple transition in transitions) { Surf.Tuple input = (Surf.Tuple)transition[0]; if (input.Count == 1 && (int)input[0] == state) { int toState = (int)transition[1]; if (!epsilonClosure.Contains(toState)) { epsilonClosure.Add(toState); worklist.Push(toState); } } } } epsilonCache.Add(new Surf.Tuple(new object[] { key, epsilonClosure })); //System.Console.WriteLine("END EpsilonClosure " + System.DateTime.Now.ToString()); return(epsilonClosure); }
public Surf.Set Build() { foreach (string symbol in grammar.Terminals) { follow.Add(new Surf.Tuple(new object[] { symbol, new Surf.Set() })); } foreach (string symbol in grammar.Nonterminals) { follow.Add(new Surf.Tuple(new object[] { symbol, new Surf.Set() })); } // I hope this is fixed-point. for (int z = 0; z < grammar.Productions.Count; z++) { foreach (Bamboo.Parsing.Grammars.Production production in grammar.Productions) { string A = production.Nonterminal; List <Bamboo.Parsing.Grammars.Expression> B = ToList(production.Expression); int k = B.Count - 1; Union(FOLLOW(B[k]), FOLLOW(A)); Surf.Set trailer = FOLLOW(A); for (int i = k; i >= 1; i--) { if (FIRST(B[i]).Contains("EPSILON")) { Union(FOLLOW(B[i - 1]), FIRST(B[i]).Difference(EPSILON)); Union(FOLLOW(B[i - 1]), trailer); } else { Union(FOLLOW(B[i - 1]), FIRST(B[i])); trailer = new Surf.Set(); } } } } return(follow); }
public static Surf.Set Predict(Bamboo.Parsing.Grammars.Grammar grammar, Surf.Set FIRST, Surf.Set FOLLOW) { Surf.Set PREDICT = new Surf.Set(); int i = 0; foreach (Bamboo.Parsing.Grammars.Production production in grammar.Productions) { Surf.Set PREDICT_i = ((Surf.Set)FIRST.Apply(GetFirstSymbol(production.Expression))).Difference(EPSILON); if (((Surf.Set)FIRST.Apply(GetFirstSymbol(production.Expression))).Contains("EPSILON")) { Union(PREDICT_i, (Surf.Set)FOLLOW.Apply(production.Nonterminal)); } PREDICT.Add(new Surf.Tuple(new object[] { i, production, PREDICT_i })); i++; } AssertDisjoint(PREDICT, grammar.Nonterminals); return(PREDICT); }
private static void AssertDisjoint(Surf.Set PREDICT, Surf.Set nonterminals) { Dictionary <string, List <Surf.Set> > lookup = new Dictionary <string, List <Surf.Set> >(); foreach (string nonterminal in nonterminals) { lookup.Add(nonterminal, new List <Surf.Set>()); } foreach (Surf.Tuple tuple in PREDICT) { Bamboo.Parsing.Grammars.Production production = (Bamboo.Parsing.Grammars.Production)tuple[1]; Surf.Set predict = (Surf.Set)tuple[2]; lookup[production.Nonterminal].Add(predict); } foreach (List <Surf.Set> sets in lookup.Values) { for (int i = 0; i < sets.Count; i++) { for (int j = (i + 1); j < sets.Count; j++) { if (sets[i].Intersection(sets[j]).Count > 0) { System.Console.WriteLine("PREDICT"); foreach (Surf.Tuple tuple in PREDICT) { int n = (int)tuple[0]; Bamboo.Parsing.Grammars.Production production = (Bamboo.Parsing.Grammars.Production)tuple[1]; Surf.Set predict = (Surf.Set)tuple[2]; System.Console.Write(n + " "+ production.Nonterminal + " "); Surf.Printer.Print(predict, System.Console.Out); System.Console.WriteLine(); } System.Console.WriteLine(); throw new System.Exception("Ambiguous grammar. Predict-predict conflict."); } } } } }
private static void TopologicalSort(string name, Surf.Set dependencyGraph, Surf.Tuple topologicalSort) { Surf.Set completed = new Surf.Set(); completed.Add(name); while (dependencyGraph.Count > 0) { for (int i = 0; i < dependencyGraph.Count; i++) { Surf.Tuple tuple = (Surf.Tuple)dependencyGraph[i]; if (((Surf.Set)tuple[1]).Difference(completed).Count == 0) { topologicalSort.Add(tuple[0]); completed.Add(tuple[0]); dependencyGraph.Remove(i); break; } } } }
private static Surf.Set Set(Transition[] transitions) { #region Convert a Transition[] to a transition relation. Surf.Set fn = new Surf.Set(); for (int i = 0; i < transitions.Length; i++) { Transition transition = transitions[i]; if (transition.Epsilon) { fn.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { transition.FromState }), transition.ToState })); } else { fn.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { transition.FromState, transition.Character }), transition.ToState })); } } return(fn); #endregion }
private static void First(string A, Bamboo.Parsing.Grammars.Expression expression, Surf.Set FIRST) { List <Bamboo.Parsing.Grammars.Expression> B = ToList(expression); Surf.Set FIRST_A = (Surf.Set)FIRST.Apply(A); Union(FIRST_A, ((Surf.Set)FIRST.Apply(((Bamboo.Parsing.Grammars.Symbol)B[0]).Token)).Difference(EPSILON)); int i = 0; while (((Surf.Set)FIRST.Apply(((Bamboo.Parsing.Grammars.Symbol)B[0]).Token)).Contains("EPSILON") && i < (B.Count - 1)) { Union(FIRST_A, ((Surf.Set)FIRST.Apply(((Bamboo.Parsing.Grammars.Symbol)B[i + 1]).Token)).Difference(EPSILON)); i++; } if (i == (B.Count - 1) && ((Surf.Set)FIRST.Apply(((Bamboo.Parsing.Grammars.Symbol)B[B.Count - 1]).Token)).Contains("EPSILON")) { Union(FIRST_A, EPSILON); } }
private void Assign(string name, Node node) { // Set defintion. this._definitions.Define(name, node); // Set variable. object value = Evaluate(node); if (value != null) { this._variables.Define(name, value); } // Rebuild dependency graph. Surf.Set dependencies = Dependencies(node); if (dependencies.Count > 0) { this._dependencies.Define(name, dependencies); } // Recalculate dependencies. this.RecalculateDependencies(name); }
public static void GenerateClass(string name, string multinamespace, Bamboo.Parsing.FiniteAutomata.FiniteAutomaton finiteAutomaton, System.IO.TextWriter writer) { writer.WriteLine("//"); writer.WriteLine("// " + name + "Tokenizer.cpp"); writer.WriteLine("//"); writer.WriteLine("// AUTOGENERATED " + System.DateTime.Now + ""); writer.WriteLine("//"); writer.WriteLine(""); writer.WriteLine("#include <istream>"); writer.WriteLine("#include \"" + name + "Parser.h\""); writer.WriteLine("#include \"" + name + "Token.h\""); writer.WriteLine("#include \"" + name + "Tokenizer.h\""); writer.WriteLine("#include \"" + name + "TokenType.h\""); writer.WriteLine(""); string[] namespaces = multinamespace.Split(new string[] { "::" }, StringSplitOptions.None); foreach (string nspace in namespaces) { writer.WriteLine("namespace " + nspace + ""); writer.WriteLine("{"); } writer.WriteLine(" int "+ name + "Tokenizer::_counter = 0;"); writer.WriteLine(""); writer.WriteLine(" void "+ name + "Tokenizer::next(char ch)"); writer.WriteLine(" {"); writer.WriteLine(" switch(_state)"); writer.WriteLine(" {"); //TODO if ch == -1, purge remaining token. foreach (int state in finiteAutomaton.States) { bool isFinal = Operators.IsFinal(state, finiteAutomaton.FinalStates); bool hasTransitions = Operators.HasTransitions(state, finiteAutomaton.Transitions); if (!isFinal || hasTransitions) { writer.WriteLine(" case "+ state + ":"); writer.WriteLine(" {"); writer.WriteLine(" switch (ch)"); writer.WriteLine(" {"); if (state == 0) { writer.WriteLine(" case ' ':"); writer.WriteLine(" case '\\t':"); writer.WriteLine(" case '\\r':"); writer.WriteLine(" case '\\n':"); writer.WriteLine(" {"); writer.WriteLine(" // Trim whitespace"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } Surf.Set transitions = new Surf.Set(); foreach (Bamboo.Parsing.FiniteAutomata.Transition transition in finiteAutomaton.Transitions) { if (transition.FromState == state) { transitions.Add(new Surf.Tuple(new object[] { transition.ToState, transition.Character })); } } transitions = transitions.Nest(); foreach (Surf.Tuple transition in transitions) { foreach (char character in (Surf.Set)transition[1]) { writer.WriteLine(" case '"+ Operators.Escape(character) + "':"); } writer.WriteLine(" {"); bool isFinal2 = Operators.IsFinal((int)transition[0], finiteAutomaton.FinalStates); bool hasTransitions2 = Operators.HasTransitions((int)transition[0], finiteAutomaton.Transitions); writer.WriteLine(" _buffer += ch;"); if (isFinal2 && !hasTransitions2) { Bamboo.Parsing.FiniteAutomata.Token token = Operators.GetToken((int)transition[0], finiteAutomaton.Tokens); writer.WriteLine(" "+ name + "Token token(" + name + "TokenType::" + token.Name + ", _buffer);"); writer.WriteLine(" _parser->next(token);"); writer.WriteLine(" _state = 0;"); writer.WriteLine(" _buffer.clear();"); } else { writer.WriteLine(" _state = "+ transition[0] + ";"); } writer.WriteLine(" break;"); writer.WriteLine(" }"); } writer.WriteLine(" default:"); writer.WriteLine(" {"); if (isFinal) { Bamboo.Parsing.FiniteAutomata.Token token = Operators.GetToken(state, finiteAutomaton.Tokens); writer.WriteLine(" "+ name + "Token token(" + name + "TokenType::" + token.Name + ", _buffer);"); writer.WriteLine(" _parser->next(token);"); writer.WriteLine(" _state = 0;"); writer.WriteLine(" _buffer.clear();"); writer.WriteLine(" next(ch);"); } else { writer.WriteLine(" _buffer += ch;"); writer.WriteLine(" "+ name + "Token token(" + name + "TokenType::_ERROR_, _buffer);"); writer.WriteLine(" _parser->next(token);"); } writer.WriteLine(" break;"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" "+ name + "Token token(" + name + "TokenType::_ERROR_, _buffer);"); writer.WriteLine(" _parser->next(token);"); writer.WriteLine(" break;"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); foreach (string nspace in namespaces) { writer.WriteLine("}"); } }
public static FiniteAutomaton CreateFA(Bamboo.Parsing.RegularExpressions.Expression expression) { FiniteAutomaton nfa = NFA(expression); List <System.Collections.BitArray> alphabet = Alphabet.Create(expression); char[] alphabet_index = new char[128]; for (int i = 0; i < alphabet.Count; i++) { System.Collections.BitArray bitArray = alphabet[i]; for (int j = 0; j < bitArray.Count; j++) { if (bitArray[j]) { if (alphabet_index[j] != 0) { throw new System.Exception("Already assigned."); } alphabet_index[j] = (char)i; } } } Surf.Set alphabet2 = new Surf.Set(); foreach (char ch in nfa.Alphabet) { alphabet2.Add(alphabet_index[ch]); } Surf.Set transitions2 = new Surf.Set(); foreach (Transition transition in nfa.Transitions) { if (transition.Epsilon) { transitions2.Add(transition); } else { transitions2.Add(new Transition(transition.FromState, alphabet_index[transition.Character], transition.ToState)); } } FiniteAutomaton nfa2 = new FiniteAutomaton(); nfa2.States = nfa.States; nfa2.StartState = nfa.StartState; nfa2.FinalStates = nfa.FinalStates; nfa2.Tokens = nfa.Tokens; nfa2.Alphabet = new char[alphabet2.Count]; for (int i = 0; i < alphabet2.Count; i++) { nfa2.Alphabet[i] = (char)alphabet2[i]; } nfa2.Transitions = new Transition[transitions2.Count]; for (int i = 0; i < transitions2.Count; i++) { nfa2.Transitions[i] = (Transition)transitions2[i]; } FiniteAutomaton dfa = DFA(nfa2); FiniteAutomaton fa2 = new FiniteAutomaton(); fa2.States = dfa.States; fa2.StartState = dfa.StartState; fa2.FinalStates = dfa.FinalStates; fa2.Tokens = dfa.Tokens; List <char> alphabet3 = new List <char>(); foreach (char ch in dfa.Alphabet) { System.Collections.BitArray bitArray = alphabet[ch]; for (int i = 0; i < bitArray.Count; i++) { if (bitArray[i]) { alphabet3.Add((char)i); } } } fa2.Alphabet = alphabet3.ToArray(); List <Bamboo.Parsing.FiniteAutomata.Transition> transitions = new List <Transition>(); foreach (Bamboo.Parsing.FiniteAutomata.Transition transition in dfa.Transitions) { if (transition.Epsilon) { transitions.Add(transition); } else { System.Collections.BitArray bitArray = alphabet[transition.Character]; for (int i = 0; i < bitArray.Count; i++) { if (bitArray[i]) { transitions.Add(new Bamboo.Parsing.FiniteAutomata.Transition(transition.FromState, (char)i, transition.ToState)); } } } } fa2.Transitions = transitions.ToArray(); return(fa2); }
public static FiniteAutomaton DFA(Bamboo.Parsing.FiniteAutomata.FiniteAutomaton nfa, Counter counter) { System.Console.WriteLine("START DFA " + System.DateTime.Now.ToString()); Surf.Set epsilonCache = new Surf.Set(); Surf.Set moveCache = new Surf.Set(); Surf.Set nfa_transitions = Set(nfa.Transitions); Dictionary <string, int> nfa_transitions_lookup = new Dictionary <string, int>(); foreach (Surf.Tuple transition in nfa_transitions) { Surf.Tuple input = (Surf.Tuple)transition[0]; if (input.Count == 2) { int state = (int)input[0]; char ch = (char)input[1]; nfa_transitions_lookup.Add("" + state + "::" + ch, (int)transition[1]); } } Surf.Set q0 = EpsilonClosure(new Surf.Set(new object[] { nfa.StartState }), nfa_transitions, epsilonCache); Surf.Set Q = new Surf.Set(); // A set whose element are sets of states that are subsets of N. Q.Add(q0); Surf.Set T = new Surf.Set(); Stack <Surf.Set> worklist = new Stack <Surf.Set>(); worklist.Push(q0); while (worklist.Count > 0) { Surf.Set q = worklist.Pop(); foreach (char character in nfa.Alphabet) { Surf.Set t = EpsilonClosure(Move(q, character, nfa_transitions_lookup), nfa_transitions, epsilonCache); if (t.Count > 0) { T.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { q, character }), t })); if (!Q.Contains(t)) { Q.Add(t); worklist.Push(t); } } } } Surf.Set states = new Surf.Set(); Surf.Set alphabet = new Surf.Set(); Surf.Set transitions = new Surf.Set(); int startState; Surf.Set finalStates = new Surf.Set(); Surf.Set tokens = new Surf.Set(); Surf.Set D = new Surf.Set(); foreach (Surf.Set q in Q) { D.Add(new Surf.Tuple(new object[] { q, counter.Next() })); } foreach (Surf.Set q in Q) { states.Add(D.Apply(q)); } alphabet = new Surf.Set(nfa.Alphabet); foreach (Surf.Tuple t in T) { Surf.Tuple input = (Surf.Tuple)t[0]; int fromState = (int)D.Apply(input[0]); char character = (char)input[1]; int toState = (int)D.Apply(t[1]); transitions.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { fromState, character }), toState })); } startState = (int)states[0]; foreach (int state in nfa.FinalStates) { foreach (Surf.Tuple d in D) { Surf.Set q = (Surf.Set)d[0]; if (q.Contains(state)) { finalStates.Add(d[1]); foreach (int q_state in q) { string token = Lookup(nfa.Tokens, (int)q_state); if (token.Length > 0) { tokens.Add(new Surf.Tuple(new object[] { d[1], token })); break; } } } } } System.Console.WriteLine("END DFA " + System.DateTime.Now.ToString()); //foreach (Token token in nfa.Tokens) //{ // System.Console.WriteLine(token.Name + " " + token.Number); //} //System.Console.WriteLine(); //Surf.Printer.Print(tokens, System.Console.Out); //System.Console.WriteLine(); //System.Console.WriteLine(); return(Minimize(Reorder(new FiniteAutomaton(states, alphabet, transitions, startState, finalStates, tokens)))); }
// Hopcroft's Algorithm public static FiniteAutomaton Minimize(FiniteAutomaton dfa) { System.Console.WriteLine("START Minimize " + System.DateTime.Now.ToString()); Surf.Set dfa_transitions = Set(dfa.Transitions); // Split final states and non-final states. Surf.Set worklist = new Surf.Set(); Surf.Set P = new Surf.Set(); Surf.Set f = SplitFinalStates(dfa.Tokens); foreach (Surf.Set f2 in f) { worklist.Add(f2); P.Add(f2); } Surf.Set nonFinalStates = new Surf.Set(dfa.States).Difference(new Surf.Set(dfa.FinalStates)); worklist.Add(nonFinalStates); P.Add(nonFinalStates); // While there are more states to split. while (worklist.Count > 0) { Surf.Set p = (Surf.Set)worklist[0]; worklist.Remove(0); Surf.Set t = Split(p, dfa_transitions, P); if (t.Count > 1) { int i = 0; foreach (Surf.Set p2 in P) { if (p2.Equals(p)) { P.Remove(i); break; } i++; } foreach (Surf.Set t2 in t) { worklist.Add(t2); P.Add(t2); } } } /* * // Split final states and non-final states. * Surf.Set P = new Surf.Set(); * Surf.Set f = SplitFinalStates(dfa.Tokens); * foreach (Surf.Set f2 in f) * { * P.Add(f2); * } * P.Add(new Surf.Set(dfa.States).Difference(new Surf.Set(dfa.FinalStates))); * * // While there are more states to split. * bool isChanging = true; * while (isChanging) * { * isChanging = false; * * Surf.Set T = new Surf.Set(); * foreach (Surf.Set p in P) * { * Surf.Set t = Split(p, dfa_transitions, P); * * if (t.Count > 1) * { * isChanging = true; * } * foreach (Surf.Set t2 in t) * { * T.Add(t2); * } * } * P = T; * } */ Surf.Set states = new Surf.Set(); Surf.Set alphabet = new Surf.Set(); Surf.Set transitions = new Surf.Set(); int startState; Surf.Set finalStates = new Surf.Set(); Surf.Set tokens = new Surf.Set(); Surf.Set P_map = PartitionMap(P); foreach (int state in dfa.States) { states.Add(P_map.Apply(state)); } alphabet = new Surf.Set(dfa.Alphabet); foreach (Surf.Tuple transition in dfa_transitions) { Surf.Tuple input = (Surf.Tuple)transition[0]; int fromState = (int)P_map.Apply(input[0]); char character = (char)input[1]; int toState = (int)P_map.Apply(transition[1]); transitions.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { fromState, character }), toState })); } startState = (int)P_map.Apply(dfa.StartState); foreach (int state in dfa.FinalStates) { finalStates.Add(P_map.Apply(state)); if (!tokens.IsDefined(P_map.Apply(state))) { tokens.Add(new Surf.Tuple(new object[] { P_map.Apply(state), Lookup(dfa.Tokens, state) })); } } System.Console.WriteLine("END Minimize " + System.DateTime.Now.ToString()); return(Reorder(new FiniteAutomaton(states, alphabet, transitions, startState, finalStates, tokens))); }