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 Surf.Set FOLLOW(string symbol) { if (!follow.IsDefined(symbol)) { return(new Surf.Set()); } return((Surf.Set)follow.Apply(symbol)); }
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 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); } } }
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 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); }
// 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))); }
public static void Generate(string name, string nspace, Bamboo.Parsing.Grammars.Grammar grammar, System.IO.TextWriter writer) { writer.WriteLine("//"); writer.WriteLine("// AUTOGENERATED " + System.DateTime.Now + ""); writer.WriteLine("//"); writer.WriteLine("using System;"); writer.WriteLine(""); writer.WriteLine("namespace " + nspace + ""); writer.WriteLine("{"); writer.WriteLine(" public abstract class "+ name + "Evaluator"); writer.WriteLine(" {"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Evaluator()"); writer.WriteLine(" {"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" public object Evaluate("+ name + "Node node)"); writer.WriteLine(" {"); writer.WriteLine(" switch (node.Type)"); writer.WriteLine(" {"); foreach (string nonterminal in grammar.Nonterminals) { writer.WriteLine(" case "+ name + "NodeType." + nonterminal + ":"); writer.WriteLine(" {"); foreach (Bamboo.Parsing.Grammars.Production production in GetProductions(nonterminal, grammar)) { if (production.Expression is Bamboo.Parsing.Grammars.Concatenation) { Bamboo.Parsing.Grammars.Concatenation concatenation = (Bamboo.Parsing.Grammars.Concatenation)production.Expression; string tag = ""; writer.Write(" if("); writer.Write("node.Nodes.Count == " + concatenation.Expressions.Count); int i = 0; foreach (Bamboo.Parsing.Grammars.Symbol symbol in concatenation.Expressions) { tag += symbol.Token; writer.Write(" && node.Nodes[" + i + "].Type == " + name + "NodeType." + symbol.Token + ""); i++; } writer.WriteLine(")"); writer.WriteLine(" {"); writer.WriteLine(" return Evaluate"+ tag + "(node);"); writer.WriteLine(" }"); } else if (production.Expression is Bamboo.Parsing.Grammars.Symbol) { Bamboo.Parsing.Grammars.Symbol symbol = (Bamboo.Parsing.Grammars.Symbol)production.Expression; if (!symbol.Token.Equals("EPSILON")) { string tag = symbol.Token; writer.Write(" if("); writer.Write("node.Nodes.Count == 1"); writer.Write(" && node.Nodes[0].Type == " + name + "NodeType." + symbol.Token + ""); writer.WriteLine(")"); writer.WriteLine(" {"); if (grammar.Terminals.Contains(symbol.Token)) { writer.WriteLine(" return Evaluate"+ tag + "(node.Nodes[0].Value);"); } else { writer.WriteLine(" return Evaluate"+ tag + "(node.Nodes[0]);"); } writer.WriteLine(" }"); } } else { throw new System.Exception("Invalid expression."); } } writer.WriteLine(" throw new System.Exception(\"Invalid expression.\");"); writer.WriteLine(" }"); } foreach (string terminal in grammar.Terminals) { if (!terminal.Equals("EPSILON")) { writer.WriteLine(" case "+ name + "NodeType." + terminal + ":"); writer.WriteLine(" {"); writer.WriteLine(" return Evaluate"+ terminal + "(node.Value);"); writer.WriteLine(" }"); } } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Invalid expression.\");"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); Surf.Set functions = new Surf.Set(); functions.Define("EPSILON", "EPSILON"); foreach (string nonterminal in grammar.Nonterminals) { foreach (Bamboo.Parsing.Grammars.Production production in GetProductions(nonterminal, grammar)) { string tag = ""; if (production.Expression is Bamboo.Parsing.Grammars.Concatenation) { Bamboo.Parsing.Grammars.Concatenation concatenation = (Bamboo.Parsing.Grammars.Concatenation)production.Expression; foreach (Bamboo.Parsing.Grammars.Symbol symbol in concatenation.Expressions) { tag += symbol.Token; } if (!functions.IsDefined(tag)) { writer.WriteLine(" protected virtual object Evaluate"+ tag + "(" + name + "Node node)"); writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Implement.\");"); writer.WriteLine(" }"); writer.WriteLine(""); functions.Define(tag, tag); } } else if (production.Expression is Bamboo.Parsing.Grammars.Symbol) { Bamboo.Parsing.Grammars.Symbol symbol = (Bamboo.Parsing.Grammars.Symbol)production.Expression; tag += symbol.Token; if (!functions.IsDefined(tag)) { if (grammar.Terminals.Contains(symbol.Token)) { writer.WriteLine(" protected virtual object Evaluate"+ tag + "(string value)"); } else { writer.WriteLine(" protected virtual object Evaluate"+ tag + "(" + name + "Node node)"); } writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Implement.\");"); writer.WriteLine(" }"); writer.WriteLine(""); functions.Define(tag, tag); } } else { throw new System.Exception("Invalid expression."); } } } foreach (string terminal in grammar.Terminals) { if (!functions.IsDefined(terminal)) { writer.WriteLine(" protected virtual object Evaluate"+ terminal + "(string value)"); writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Implement.\");"); writer.WriteLine(" }"); writer.WriteLine(""); functions.Define(terminal, terminal); } } writer.WriteLine(" }"); writer.WriteLine("}"); }
public static void Generate(string name, string nspace, Bamboo.Parsing.FiniteAutomata.FiniteAutomaton finiteAutomaton, System.IO.TextWriter writer) { writer.WriteLine("//"); writer.WriteLine("// AUTOGENERATED " + System.DateTime.Now + ""); writer.WriteLine("//"); writer.WriteLine("using System;"); writer.WriteLine(""); writer.WriteLine("namespace " + nspace + ""); writer.WriteLine("{"); writer.WriteLine(" public class "+ name + "Tokenizer"); writer.WriteLine(" {"); writer.WriteLine(" private static readonly int[,] TABLE = new int[,] {"); Surf.Set transitions = new Surf.Set(); foreach (Bamboo.Parsing.FiniteAutomata.Transition transition in finiteAutomaton.Transitions) { transitions.Add(new Surf.Tuple(new object[] { new Surf.Tuple(new object[] { transition.FromState, transition.Character }), transition.ToState })); } foreach (int state in finiteAutomaton.States) { writer.Write(" { "); foreach (object character in finiteAutomaton.Alphabet) { Surf.Tuple key = new Surf.Tuple(new object[] { state, character }); if (transitions.IsDefined(key)) { int toState = (int)transitions.Apply(key); writer.Write("" + toState + ", "); } else { writer.Write("-1, "); } } writer.WriteLine("},"); } writer.WriteLine(" };"); writer.WriteLine(""); writer.WriteLine(" private System.Text.StringBuilder _stringBuilder = new System.Text.StringBuilder();"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Tokenizer()"); writer.WriteLine(" {"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Token Tokenize(" + name + "TextReader reader)"); writer.WriteLine(" {"); writer.WriteLine(" int n;"); writer.WriteLine(" char ch;"); writer.WriteLine(""); writer.WriteLine(" _stringBuilder.Length = 0;"); writer.WriteLine(""); /* * // * // Trim whitespace * // * while ((n = reader.Peek()) != -1) * { * ch = (char)n; * switch (ch) * { * case ' ': * case '\t': * case '\r': * case '\n': * { * break; * } * default: * { * goto s0; * } * } * } */ writer.WriteLine(" n = reader.Peek();"); writer.WriteLine(" ch = (char)0;"); writer.WriteLine(" int state = 0;"); writer.WriteLine(""); writer.WriteLine(" if (n == -1)"); writer.WriteLine(" {"); writer.WriteLine(" return new "+ name + "Token(" + name + "TokenType._EOF_);"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" while(n != -1 && state != -1)"); writer.WriteLine(" {"); writer.WriteLine(" ch = (char)n;"); writer.WriteLine(""); writer.WriteLine(" switch(ch)"); writer.WriteLine(" {"); int i = 0; foreach (char character in finiteAutomaton.Alphabet) { writer.WriteLine(" case '"+ Escape(character) + "':"); writer.WriteLine(" {"); writer.WriteLine(" int state2 = TABLE[state, "+ i + "];"); writer.WriteLine(" if(state2 == -1)"); writer.WriteLine(" {"); writer.WriteLine(" goto EXIT;"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" state = state2;"); writer.WriteLine(" _stringBuilder.Append(ch);"); writer.WriteLine(" reader.Read();"); writer.WriteLine(" n = reader.Peek();"); writer.WriteLine(" break;"); writer.WriteLine(" }"); i++; } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" goto EXIT;"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" EXIT:"); writer.WriteLine(" switch(state)"); writer.WriteLine(" {"); foreach (int finalState in finiteAutomaton.FinalStates) { Bamboo.Parsing.FiniteAutomata.Token token = GetToken(finalState, finiteAutomaton.Tokens); writer.WriteLine(" case "+ finalState + ":"); writer.WriteLine(" {"); writer.WriteLine(" return new "+ name + "Token(" + name + "TokenType." + token.Name + ", _stringBuilder.ToString());"); writer.WriteLine(" }"); } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" if (n > -1)"); writer.WriteLine(" {"); writer.WriteLine(" _stringBuilder.Append(ch);"); writer.WriteLine(" }"); writer.WriteLine(" return new "+ name + "Token(" + name + "TokenType._ERROR_, _stringBuilder.ToString());"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" }"); writer.WriteLine("}"); }