private static string GetFirstSymbol(Bamboo.Parsing.Grammars.Expression expression) { if (expression is Bamboo.Parsing.Grammars.Symbol) { Bamboo.Parsing.Grammars.Symbol symbol = (Bamboo.Parsing.Grammars.Symbol)expression; return(symbol.Token); } else if (expression is Bamboo.Parsing.Grammars.Concatenation) { Bamboo.Parsing.Grammars.Concatenation concatenation = (Bamboo.Parsing.Grammars.Concatenation)expression; return(GetFirstSymbol(concatenation.Expressions[0])); } else { throw new System.Exception("INVALID"); } }
private static List <Bamboo.Parsing.Grammars.Expression> ToList(Bamboo.Parsing.Grammars.Expression expression) { List <Bamboo.Parsing.Grammars.Expression> list = new List <Bamboo.Parsing.Grammars.Expression>(); if (expression is Bamboo.Parsing.Grammars.Symbol) { Bamboo.Parsing.Grammars.Symbol symbol = (Bamboo.Parsing.Grammars.Symbol)expression; list.Add(symbol); } else if (expression is Bamboo.Parsing.Grammars.Concatenation) { Bamboo.Parsing.Grammars.Concatenation concatenation = (Bamboo.Parsing.Grammars.Concatenation)expression; foreach (Bamboo.Parsing.Grammars.Symbol symbol in concatenation.Expressions) { list.Add(symbol); } } else { throw new System.Exception("INVALID"); } return(list); }
private static bool CanResolve(Bamboo.Parsing.Grammars.Expression expression, List <Bamboo.Parsing.Grammars.Production> remaining) { if (expression is Bamboo.Parsing.Grammars.Symbol) { Bamboo.Parsing.Grammars.Symbol symbol = (Bamboo.Parsing.Grammars.Symbol)expression; foreach (Bamboo.Parsing.Grammars.Production production in remaining) { if (production.Nonterminal.Equals(symbol.Token)) { return(false); } } return(true); } else if (expression is Bamboo.Parsing.Grammars.Concatenation) { Bamboo.Parsing.Grammars.Concatenation concatenation = (Bamboo.Parsing.Grammars.Concatenation)expression; return(CanResolve(concatenation.Expressions[0], remaining)); } else { throw new System.Exception("INVALID"); } }
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 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("}"); } }