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); }
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 class "+ name + "NodeType"); writer.WriteLine(" {"); int i = 0; writer.WriteLine(" // Nonterminals"); foreach (string nonterminal in grammar.Nonterminals) { writer.WriteLine(" public const int "+ nonterminal + " = " + i + ";"); i++; } writer.WriteLine(""); writer.WriteLine(" // Terminals"); foreach (string terminal in grammar.Terminals) { writer.WriteLine(" public const int "+ terminal + " = " + i + ";"); i++; } writer.WriteLine(""); writer.WriteLine(" }"); writer.WriteLine("}"); }
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); }
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 class "+ name + "Node : System.IComparable"); writer.WriteLine(" {"); writer.WriteLine(" public int Type;"); writer.WriteLine(" public string Value;"); writer.WriteLine(" public System.Collections.Generic.List<"+ name + "Node> Nodes = new System.Collections.Generic.List<" + name + "Node>();"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Node(int type)"); writer.WriteLine(" {"); writer.WriteLine(" Type = type;"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Node(int type, string value)"); writer.WriteLine(" {"); writer.WriteLine(" Type = type;"); writer.WriteLine(" Value = value;"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" public int CompareTo(object obj)"); writer.WriteLine(" {"); writer.WriteLine(" "+ name + "Node node = (" + name + "Node)obj;"); writer.WriteLine(" int cmp = this.Type.CompareTo(node.Type);"); writer.WriteLine(" if (cmp != 0)"); writer.WriteLine(" {"); writer.WriteLine(" return cmp;"); writer.WriteLine(" }"); writer.WriteLine(" if (this.Value != null && node.Value != null)"); writer.WriteLine(" {"); writer.WriteLine(" cmp = this.Value.CompareTo(node.Value);"); writer.WriteLine(" if (cmp != 0)"); writer.WriteLine(" {"); writer.WriteLine(" return cmp;"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" else if (this.Value != null)"); writer.WriteLine(" {"); writer.WriteLine(" return 1;"); writer.WriteLine(" }"); writer.WriteLine(" else if (node.Value != null)"); writer.WriteLine(" {"); writer.WriteLine(" return -1;"); writer.WriteLine(" }"); writer.WriteLine(" int min = Math.Min(this.Nodes.Count, node.Nodes.Count);"); writer.WriteLine(" for (int i = 0; i < min; i++)"); writer.WriteLine(" {"); writer.WriteLine(" cmp = this.Nodes[i].CompareTo(node.Nodes[i]);"); writer.WriteLine(" if (cmp != 0)"); writer.WriteLine(" {"); writer.WriteLine(" return cmp;"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" return (this.Nodes.Count == node.Nodes.Count) ? 0 : ((this.Nodes.Count > node.Nodes.Count) ? -1 : 1);"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" }"); writer.WriteLine("}"); }
public static Surf.Set Follow(Bamboo.Parsing.Grammars.Grammar grammar, Surf.Set FIRST) { FollowBuilder followBuilder = new FollowBuilder(grammar, FIRST); return(followBuilder.Build()); }
public static void Generate(string name, string nspace, Bamboo.Parsing.Grammars.Grammar grammar, Surf.Set FIRST, Surf.Set FOLLOW, Surf.Set PREDICT, 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 + "Parser"); writer.WriteLine(" {"); writer.WriteLine(" private "+ name + "Tokenizer _tokenizer = new " + name + "Tokenizer();"); //TODO use a state variable. writer.WriteLine(" private "+ name + "TextReader _reader;"); writer.WriteLine(" private "+ name + "Token _token;"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Parser(" + name + "TextReader reader)"); writer.WriteLine(" {"); writer.WriteLine(" this._reader = reader;"); writer.WriteLine(" this._token = this._tokenizer.Tokenize(this._reader);"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" public "+ name + "Node Parse()"); writer.WriteLine(" {"); writer.WriteLine(" return Parse"+ grammar.Productions[0].Nonterminal + "();"); writer.WriteLine(" }"); writer.WriteLine(""); foreach (string nonterminal in grammar.Nonterminals) { writer.WriteLine(" private "+ name + "Node Parse" + nonterminal + "()"); writer.WriteLine(" {"); writer.WriteLine(" "+ name + "Node node = new " + name + "Node(" + name + "NodeType." + nonterminal + ");"); writer.WriteLine(""); writer.WriteLine(" switch (this._token.Type)"); writer.WriteLine(" {"); bool hasDefault = false; 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]; if (production.Nonterminal.Equals(nonterminal)) { List <Bamboo.Parsing.Grammars.Expression> expressions = ToList(production.Expression); //predict.Count == 0 && if (expressions.Count == 1 && ((Bamboo.Parsing.Grammars.Symbol)expressions[0]).Token.Equals("EPSILON")) { hasDefault = true; writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" return node;"); writer.WriteLine(" }"); } else { if (predict.Count == 1 && predict[0].Equals("EOF")) { writer.WriteLine(" case "+ name + "TokenType._EOF_:"); writer.WriteLine(" {"); writer.WriteLine(" return node;"); writer.WriteLine(" }"); } else { foreach (string symbol in predict) { writer.WriteLine(" case "+ name + "TokenType." + symbol + ":"); } writer.WriteLine(" {"); if (!((Bamboo.Parsing.Grammars.Symbol)expressions[0]).Token.Equals("EPSILON")) { for (int i = 0; i < expressions.Count; i++) { writer.WriteLine(" node.Nodes.Add(Parse"+ ((Bamboo.Parsing.Grammars.Symbol)expressions[i]).Token + "());"); } } writer.WriteLine(" return node;"); writer.WriteLine(" }"); } } } } if (!hasDefault) { writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Syntax error.\");"); writer.WriteLine(" }"); } writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); } foreach (string terminal in grammar.Terminals) { if (!terminal.Equals("EPSILON")) { writer.WriteLine(" private "+ name + "Node Parse" + terminal + "()"); writer.WriteLine(" {"); writer.WriteLine(" "+ name + "Node node = new " + name + "Node(" + name + "NodeType." + terminal + ", this._token.Value);"); writer.WriteLine(" this._token = this._tokenizer.Tokenize(this._reader);"); writer.WriteLine(" return node;"); writer.WriteLine(" }"); writer.WriteLine(""); } } writer.WriteLine(" }"); writer.WriteLine("}"); }
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 class "+ name + "NodePrinter"); writer.WriteLine(" {"); writer.WriteLine(""); writer.WriteLine(" public static void Print("+ name + "Node node, System.IO.TextWriter writer)"); writer.WriteLine(" {"); writer.WriteLine(" Print(node, writer, 0);"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" private static void Print("+ name + "Node node, System.IO.TextWriter writer, int indentationLevel)"); writer.WriteLine(" {"); writer.WriteLine(" switch(node.Type)"); writer.WriteLine(" {"); int i = 0; foreach (string nonterminal in grammar.Nonterminals) { writer.WriteLine(" case "+ name + "NodeType." + nonterminal + " :"); writer.WriteLine(" {"); writer.WriteLine(" for(int i = 0; i < indentationLevel; i++)"); writer.WriteLine(" {"); writer.WriteLine(" System.Console.Write(\" \");"); writer.WriteLine(" }"); writer.WriteLine(" System.Console.WriteLine(\""+ nonterminal + ":\");"); writer.WriteLine(" foreach("+ name + "Node node2 in node.Nodes)"); writer.WriteLine(" {"); writer.WriteLine(" Print(node2, writer, indentationLevel + 1);"); writer.WriteLine(" }"); writer.WriteLine(" break;"); writer.WriteLine(" }"); i++; } foreach (string terminal in grammar.Terminals) { writer.WriteLine(" case "+ name + "NodeType." + terminal + " :"); writer.WriteLine(" {"); writer.WriteLine(" for(int i = 0; i < indentationLevel; i++)"); writer.WriteLine(" {"); writer.WriteLine(" System.Console.Write(\" \");"); writer.WriteLine(" }"); writer.WriteLine(" System.Console.WriteLine(\""+ terminal + ": \" + node.Value);"); writer.WriteLine(" break;"); writer.WriteLine(" }"); i++; } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Invalid node type.\");"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" private "+ name + "NodePrinter()"); writer.WriteLine(" {"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" }"); writer.WriteLine("}"); }
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("}"); }
private static List <Bamboo.Parsing.Grammars.Production> GetProductions(string nonterminal, Bamboo.Parsing.Grammars.Grammar grammar) { List <Bamboo.Parsing.Grammars.Production> productions = new List <Bamboo.Parsing.Grammars.Production>(); foreach (Bamboo.Parsing.Grammars.Production production in grammar.Productions) { if (production.Nonterminal.Equals(nonterminal)) { productions.Add(production); } } return(productions); }
public FollowBuilder(Bamboo.Parsing.Grammars.Grammar grammar, Surf.Set FIRST) { this.grammar = grammar; this.first = FIRST; this.follow = new Surf.Set(); }
public static void GenerateHeader(string name, string multinamespace, Bamboo.Parsing.Grammars.Grammar grammar, Surf.Set PREDICT, System.IO.TextWriter writer) { writer.WriteLine("//"); writer.WriteLine("// " + name + "Parser.h"); writer.WriteLine("//"); writer.WriteLine("// AUTOGENERATED " + System.DateTime.Now + ""); writer.WriteLine("//"); writer.WriteLine(""); writer.WriteLine("#ifndef " + name.ToUpper() + "PARSER_H"); writer.WriteLine("#define " + name.ToUpper() + "PARSER_H"); writer.WriteLine(""); writer.WriteLine("#include <istream>"); writer.WriteLine("#include <vector>"); writer.WriteLine("#include \"" + name + "Token.h\""); writer.WriteLine(""); string[] namespaces = multinamespace.Split(new string[] { "::" }, StringSplitOptions.None); foreach (string nspace in namespaces) { writer.WriteLine("namespace " + nspace + ""); writer.WriteLine("{"); } writer.WriteLine(" class "+ name + "Parser"); writer.WriteLine(" {"); writer.WriteLine(" private:"); writer.WriteLine(" int _currentState;"); writer.WriteLine(" std::vector<int> _states;"); writer.WriteLine(" public:"); writer.WriteLine(" Parser() : _currentState(0) { }"); writer.WriteLine(" virtual ~"+ name + "Parser() { }"); writer.WriteLine(""); writer.WriteLine(" void next("+ name + "Token&);"); writer.WriteLine(""); Dictionary <string, string> constructors = new Dictionary <string, string>(); foreach (string nonterminal in grammar.Nonterminals) { foreach (Surf.Tuple tuple in PREDICT) { int n = (int)tuple[0] + 1; Bamboo.Parsing.Grammars.Production production = (Bamboo.Parsing.Grammars.Production)tuple[1]; Surf.Set predict = (Surf.Set)tuple[2]; if (production.Nonterminal.Equals(nonterminal)) { foreach (string symbol in predict) { List <Bamboo.Parsing.Grammars.Expression> expressions = ToList(production.Expression); if (expressions.Count == 1 && ((Bamboo.Parsing.Grammars.Symbol)expressions[0]).Token == "EPSILON") { } else { string constructor2 = " virtual void beginParse"+ nonterminal; foreach (Bamboo.Parsing.Grammars.Symbol expression in expressions) { constructor2 += "_" + expression.Token; } constructor2 += "() = 0;"; string constructor = " virtual void endParse"+ nonterminal; foreach (Bamboo.Parsing.Grammars.Symbol expression in expressions) { constructor += "_" + expression.Token; } constructor += "() = 0;"; if (!constructors.ContainsKey(constructor)) { writer.WriteLine(constructor2); writer.WriteLine(constructor); constructors.Add(constructor, constructor); } } } } } } writer.WriteLine(""); foreach (string terminal in grammar.Terminals) { if (terminal != "EPSILON") { writer.WriteLine(" virtual void parse"+ terminal + "(" + name + "Token&) = 0;"); } } writer.WriteLine(" };"); foreach (string nspace in namespaces) { writer.WriteLine("}"); } writer.WriteLine("#endif"); }
public static void GenerateClass(string name, string multinamespace, Bamboo.Parsing.Grammars.Grammar grammar, Surf.Set FIRST, Surf.Set FOLLOW, Surf.Set PREDICT, System.IO.TextWriter writer) { writer.WriteLine("//"); writer.WriteLine("// " + name + "Parser.cpp"); writer.WriteLine("//"); writer.WriteLine("// AUTOGENERATED " + System.DateTime.Now + ""); writer.WriteLine("//"); writer.WriteLine(""); writer.WriteLine("#include <istream>"); writer.WriteLine("#include <sstream>"); writer.WriteLine("#include <string>"); writer.WriteLine("#include <vector>"); writer.WriteLine("#include \"" + name + "Parser.h\""); writer.WriteLine("#include \"" + name + "Token.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(" void Parser::next("+ name + "Token& token)"); writer.WriteLine(" {"); writer.WriteLine(" start:"); writer.WriteLine(" switch(_currentState)"); writer.WriteLine(" {"); Dictionary <string, int> states = new Dictionary <string, int>(); int state = 0; foreach (string nonterminal in grammar.Nonterminals) { states.Add(nonterminal, state++); } foreach (string terminal in grammar.Terminals) { if (terminal != "EPSILON") { states.Add(terminal, state++); } } foreach (string nonterminal in grammar.Nonterminals) { bool hasDefault = false; writer.WriteLine(" case "+ states[nonterminal] + ": // parse" + nonterminal); writer.WriteLine(" {"); writer.WriteLine(" switch(token.type())"); writer.WriteLine(" {"); int state2 = state; foreach (Surf.Tuple tuple in PREDICT) { int n = (int)tuple[0] + 1; Bamboo.Parsing.Grammars.Production production = (Bamboo.Parsing.Grammars.Production)tuple[1]; Surf.Set predict = (Surf.Set)tuple[2]; if (production.Nonterminal.Equals(nonterminal)) { foreach (string symbol in predict) { List <Bamboo.Parsing.Grammars.Expression> expressions = ToList(production.Expression); if (expressions.Count == 1 && ((Bamboo.Parsing.Grammars.Symbol)expressions[0]).Token == "EPSILON") { hasDefault = true; } else { writer.WriteLine(" case TokenType::"+ symbol + ":"); writer.WriteLine(" {"); writer.Write(" beginParse"+ nonterminal); foreach (Bamboo.Parsing.Grammars.Symbol expression in expressions) { writer.Write("_" + expression.Token); } writer.WriteLine("();"); writer.Write(" _states.push_back("+ state2++ + "); // endParse" + nonterminal); foreach (Bamboo.Parsing.Grammars.Symbol expression in expressions) { writer.Write("_" + expression.Token); } writer.WriteLine("();"); for (int i = (expressions.Count - 1); i >= 1; i--) { Bamboo.Parsing.Grammars.Symbol expression = (Bamboo.Parsing.Grammars.Symbol)expressions[i]; writer.WriteLine(" _states.push_back("+ states[expression.Token] + "); // parse" + expression.Token); } Bamboo.Parsing.Grammars.Symbol expression2 = (Bamboo.Parsing.Grammars.Symbol)expressions[0]; writer.WriteLine(" _currentState = "+ states[expression2.Token] + "; // parse" + expression2.Token); writer.WriteLine(" goto start;"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } } } } if (states[nonterminal] == 0) { writer.WriteLine(" case "+ name + "TokenType::_EOF_:"); writer.WriteLine(" {"); writer.WriteLine(" if (_states.size() > 0)"); writer.WriteLine(" {"); writer.WriteLine(" _currentState = _states.back();"); writer.WriteLine(" _states.pop_back();"); writer.WriteLine(" goto start;"); writer.WriteLine(" }"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } if (hasDefault) { writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" // EPSILON"); writer.WriteLine(" _currentState = _states.back();"); writer.WriteLine(" _states.pop_back();"); writer.WriteLine(" goto start;"); writer.WriteLine(" }"); } else { writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" std::stringstream stream;"); writer.WriteLine(" stream << __FILE__ << \" \" << __LINE__ << \" \" << \"Syntax error.\";"); writer.WriteLine(" throw stream.str();"); writer.WriteLine(" }"); } writer.WriteLine(" }"); writer.WriteLine(" break;"); writer.WriteLine(" }"); state2 = state; foreach (Surf.Tuple tuple in PREDICT) { int n = (int)tuple[0] + 1; Bamboo.Parsing.Grammars.Production production = (Bamboo.Parsing.Grammars.Production)tuple[1]; Surf.Set predict = (Surf.Set)tuple[2]; if (production.Nonterminal.Equals(nonterminal)) { foreach (string symbol in predict) { List <Bamboo.Parsing.Grammars.Expression> expressions = ToList(production.Expression); if (expressions.Count == 1 && ((Bamboo.Parsing.Grammars.Symbol)expressions[0]).Token == "EPSILON") { } else { writer.Write(" case "+ state2++ + ": // endParse" + nonterminal); foreach (Bamboo.Parsing.Grammars.Symbol expression in expressions) { writer.Write("_" + expression.Token); } writer.WriteLine("();"); writer.WriteLine(" {"); writer.Write(" "+ "endParse" + nonterminal); foreach (Bamboo.Parsing.Grammars.Symbol expression in expressions) { writer.Write("_" + expression.Token); } writer.WriteLine("();"); writer.WriteLine(" if (_states.size() == 0)"); writer.WriteLine(" {"); writer.WriteLine(" _currentState = 0;"); writer.WriteLine(" }"); writer.WriteLine(" else"); writer.WriteLine(" {"); writer.WriteLine(" _currentState = _states.back();"); writer.WriteLine(" _states.pop_back();"); writer.WriteLine(" }"); writer.WriteLine(" goto start;"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } } } } state = state2; } foreach (string terminal in grammar.Terminals) { if (terminal != "EPSILON") { writer.WriteLine(" case "+ states[terminal] + ": // " + terminal); writer.WriteLine(" {"); writer.WriteLine(" parse"+ terminal + "(token);"); writer.WriteLine(" if (_states.size() == 0)"); writer.WriteLine(" {"); writer.WriteLine(" _currentState = 0;"); writer.WriteLine(" }"); writer.WriteLine(" else"); writer.WriteLine(" {"); writer.WriteLine(" _currentState = _states.back();"); writer.WriteLine(" _states.pop_back();"); writer.WriteLine(" }"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" std::stringstream stream;"); writer.WriteLine(" stream << __FILE__ << \" \" << __LINE__ << \" \" << \"Invalid parser state.\";"); writer.WriteLine(" throw stream.str();"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); foreach (string nspace in namespaces) { writer.WriteLine("}"); } }
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 class " + name + "Generator"); writer.WriteLine(" {"); writer.WriteLine(""); writer.WriteLine(" public " + name + "Generator()"); writer.WriteLine(" {"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" public void Generate(" + name + "Node node, System.IO.TextWriter writer)"); writer.WriteLine(" {"); writer.WriteLine(" bool writeWhitespace = false;"); writer.WriteLine(""); writer.WriteLine(" Generate(node, writer, ref writeWhitespace);"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" private void Generate(" + name + "Node node, System.IO.TextWriter writer, ref bool writeWhitespace)"); writer.WriteLine(" {"); writer.WriteLine(" switch(node.Type)"); writer.WriteLine(" {"); foreach (string nonterminal in grammar.Nonterminals) { writer.WriteLine(" case " + name + "NodeType." + nonterminal + ":"); writer.WriteLine(" {"); writer.WriteLine(" for(int i = 0; i < node.Nodes.Count; i++)"); writer.WriteLine(" {"); writer.WriteLine(" Generate(node.Nodes[i], writer, ref writeWhitespace);"); writer.WriteLine(" }"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } foreach (string terminal in grammar.Terminals) { writer.WriteLine(" case " + name + "NodeType." + terminal + ":"); writer.WriteLine(" {"); writer.WriteLine(" if(writeWhitespace)"); writer.WriteLine(" {"); writer.WriteLine(" writer.Write(\" \");"); writer.WriteLine(" }"); writer.WriteLine(" writer.Write(node.Value);"); writer.WriteLine(" writeWhitespace = true;"); writer.WriteLine(" break;"); writer.WriteLine(" }"); } writer.WriteLine(" default:"); writer.WriteLine(" {"); writer.WriteLine(" throw new System.Exception(\"Invalid node type.\");"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(""); writer.WriteLine(" }"); writer.WriteLine("}"); }