Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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.");
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        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");
        }
Esempio n. 4
0
        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("}");
        }
Esempio n. 5
0
        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("}");
            }
        }