Exemple #1
0
        static int ParseFiles(string grammarFile, string rootParserName, List <string> sourceFiles, string outputFormat)
        {
            if (string.IsNullOrEmpty(grammarFile))
            {
                WriteError("Expected a grammar file path");
                return(1);
            }

            Parser parser = new ExtendedBackusNaurFormParser();

            if (!TryParse(parser, grammarFile))
            {
                return(1);
            }

            try {
                parser = ParserGenerator.FromEBnf(File.ReadAllText(grammarFile), rootParserName);
            } catch (ParserGenerationException e) {
                foreach (var semanticError in e.Errors)
                {
                    WriteError("{0}({2},{3}): {1}", grammarFile, semanticError.Message, semanticError.LineNumber, semanticError.ColumnNumber);
                }
            }

            var error = false;

            foreach (var file in sourceFiles)
            {
                error |= TryParse(parser, file, outputFormat);
            }

            return(error ? 1 : 0);
        }
Exemple #2
0
        private void bPGG_Click(object sender, EventArgs e)
        {
            try
            {
                var gen = ParserGenerator.GetGenerator(rtbPGNT.Text.Split(','), rtbPGT.Lines.Select(x => x.Trim()).Select(x =>
                                                                                                                          new Tuple <string, string> (x.Split(',')[0], x.Substring(x.Split(',')[0].Length + 1).Trim())).ToArray(),
                                                       rtbPGPR.Lines.Select(x => x.Trim()).ToArray(), rtbPGC.Lines.Select(x => x.Trim()).ToArray());

                rtbPGS.Clear();
                gen.GlobalPrinter.Clear();
                gen.PrintProductionRules();
                if (rbSLR.Checked == true)
                {
                    gen.Generate();
                }
                else if (rbLALR.Checked == true)
                {
                    gen.GenerateLALR();
                }
                else
                {
                    gen.GenerateLR1();
                }
                gen.PrintStates();
                gen.PrintTable();
                rtbPGS.AppendText(gen.GlobalPrinter.ToString());
                srparser = gen.CreateShiftReduceParserInstance();
            }
            catch (Exception ex)
            {
                rtbPGS.AppendText("Generate Error!\r\n" + ex.Message + "\r\n" + ex.StackTrace);
            }
        }
Exemple #3
0
        private string GenerateParser()
        {
            var g = new ParserGenerator();

            var sw = new StringWriter();
            g.Execute(sw, new GrammarInfo(typeof(TestGrammar)));

            return sw.ToString();
        }
        public void TestParseErrorGetsReported()
        {
            // Create an instance of our language grammar and set handlers for its rules.
            LanguageGrammar<Expression> g = new LanguageGrammar<Expression>();

            g.DivideRule.Action = (e1, e2) => Expression.Divide(e1, e2);
            g.DoubleLiteralRule.Action = (d) => Expression.Constant(d);
            g.IntLiteralRule.Action = (i) => Expression.Constant(i);
            g.StringLiteralRule.Action = (s) => Expression.Constant(s);
            g.MinusRule.Action = (e1, e2) => Expression.Subtract(e1, e2);
            g.ModRule.Action = (e1, e2) => Expression.Modulo(e1, e2);
            g.MultiplyRule.Action = (e1, e2) => Expression.Multiply(e1, e2);
            g.NegateRule.Action = (e) => Expression.Negate(e);
            g.PlusRule.Action = (e1, e2) => Expression.Add(e1, e2);
            g.VariableRefRule.SetStatefulAction<ParserState>((s, name) => s.GetVariable(name));

            // Spin up a parser for our language.
            // TODO: Package this up and simplify it.
            var expressionHelper = new ExpressionHelper();
            var classifierSession = new TerminalClassifierSession<char, ParserState, int>()
                .AddSkipTerminal(new Terminal<char> { Name = "Whitespace", InitialState = RegexCharNFABuilder.RegexCompiler(@"\s+") })
                .CurrentCharExprIs(x => x.CurrentChar())
                .GetFromMarkExprIs(x => x.GetFromMarkedPos())
                .HasCurrentCharExprIs(x => x.HasCurrentChar())
                .MarkPosExprIs(x => x.MarkPos())
                .MoveNextCharExprIs(x => x.MoveNextChar())
                .GetLocationIs(x=>new ParseLocation {Line = 1, Column = x.GetPos()})
                .ErrorCollectionIs(x=>x.Errors)
                .UnmarkPosExprIs(x => x.UnmarkPos());

            var parserGen = new ParserGenerator<char>(expressionHelper);
            var parseTableBuilder = new LRParseTableBuilder();
            var parseTable = parseTableBuilder.BuildParseTable(g);
            var session = parserGen.NewSession<ParserState>()
                .NonTerminalValueExprIs<object>(x => x.NonTerminalValue)
                .TerminalValueExprIs<string>(x => x.TerminalStringValue)
                .TerminalValueExprIs<int>(x => x.TerminalIntValue)
                .TerminalValueExprIs<double>(x => x.TerminalDoubleValue)
                .TerminalIs(x => x.Terminal)
                .NonTerminalIs(x => x.NonTerminal)
                .IncludeSymbols(true)
                .DebugOutputIs(x => Debug.WriteLine(x))
                .Generate("LanguageParser", parseTable, classifierSession);
            // At this point, session is an Expression<ParserState,int> representing our parser.
            // We can compile it into a delegate or a MethodBuilder.  For the examples, we'll use a delegate.
            var compiler = session.Compile();

            // Create a parser state object and initialize it.
            ParserState ps = new ParserState("x*y +* 2.0");
            ps.SetParameters(
                Expression.Parameter(typeof(double), "x"),
                Expression.Parameter(typeof(double), "y"));
            Assert.AreNotEqual(0, compiler(ps));
            Assert.AreNotEqual(0, ps.Errors.Count);
            Assert.Less(ps.Errors.First().ExpectedTerminalNames.Count, g.Terminals.Count);
        }
        private string GenerateParser()
        {
            var g = new ParserGenerator();

            var sw = new StringWriter();

            g.Execute(sw, new GrammarInfo(typeof(TestGrammar)));

            return(sw.ToString());
        }
Exemple #6
0
        static void TestGenerationSample()
        {
            var g = Grammar.FromTokens("S'", "$", "S", "C", "C", "c", "d");

            g.Matches("S'", "S");
            g.Matches("S", "C", "C");
            g.Matches("C", "c", "C");
            g.Matches("C", "d");
            var gen = new ParserGenerator(g);
            var tab = gen.GenerateParserTable();
        }
        /// <summary>
        /// HTML Parser를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var html        = gen.CreateNewProduction("HTML", false);
            var annote      = gen.CreateNewProduction("ANNOTATE", false);  // <!-- ~ -->
            var annote2     = gen.CreateNewProduction("ANNOTATE2", false); // <!~>
            var tag_closing = gen.CreateNewProduction("CLOSING", false);   // <~> ~ </~>
            var tag_aio     = gen.CreateNewProduction("ALLINONE", false);  // <~/>

            // Terminals
            var open          = gen.CreateNewProduction("open");
            var empty_open    = gen.CreateNewProduction("empty-open");
            var close         = gen.CreateNewProduction("close");
            var empty_close   = gen.CreateNewProduction("empty-close");
            var annoate_open  = gen.CreateNewProduction("annoate-open");
            var annoate_close = gen.CreateNewProduction("annoate-close");
            var annoate2_open = gen.CreateNewProduction("annoate2-open");
            var tag_name      = gen.CreateNewProduction("tag-name");
            var attr_name     = gen.CreateNewProduction("attr-name");

            html |= annoate_open + annote + annoate_close;
            html |= annoate_open + annote2;
            html |= tag_closing;
            html |= tag_aio;
            html |= html + html;
            html |= ParserGenerator.EmptyString;



            try
            {
                gen.PushStarts(html);
                gen.PrintProductionRules();
                gen.GenerateLALR();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateShiftReduceParserInstance());
        }
Exemple #8
0
        public void Ebnf()
        {
            var parserGen = new ParserGenerator();

            var grammar  = $@"
{RuleName.Equals} = ""="";
{RuleName.Pipe} = ""|"";
{RuleName.Asterisk} = ""*"";
{RuleName.QuestionMark} = ""?"";
{RuleName.ExclamationPoint} = ""!"";
{RuleName.Semicolon} = "";"";
{RuleName.LeftParenthesis} = ""("";
{RuleName.RightParenthesis} = "")"";

{RuleName.Whitespace} = /\s+/;
{RuleName.Identifier} = /\w(?:\w|\d)*/;
{RuleName.String} = /""(\\\\[^""]|\\\\""|[^""])*""/;
{RuleName.Regex} = /\/(\\\\[^\/]|\\\\\/|[^\/])+\//;
{RuleName.LineComment} = /\/\/[^{"\r\n"}]*(?=[{"\r\n"}])/;

{RuleName.And} = {RuleName.SimpleExpression} {RuleName.Expression};
{RuleName.Or} = {RuleName.SimpleExpression} {RuleName.Pipe} {RuleName.Expression};
{RuleName.Not} = {RuleName.ExclamationPoint} {RuleName.Expression};
{RuleName.Optional} = {RuleName.QuestionMark} {RuleName.Expression};
{RuleName.Repeat} = {RuleName.Asterisk} {RuleName.Expression};
{RuleName.Group} = {RuleName.LeftParenthesis} {RuleName.Expression} {RuleName.RightParenthesis};

{RuleName.Literal} = {RuleName.String} | {RuleName.Regex};
{RuleName.SimpleExpression} = {RuleName.Not} | {RuleName.Optional} | {RuleName.Repeat} | {RuleName.Group} | {RuleName.Identifier};
{RuleName.Expression} = {RuleName.Or} | {RuleName.And} | {RuleName.SimpleExpression};

{RuleName.Token} = {RuleName.Identifier} {RuleName.Equals} {RuleName.Literal} {RuleName.Semicolon};
{RuleName.Rule} = {RuleName.Identifier} {RuleName.Equals} {RuleName.Expression} {RuleName.Semicolon};

// This is a comment.
{RuleName.Root} = *({RuleName.Token} | {RuleName.Rule});
";
            var settings = new ParserSettings
            {
                Algorithm   = Parser.Algorithm.LL,
                NestingType = Parser.NestingType.Recursion,
                Unit        = Parser.Unit.Lexeme,
            };
            Parser parser = parserGen.SpawnParser(settings, grammar, RuleName.Whitespace, RuleName.LineComment);

            parser.Lock();

            BranchParseNode result = parser.ParseSyntax(grammar);

            Assert.AreEqual(grammar, result.MatchedText);
        }
Exemple #9
0
        static void TestGenerationAmbiguous()
        {
            var g = Grammar.FromTokens("E", "+", "-", "*", "/", "N", "(", ")", "x");

            g.Matches("E", "N");
            g.MatchesRight("E", "E", "+", "E");
            g.MatchesRight("E", "E", "-", "E");
            g.MatchesLeft("E", "E", "*", "E");
            g.MatchesLeft("E", "E", "/", "E");
            g.MatchesLeft("E", "-", "E");
            g.Matches("E", "(", "E", ")");
            g.Matches("N", "x");
            g.Matches("N", "N", "x");
            var gen = new ParserGenerator(g);
            var tab = gen.GenerateParserTable();

            Console.WriteLine("Constructed table with {0} states.", tab.Length);
            var parser = new RunTimeParser <double>(tab, new RunTimeParser <double> .RuntimeParserAction[]
            {
                seg => seg.Array[seg.Offset],
                seg => seg.Array[seg.Offset],
                seg => seg.Array[seg.Offset] + seg.Array[seg.Offset + 2],
                seg => seg.Array[seg.Offset] - seg.Array[seg.Offset + 2],
                seg => seg.Array[seg.Offset] * seg.Array[seg.Offset + 2],
                seg => seg.Array[seg.Offset] / seg.Array[seg.Offset + 2],
                seg => - seg.Array[seg.Offset + 1],
                seg => seg.Array[seg.Offset + 1],
                seg => seg.Array[seg.Offset],
                seg => 10 * seg.Array[seg.Offset] + seg.Array[seg.Offset + 1]
            });

            while (true)
            {
                Console.Write(">");
                var line = Console.ReadLine();
                if (string.IsNullOrEmpty(line))
                {
                    break;
                }
                parser.SetInput(Tokenize(line));
                try
                {
                    var res = parser.Parse();
                    Console.WriteLine("Res={0}", res);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ERROR: {0}", ex);
                }
            }
        }
        static ReflectionCommands()
        {
            const string ebnf = @"
                (* skip-whitespace omit-from-hierarchy *)
                Location Root = Location, End of Input;

                (* skip-whitespace omit-from-hierarchy *)
                Value Root = Value, End of Input;

                Location = ""["", Root, ""]"", {Accessor};

                (* omit-from-hierarchy *) Root     = Networkable Identifier | Type Name;
                (* omit-from-hierarchy *) Accessor = Member Access | Component Access | Invocation;

                Member Access = ""."", Identifier;
                Component Access = ""<"", Type Name, "">"";

                Invocation = ""("", [Value, {"","", Value}], "")"";

                (* omit-from-hierarchy *)
                Value = Null | Boolean | Vector | Float | Double | (""0x"", Hex Integer) | Integer | String | Location;

                Boolean = True | False;
                Vector = ""Vector"", Invocation;

                Float = (Integer | Decimal), ""f"";
                Double = Decimal, [""d""];

                String = ""'"", {(""\\"", Escaped Character) | Single Character}, ""'"";

                (* collapse *) End of Input = ? /$/ ?;
                (* collapse *) Single Character = ? /[^\\']/ ?;
                (* collapse *) Escaped Character = ? /[\\'rnt]/ ?;
                (* collapse *) Integer = ? /-?[0-9]+/ ?;
                (* collapse *) Hex Integer = ? /[0-9A-F]/i ?;
                (* collapse *) Decimal = ? /-?[0-9]+\.[0-9]+/ ?;

                (* collapse *) Networkable Identifier = ? /[0-9]+/ ?;
                (* collapse *) Type Name = ? /[^0-9\]>][^\]>]*/ ?;
                (* collapse *) Component Name = Type Name;
                (* collapse *) Null = ""null"";
                (* collapse *) True = ? /[Tt]rue/ ?;
                (* collapse *) False = ? /[Ff]alse/ ?;
                (* collapse *) Identifier = ? /[A-Za-z_][A-Za-z0-9_]*/ ?;";

            _sLocationParser = ParserGenerator.FromEBnf(ebnf, "Location Root");
            _sValueParser    = ParserGenerator.FromEBnf(ebnf, "Value Root");
        }
Exemple #11
0
        public void Emit(CompilationContext context)
        {
            var grammar = System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
                          .Where(c => c.Namespace == "CmC.Compiler.Syntax.Assembly" || c.Namespace == "CmC.Compiler.Syntax.Common")
                          .Where(c => typeof(ILanguageToken).IsAssignableFrom(c))
                          .Select(t => (ILanguageToken)Activator.CreateInstance(t, null)).ToList();

            var generator = new ParserGenerator(grammar);

            LanguageParser parser = generator.GetParser();

            var tokens = parser.Parse(AssemblySource, "ASM_INSTRUCTION");

            foreach (var token in tokens)
            {
                ((ICodeEmitter)token).Emit(context);
            }
        }
Exemple #12
0
        private static void ProcessSourceText(string text, CompilationContext context)
        {
            var grammar = Assembly.GetExecutingAssembly().GetTypes()
                          .Where(c => c.Namespace == "CmC.Compiler.Syntax" || c.Namespace == "CmC.Compiler.Syntax.Common")
                          .Where(c => typeof(ILanguageToken).IsAssignableFrom(c))
                          .Select(t => (ILanguageToken)Activator.CreateInstance(t, null));

            var generator = new ParserGenerator(grammar.ToList());

            LanguageParser parser = generator.GetParser();

            var tokens = parser.Parse(text);

            foreach (var token in tokens)
            {
                ((ICodeEmitter)token).Emit(context);
            }
        }
Exemple #13
0
        private Parser()
        {
            Lingua.Grammar grammar = new Lingua.Grammar();
            grammar.Load(Assembly.GetCallingAssembly(), "Prolog");
            grammar.LoadRules(Assembly.GetCallingAssembly(), "Prolog");
            grammar.Resolve();
            m_grammar = grammar;

            TerminalReaderGenerator       terminalReaderGenerator       = new TerminalReaderGenerator();
            TerminalReaderGeneratorResult terminalReaderGeneratorResult = terminalReaderGenerator.GenerateTerminalReader(m_grammar);

            m_terminalReader = terminalReaderGeneratorResult.TerminalReader;

            ParserGenerator       parserGenerator       = new ParserGenerator();
            ParserGeneratorResult parserGeneratorResult = parserGenerator.GenerateParser(m_grammar);

            m_parser = parserGeneratorResult.Parser;
        }
Exemple #14
0
        static void TestGeneration()
        {
            var g = Grammar.FromTokens("E'", "$", "E", "T", "F", "P", "w", "(", ")", "+", "*", "?", "|");

            g.Matches("E'", "E", "$");
            g.Matches("E", "T");
            g.Matches("E", "E", "|", "T");
            g.Matches("T", "F");
            g.Matches("T", "T", "F");
            g.Matches("F", "P");
            g.Matches("F", "P", "*");
            g.Matches("F", "P", "+");
            g.Matches("F", "P", "?");
            g.Matches("P", "w");
            g.Matches("P", "(", "E", ")");
            var gen = new ParserGenerator(g);
            var tab = gen.GenerateParserTable();
        }
Exemple #15
0
        static void ProcessPGSample()
        {
            var gen = new ParserGenerator();

            // Non-Terminals
            var exp       = gen.CreateNewProduction("exp", false);
            var term      = gen.CreateNewProduction("term", false);
            var factor    = gen.CreateNewProduction("factor", false);
            var func      = gen.CreateNewProduction("func", false);
            var arguments = gen.CreateNewProduction("args", false);

            // Terminals
            var plus     = gen.CreateNewProduction("plus");     // +
            var minus    = gen.CreateNewProduction("minus");    // -
            var multiple = gen.CreateNewProduction("multiple"); // *
            var divide   = gen.CreateNewProduction("divide");   // /
            var id       = gen.CreateNewProduction("id");       // [_$a-zA-Z][_$a-zA-Z0-9]*
            var op_open  = gen.CreateNewProduction("op_open");  // (
            var op_close = gen.CreateNewProduction("op_close"); // )
            var num      = gen.CreateNewProduction("num");      // [0-9]+
            var split    = gen.CreateNewProduction("split");    // ,

            exp       |= exp + plus + term;
            exp       |= exp + minus + term;
            exp       |= term;
            term      |= term + multiple + factor;
            term      |= term + divide + factor;
            term      |= factor;
            factor    |= op_open + exp + op_close;
            factor    |= num;
            factor    |= id;
            factor    |= func;
            func      |= id + op_open + arguments + op_close;
            arguments |= id;
            arguments |= arguments + split + id;
            arguments |= ParserGenerator.EmptyString;

            gen.PushStarts(exp);
            gen.GenerateLALR();
            gen.PrintStates();
            gen.PrintTable();

            Console.Instance.WriteLine(gen.GlobalPrinter.ToString());
        }
Exemple #16
0
        Parser()
        {
            var grammar = new Lingua.Grammar();

            grammar.Load(Assembly.GetCallingAssembly(), "Prolog");
            grammar.LoadRules(Assembly.GetCallingAssembly(), "Prolog");
            grammar.Resolve();
            Grammar = grammar;

            var terminalReaderGenerator       = new TerminalReaderGenerator();
            var terminalReaderGeneratorResult = terminalReaderGenerator.GenerateTerminalReader(Grammar);

            _terminalReader = terminalReaderGeneratorResult.TerminalReader;

            var parserGenerator       = new ParserGenerator();
            var parserGeneratorResult = parserGenerator.GenerateParser(Grammar);

            _parser = parserGeneratorResult.Parser;
        }
Exemple #17
0
        public IEnumerable <CodeGenerator> DoGeneration()
        {
            // generation requires two runs - first we collect the grammar
            yield return(this);

            // process the grammar
            _productions = _grammar.Productions.ToArray();
            var generator = new ParserGenerator(_grammar);
            var table     = generator.GenerateParserTable();

            // on second run we render the code and insert the actions.
            WriteLine(PreParser.Replace("{VALUETYPE}", _valueType));
            // write the token enum
            WriteTokenEnum();
            // write the parser table code
            WriteParserTableCode(table);
            // put in the actions at the end using a second run
            yield return(this);

            EndAction(); // (manually close the last action)
            // write the end of the parser function
            WriteLine(PostParser);
        }
Exemple #18
0
        /// <summary>
        /// SRCAL의 파서제너레이터를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var script   = gen.CreateNewProduction("script", false);
            var line     = gen.CreateNewProduction("line", false);
            var lines    = gen.CreateNewProduction("lines", false);
            var expr     = gen.CreateNewProduction("expr", false);
            var block    = gen.CreateNewProduction("block", false);
            var iblock   = gen.CreateNewProduction("iblock", false);
            var index    = gen.CreateNewProduction("index", false);
            var variable = gen.CreateNewProduction("variable", false);
            var argument = gen.CreateNewProduction("argument", false);
            var function = gen.CreateNewProduction("function", false);
            var runnable = gen.CreateNewProduction("runnable", false);

            // Terminals
            var name     = gen.CreateNewProduction("name");
            var _const   = gen.CreateNewProduction("const"); // number | string
            var loop     = gen.CreateNewProduction("loop");
            var op_open  = gen.CreateNewProduction("op_open");
            var op_close = gen.CreateNewProduction("op_close");
            var pp_open  = gen.CreateNewProduction("pp_open");  // [
            var pp_close = gen.CreateNewProduction("pp_close"); // ]
            var equal    = gen.CreateNewProduction("equal");
            var to       = gen.CreateNewProduction("to");
            var scolon   = gen.CreateNewProduction("scolon");
            var comma    = gen.CreateNewProduction("comma");
            var _foreach = gen.CreateNewProduction("foreach");
            var _if      = gen.CreateNewProduction("if");
            var _else    = gen.CreateNewProduction("else");

            script |= lines + ParserAction.Create(x => { });
            script |= ParserGenerator.EmptyString + ParserAction.Create(x => { });

            block |= pp_open + iblock + pp_close + ParserAction.Create(x => { });
            block |= line + ParserAction.Create(x => { });

            iblock |= block + ParserAction.Create(x => { });
            iblock |= lines + ParserAction.Create(x => { });
            iblock |= ParserGenerator.EmptyString + ParserAction.Create(x => { });

            line |= expr + ParserAction.Create(x => { });

            lines |= expr + ParserAction.Create(x => { });
            lines |= expr + lines + ParserAction.Create(x => { });

            expr |= function + ParserAction.Create(x => { });
            expr |= name + equal + index + ParserAction.Create(x => { });
            expr |= runnable + ParserAction.Create(x => { });

            function |= name + op_open + op_close + ParserAction.Create(x => { });
            function |= name + op_open + argument + op_close + ParserAction.Create(x => { });

            argument |= index + ParserAction.Create(x => { });
            argument |= index + comma + argument + ParserAction.Create(x => { });

            index |= variable + ParserAction.Create(x => { });
            index |= variable + pp_open + variable + pp_close + ParserAction.Create(x => { });

            variable |= name + ParserAction.Create(x => { });
            variable |= function + ParserAction.Create(x => { });
            variable |= _const + ParserAction.Create(x => { });

            runnable |= loop + op_open + name + equal + index + to + index + op_close + block + ParserAction.Create(x => { });
            runnable |= _foreach + op_open + name + scolon + index + op_close + block + ParserAction.Create(x => { });
            runnable |= _if + op_open + index + op_close + block + ParserAction.Create(x => { });
            runnable |= _if + op_open + index + op_close + block + _else + block + ParserAction.Create(x => { });

            gen.PushConflictSolver(true, _else);
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(runnable, 2));

            try
            {
                gen.PushStarts(script);
                gen.PrintProductionRules();
                gen.GenerateLALR();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateShiftReduceParserInstance());
        }
Exemple #19
0
        /// <summary>
        /// ESRCAL의 파서제너레이터를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var expr = gen.CreateNewProduction("expr", false);

            // Terminals
            //var id = gen.CreateNewProduction("id");
            var num = gen.CreateNewProduction("num");
            //var str = gen.CreateNewProduction("str");
            var plus     = gen.CreateNewProduction("plus");
            var minus    = gen.CreateNewProduction("minus");
            var multiple = gen.CreateNewProduction("multiple");
            var divide   = gen.CreateNewProduction("divide");
            //var loop = gen.CreateNewProduction("loop");
            var op_open  = gen.CreateNewProduction("op_open");
            var op_close = gen.CreateNewProduction("op_close");

            //var pp_open = gen.CreateNewProduction("pp_open"); // [
            //var pp_close = gen.CreateNewProduction("pp_close"); // ]
            //var equal = gen.CreateNewProduction("equal");
            //var to = gen.CreateNewProduction("to");
            //var scolon = gen.CreateNewProduction("scolon");
            //var comma = gen.CreateNewProduction("comma");
            //var _foreach = gen.CreateNewProduction("foreach");
            //var _if = gen.CreateNewProduction("if");
            //var _else = gen.CreateNewProduction("else");

            expr |= num + ParserAction.Create(x => x.UserContents = double.Parse(x.Contents));
            expr |= expr + plus + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents + (double)x.Childs[2].UserContents);
            expr |= expr + minus + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents - (double)x.Childs[2].UserContents);
            expr |= expr + multiple + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents * (double)x.Childs[2].UserContents);
            expr |= expr + divide + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents / (double)x.Childs[2].UserContents);
            expr |= minus + expr + ParserAction.Create(x => x.UserContents = -(double)x.Childs[1].UserContents);
            expr |= op_open + expr + op_close + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);

            // right associativity, -
            gen.PushConflictSolver(false, new Tuple <ParserProduction, int>(expr, 5));
            // left associativity, *, /
            gen.PushConflictSolver(true, multiple, divide);
            // left associativity, +, -
            gen.PushConflictSolver(true, plus, minus);

            try
            {
                gen.PushStarts(expr);
                gen.PrintProductionRules();
                gen.GenerateLALR();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateShiftReduceParserInstance());
        }
 public void Setup()
 {
     _parserGenerator = new ParserGenerator();
 }
        static void Main(string[] args)
        {
            IClassGenerator  classGenerator  = new ClassGenerator();
            IBNFAnalyzer     bnfAnalyzer     = new BNFAnalyzer();
            IBNFParser       bnfParser       = new BNFParser();
            IParserGenerator parserGenerator = new ParserGenerator(bnfAnalyzer);

#if GENERATEGENERATOR
            Console.WriteLine("Generating generator...");
            BNF         bnf = bnfParser.Parse("../../docs/translator.bnf");
            string      translatorParserName  = "TranslatorParser";
            string      translatorVisitorName = "TranslatorVisitor";
            string      dataNamespace         = "Generator.Translation.Data";
            string      parsingNamespace      = "Generator.Translation.Parsing";
            string      visitorNamespace      = "Generator.Translation.Visitors";
            ClassType[] translatorParser      = parserGenerator.GenerateParserClasses(bnf, translatorParserName, dataNamespace, parsingNamespace);
            ClassType[] translatorVisitors    = parserGenerator.GenerateVisitorClasses(bnf, translatorVisitorName, dataNamespace, visitorNamespace);
            ClassType[] translatorData        = parserGenerator.GenerateSyntaxTreeClasses(bnf, translatorVisitorName, dataNamespace, visitorNamespace);
            var         classTypes            = translatorData.Union(translatorVisitors).Union(translatorParser);
            foreach (ClassType classType in classTypes)
            {
                string folder = $"../{string.Join("/", classType.NameSpace.Split('.'))}";
                Directory.CreateDirectory(folder);
                classGenerator.Generate(classType, $"{folder}/{classType.Identifier.Split('<')[0]}.cs");
            }
            Console.WriteLine($"...DONE {2 + classTypes.Count()} classes generated.");
#else
            ITranslatorGenerator translatorGenerator = new TranslatorGenerator();
            Console.WriteLine("Generating compiler...");
            Console.WriteLine("\tGenerating parser...");
            BNF                     bnf = bnfParser.Parse("../../docs/tang.bnf");
            string                  programParserName    = "ProgramParser";
            string                  programVisitorName   = "ProgramVisitor";
            string                  dataNamespace        = "Compiler.Parsing.Data";
            string                  parsingNamespace     = "Compiler.Parsing";
            string                  visitorNamespace     = "Compiler.Parsing.Visitors";
            ClassType[]             programParserClasses = parserGenerator.GenerateParserClasses(bnf, programParserName, dataNamespace, parsingNamespace);
            ClassType[]             programVisitors      = parserGenerator.GenerateVisitorClasses(bnf, programVisitorName, dataNamespace, visitorNamespace);
            ClassType[]             programData          = parserGenerator.GenerateSyntaxTreeClasses(bnf, programVisitorName, dataNamespace, visitorNamespace);
            IEnumerable <ClassType> classesToGenerate    = programData.Union(programVisitors).Union(programParserClasses);
            Console.WriteLine("\tGenerating Translators...");
            Lexer lexer = new Lexer("../../docs/translator.tokens.json");

            try
            {
                IEnumerator <Translation.Data.Token> tokens = lexer.Analyse(File.ReadAllText("../../docs/tang-ast.translator"), "ast-c.translator").Select(t => new Translation.Data.Token()
                {
                    FileName = "tang-ast.translator",
                    Name     = t.Name,
                    Value    = t.Value,
                    Row      = t.Row,
                    Column   = t.Column
                }).GetEnumerator();
                tokens.MoveNext();

                IEnumerator <Translation.Data.Token> toCTranslatorTokens = lexer.Analyse(File.ReadAllText("../../docs/ast-c.translator"), "ast-c.translator").Select(t => new Translation.Data.Token()
                {
                    FileName = "ast-c.translator",
                    Name     = t.Name,
                    Value    = t.Value,
                    Row      = t.Row,
                    Column   = t.Column
                }).GetEnumerator();
                toCTranslatorTokens.MoveNext();

                TranslatorParser translatorParser = new TranslatorParser();

                Translation.Data.Translator astTranslator = translatorParser.ParseTranslator(tokens);

                Translation.Data.Translator cTranslator = translatorParser.ParseTranslator(toCTranslatorTokens);

                string translatorName             = "ProgramToASTTranslator";
                string translatorNamespace        = "Compiler.Translation.ProgramToAST";
                string cTranslatorName            = "ASTToCTranslator";
                string cTranslatorNamespace       = "Compiler.Translation.ASTToC";
                string symbolTableDataNamspace    = "Compiler.Translation.SymbolTable.Data";
                string symbolTableVisitorNamspace = "Compiler.Translation.SymbolTable.Visitors";
                string symbolTableVisitorName     = "SymbolTableVisitor";
                string astDataNamspace            = "Compiler.AST.Data";
                string astVisitorNamespace        = "Compiler.AST.Visitors";
                string astVisitorName             = "ASTVisitor";
                string cDataNamspace     = "Compiler.C.Data";
                string cVisitorNamespace = "Compiler.C.Visitors";
                string cVisitorName      = "CVisitor";

                BNF cGrammar           = bnfParser.Parse("../../docs/c.bnf");
                BNF astGrammar         = bnfParser.Parse("../../docs/ast.bnf");
                BNF symbolTableGrammar = bnfParser.Parse("../../docs/symboltable.bnf");

                classesToGenerate = classesToGenerate.Union(parserGenerator.GenerateVisitorClasses(symbolTableGrammar, symbolTableVisitorName, symbolTableDataNamspace, symbolTableVisitorNamspace));
                classesToGenerate = classesToGenerate.Union(parserGenerator.GenerateSyntaxTreeClasses(symbolTableGrammar, symbolTableVisitorName, symbolTableDataNamspace, symbolTableVisitorNamspace));
                classesToGenerate = classesToGenerate.Union(parserGenerator.GenerateVisitorClasses(astGrammar, astVisitorName, astDataNamspace, astVisitorNamespace));
                classesToGenerate = classesToGenerate.Union(parserGenerator.GenerateSyntaxTreeClasses(astGrammar, astVisitorName, astDataNamspace, astVisitorNamespace));
                classesToGenerate = classesToGenerate.Union(parserGenerator.GenerateVisitorClasses(cGrammar, cVisitorName, cDataNamspace, cVisitorNamespace));
                classesToGenerate = classesToGenerate.Union(parserGenerator.GenerateSyntaxTreeClasses(cGrammar, cVisitorName, cDataNamspace, cVisitorNamespace));

                List <RelationDomain> relationDomains = new List <RelationDomain>()
                {
                    new RelationDomain()
                    {
                        Identifier = "Program", Grammar = bnf, DataNamespace = dataNamespace, VisitorNamespace = visitorNamespace
                    },
                    new RelationDomain()
                    {
                        Identifier = "AST", Grammar = astGrammar, DataNamespace = astDataNamspace, VisitorNamespace = astVisitorNamespace
                    },
                    new RelationDomain()
                    {
                        Identifier = "SymbolTable", Grammar = symbolTableGrammar, DataNamespace = symbolTableDataNamspace, VisitorNamespace = symbolTableVisitorNamspace
                    },
                };

                ClassType toASTTranslator = translatorGenerator.GenerateTranslatorClass(astTranslator, translatorName, relationDomains, translatorNamespace);

                classesToGenerate = classesToGenerate.Append(toASTTranslator);

                List <RelationDomain> cRelationDomains = new List <RelationDomain>()
                {
                    new RelationDomain()
                    {
                        Identifier = "AST", Grammar = astGrammar, DataNamespace = astDataNamspace, VisitorNamespace = astVisitorNamespace
                    },
                    new RelationDomain()
                    {
                        Identifier = "C", Grammar = cGrammar, DataNamespace = cDataNamspace, VisitorNamespace = cVisitorNamespace
                    },
                };

                ClassType toCTranslator = translatorGenerator.GenerateTranslatorClass(cTranslator, cTranslatorName, cRelationDomains, cTranslatorNamespace);

                classesToGenerate = classesToGenerate.Append(toCTranslator);

                foreach (ClassType classType in classesToGenerate)
                {
                    string folder = $"../{string.Join("/", classType.NameSpace.Split('.'))}";
                    Directory.CreateDirectory(folder);
                    classGenerator.Generate(classType, $"{folder}/{classType.Identifier.Split('<')[0]}.cs");
                }
                Console.WriteLine($"...Done {classesToGenerate.Count()} classes generated. Approximately {classesToGenerate.Sum(c => c.Methods.Sum(m => m.Body.Count + 3) + c.Usings.Count + c.Fields.Count)} lines of code. Thank You.");
            }
            catch (LexicalException exception)
            {
                Console.WriteLine($"Unexpected symbol near {exception.Symbol} in {exception.FileName} line {exception.Row + 1} column {exception.Column + 1}.");
            }
            catch (UnexpectedTokenException exception)
            {
                if (exception.Token.Name == exception.Token.Value)
                {
                    if (exception.Token.FileName != null)
                    {
                        Console.WriteLine($"Unexpected '{exception.Token.Name}' in {exception.Token.FileName} line {exception.Token.Row + 1} column {exception.Token.Column + 1}.");
                    }
                    else
                    {
                        Console.WriteLine($"Unexpected '{exception.Token.Name}' at line {exception.Token.Row + 1} column {exception.Token.Column + 1}.");
                    }
                }
                else
                {
                    Console.WriteLine($"Unexpected {exception.Token.Name} '{exception.Token.Value}' in {exception.Token.FileName} line {exception.Token.Row + 1} column {exception.Token.Column + 1}.");
                }
            }
#endif
        }
Exemple #22
0
        static ShiftReduceParser CreateJSonParser()
        {
            var gen = new ParserGenerator();

            var JSON     = gen.CreateNewProduction("JSON", false);
            var ARRAY    = gen.CreateNewProduction("ARRAY", false);
            var OBJECT   = gen.CreateNewProduction("OBJECT", false);
            var MEMBERS  = gen.CreateNewProduction("MEMBERS", false);
            var PAIR     = gen.CreateNewProduction("PAIR", false);
            var ELEMENTS = gen.CreateNewProduction("ELEMENTS", false);
            var VALUE    = gen.CreateNewProduction("VALUE", false);

            var object_starts = gen.CreateNewProduction("object_starts");
            var object_ends   = gen.CreateNewProduction("object_ends");
            var comma         = gen.CreateNewProduction("comma");
            var v_pair        = gen.CreateNewProduction("v_pair");
            var array_starts  = gen.CreateNewProduction("array_starts");
            var array_ends    = gen.CreateNewProduction("array_ends");
            var v_true        = gen.CreateNewProduction("v_true");
            var v_false       = gen.CreateNewProduction("v_false");
            var v_null        = gen.CreateNewProduction("v_null");
            var v_string      = gen.CreateNewProduction("v_string");
            var v_number      = gen.CreateNewProduction("v_number");

            JSON    |= OBJECT + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            JSON    |= ARRAY + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            OBJECT  |= object_starts + object_ends + ParserAction.Create(x => x.UserContents = new json_object());
            OBJECT  |= object_starts + MEMBERS + object_ends + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);
            MEMBERS |= PAIR + ParserAction.Create(x => {
                var jo = new json_object();
                jo.keyvalue.Add(new KeyValuePair <string, json_value>(x.Childs[0].Childs[0].Contents, x.Childs[0].Childs[2].UserContents as json_value));
                x.UserContents = jo;
            });
            MEMBERS |= PAIR + comma + MEMBERS + ParserAction.Create(x => {
                var jo = x.Childs[2].UserContents as json_object;
                jo.keyvalue.Insert(0, new KeyValuePair <string, json_value>(x.Childs[0].Childs[0].Contents, x.Childs[0].Childs[2].UserContents as json_value));
                x.UserContents = jo;
            });
            PAIR     |= v_string + v_pair + VALUE + ParserAction.Create(x => { });
            ARRAY    |= array_starts + array_ends + ParserAction.Create(x => x.UserContents = new json_array());
            ARRAY    |= array_starts + ELEMENTS + array_ends + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);
            ELEMENTS |= VALUE + ParserAction.Create(x => {
                var ja = new json_array();
                ja.array.Add(x.Childs[0].UserContents as json_value);
                x.UserContents = ja;
            });
            ELEMENTS |= VALUE + comma + ELEMENTS + ParserAction.Create(x => {
                var ja = x.Childs[2].UserContents as json_array;
                ja.array.Insert(0, x.Childs[0].UserContents as json_value);
                x.UserContents = ja;
            });
            VALUE |= v_string + ParserAction.Create(x => x.UserContents = new json_string {
                str = x.Contents
            });
            VALUE |= v_number + ParserAction.Create(x => x.UserContents = new json_numeric {
                numstr = x.Contents
            });
            VALUE |= OBJECT + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            VALUE |= ARRAY + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            VALUE |= v_true + ParserAction.Create(x => x.UserContents = new json_state {
                type = json_token.v_true
            });
            VALUE |= v_false + ParserAction.Create(x => x.UserContents = new json_state {
                type = json_token.v_false
            });
            VALUE |= v_null + ParserAction.Create(x => x.UserContents = new json_state {
                type = json_token.v_null
            });

            gen.PushStarts(JSON);
            gen.PrintProductionRules();
            gen.Generate();
            gen.PrintStates();
            gen.PrintTable();

#if false
            Console.WriteLine(gen.GlobalPrinter.ToString());
            Console.WriteLine(gen.CreateExtendedShiftReduceParserInstance().ToCSCode("json_parser"));
#endif

            return(gen.CreateExtendedShiftReduceParserInstance());
        }
Exemple #23
0
        public static Grammar GetGrammar()
        {
            var grammarString = $@"
varKeyword = /\b(var)\b/;               // -/
letKeyword = /\b(let)\b/;               // -/
newKeyword = /\b(new)\b/;               // -/
deleteKeyword = /\b(delete)\b/;         // X ?
instanceofKeyword = /\b(instanceof)\b/; // X ?
withKeyword = /\b(with)\b/;             // X
voidKeyword = /\b(void)\b/;             // X
typeofKeyword = /\b(typeof)\b/;         // X ?
thisKeyword = /\b(this)\b/;             // X ?
debuggerKeyword = /\b(debugger)\b/;     // X
importKeyword = /\b(import)\b/;         // X
classKeyword = /\b(class)\b/;           // X
constKeyword = /\b(const)\b/;           // X ?
extendsKeyword = /\b(extends)\b/;       // X
yieldKeyword = /\b(yield)\b/;           // X
superKeyword = /\b(super)\b/;           // X

functionKeyword = /\b(function)\b/;     // -/
tryKeyword = /\b(try)\b/;               // X ?
catchKeyword = /\b(catch)\b/;           // X ?
finallyKeyword = /\b(finally)\b/;       // X ?
throwKeyword = /\b(throw)\b/;           // X ?
returnKeyword = /\b(return)\b/;         // X ?

ifKeyword = /\b(if)\b/;                 // X ?
elseKeyword = /\b(else)\b/;             // X ?
whileKeyword = /\b(while)\b/;           // X ?
doKeyword = /\b(do)\b/;                 // X ?
forKeyword = /\b(for)\b/;               // X ?
inKeyword = /\b(in)\b/;                 // X ?
switchKeyword = /\b(switch)\b/;         // X ?
caseKeyword = /\b(case)\b/;             // X ?
defaultKeyword = /\b(default)\b/;       // X ?
breakKeyword = /\b(break)\b/;           // X ?
continueKeyword = /\b(continue)\b/;     // X ?

implementsKeyword = /\b(implements)\b/; // X
interfaceKeyword = /\b(interface)\b/;   // X
packageKeyword = /\b(package)\b/;       // X
privateKeyword = /\b(private)\b/;       // X
protectedKeyword = /\b(protected)\b/;   // X
publicKeyword = /\b(public)\b/;         // X
staticKeyword = /\b(static)\b/;         // X
awaitKeyword = /\b(await)\b/;           // X
enumKeyword = /\b(enum)\b/;             // X

leftBracket = ""{{"";
rightBracket = ""}}"";

leftParen = ""("";
rightParen = "")"";

leftSquare = ""["";
rightSquare = ""]"";

comma = "","";
dot = ""."";

equals = ""="";
colon = "":"";
semicolon = "";"";

and = ""&&"";
or = ""||"";
not = ""!"";

strictEquality = ""==="";
strictInequality = ""!=="";
equality = ""=="";
inequality = ""!="";
lessThanOrEqual = ""<="";
greaterThanOrEqual = "">="";
lessThan = ""<"";
greaterThan = "">"";

ws = /\s+/;
ident = /\b[$A-Za-z_][$A-Za-z_0-9]*\b/;
number = /\b\d+(?:\.\d+)?\b/;
doubleString = /""(?:\\\\""|\\\\[^""]|[^""\\\\])*""/;
singleString = /'(?:\\\\'|\\\\[^']|[^'\\\\])*'/;
regex = /\/(?:\\\\\/|\\\\|[^\/])+\/[A-Za-z]*/;
lineComment = /\/\/[^{"\r\n"}]*/;
blockComment = /\/\*([^*]|\*[^\/])*\*\//;

minusEquals = ""-="";
plusEquals = ""+="";
timesEquals = ""*="";
divideEquals = ""/="";
modulusEquals = ""%="";

bitAndEquals = ""&="";
bitOrEquals = ""|="";
bitXorEquals = ""^="";

minus = ""-"";
plus = ""+"";
times = ""*"";
divide = ""/"";
modulus = ""%"";

bitAnd = ""&"";
bitOr = ""|"";
bitNot = ""~"";
bitXor = ""^"";

question = ""?"";

basicKeywords = varKeyword | letKeyword | newKeyword | deleteKeyword | instanceofKeyword | withKeyword | voidKeyword | typeofKeyword | thisKeyword | debuggerKeyword | importKeyword | classKeyword | constKeyword | extendsKeyword | yieldKeyword | superKeyword;
functionLevelKeywords = functionKeyword | tryKeyword | catchKeyword | finallyKeyword | throwKeyword | returnKeyword;
controlKeywords = ifKeyword | elseKeyword | whileKeyword | doKeyword | forKeyword | inKeyword | switchKeyword | caseKeyword | defaultKeyword | breakKeyword | continueKeyword;
futureKeywords = implementsKeyword | interfaceKeyword | packageKeyword | privateKeyword | protectedKeyword | publicKeyword | staticKeyword | awaitKeyword | enumKeyword;

validIdent = im !(basicKeywords | functionLevelKeywords | controlKeywords | futureKeywords) ident;

string = doubleString | singleString;

paren = leftParen expr3 rightParen;

unaryOper = minus | plus;
unaryMath = unaryOper *unaryOper expr2;

typeof = typeofKeyword expr2;

block = leftBracket *statement rightBracket;
paramList = leftParen ?(validIdent *(comma validIdent)) rightParen;
namedFunction = functionKeyword validIdent paramList block;
anonFunction = functionKeyword paramList block;

propertyDef = (validIdent | string) colon expr3;
object = leftBracket ?(propertyDef *(comma propertyDef)) rightBracket;

dotRef = dot validIdent;
key = leftSquare expr3 rightSquare;
argList = leftParen ?(expr3 *(comma expr3)) rightParen;
expressionFragment = dotRef | key | argList;

propertyFragments = (expressionFragment propertyFragments) | dotRef | key;
functionCallFragments = (expressionFragment functionCallFragments) | argList;

constructor = newKeyword functionCall;

// == END expr0 DEFINITIONS ==

functionCall = expr0 functionCallFragments;
propertyReference = expr0 propertyFragments;

// == END expr1 definitions ==

mathOper = minus | plus | times | divide;
math = expr1 mathOper expr2;

logicOper = and | or;
logicNegation = not expr2;
logic = expr1 logicOper expr2;

bitOper = bitAnd | bitOr | bitXor;
bitNegation = bitNot expr2;
bitwise = expr1 bitOper expr2;

instanceof = expr1 instanceofKeyword expr3;
in = expr1 inKeyword expr3;

// == END expr2 DEFINITIONS ==

assignOper = equals | minusEquals | plusEquals | timesEquals | divideEquals | modulusEquals | bitAndEquals | bitOrEquals | bitXorEquals;
localAssignment = validIdent assignOper expr3;
propertyAssignment = propertyReference assignOper expr3;
assignment = localAssignment | propertyAssignment;

ternary = expr2 question expr3 colon expr3;

// == END expr3 DEFINITIONS ==

variable = localAssignment | validIdent;
variableDecl = (varKeyword | letKeyword | constKeyword) variable *(comma variable);

break = breakKeyword;
continue = continueKeyword;
return = returnKeyword ?expr3;
throw = throwKeyword ?expr3;
delete = deleteKeyword propertyReference;
catch = catchKeyword block;
finally = finallyKeyword block;
try = tryKeyword block catch *catch ?finally;

default = defaultKeyword colon *statement;
case = caseKeyword (string | number | (validIdent *dotRef)) colon *statement;
switch = switchKeyword leftBracket *case ?default *case rightBracket;

else = elseKeyword statement;
if = ifKeyword statement ?else;
while = whileKeyword paren statement;
doWhile = doKeyword statement whileKeyword paren ?semicolon;
for = forKeyword leftParen ((variableDecl | expr3) semicolon expr3 semicolon expr3) rightParen statement;

expr0 = thisKeyword | anonFunction | validIdent | number | string | paren | unaryMath | logicNegation | bitNegation | constructor | object;
expr1 = functionCall | propertyReference | expr0;
expr2 = math | logic | instanceof | in | bitwise | expr1;
expr3 = ternary | assignment | expr2;
blockStatement = if | while | doWhile | forIn | for | switch | namedFunction | block;
statement = blockStatement | ((variableDecl | break | continue | return | throw | delete | expr3) ?semicolon) | semicolon;

root = statement *statement;
";

            var parserGen = new ParserGenerator();

            Grammar grammar = parserGen.BuildGrammar(grammarString, "ws", "lineComment", "blockComment");

            grammar.AttachAction("root", (branch, recurse) =>
            {
                ISemanticNode first  = recurse(branch.GetDescendant(0));
                ISemanticNode[] rest = branch.GetDescendant(1)
                                       .Elements
                                       .Select(recurse)
                                       .ToArray();

                return(new BranchSemanticNode((int)JsNodeType.Root, first, rest));
            });

            grammar.AttachAction("statement", (branch, recurse) =>
            {
                ISemanticNode stmt = recurse(branch.GetDescendant(0));

                return(new BranchSemanticNode((int)JsNodeType.Statement, stmt));
            });

            grammar.AttachAction("variableDecl", (branch, recurse) =>
            {
                ISemanticNode first  = recurse(branch.GetDescendant(1, 0));
                ISemanticNode[] rest = branch.GetDescendant(2)
                                       .Elements
                                       .Select(n => recurse(n.GetDescendant(1, 0)))
                                       .ToArray();

                return(new BranchSemanticNode((int)JsNodeType.Variable, first, rest));
            });

            grammar.AttachAction("localAssignment", (branch, recurse) =>
            {
                ISemanticNode lvalue = recurse(branch.GetDescendant(0));
                ISemanticNode expr2  = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)JsNodeType.Assignment, lvalue, expr2));
            });

            grammar.AttachAction("propertyAssignment", RuleActions.PropertyAssignment);

            grammar.AttachAction("propertyReference", RuleActions.CompositeExpression);

            grammar.AttachAction("argList", (branch, recurse) =>
            {
                BranchParseNode args = branch.GetDescendant(1);

                if (args.Elements.Count == 0)
                {
                    return(new BranchSemanticNode((int)JsNodeType.ArgumentList, branch.StartIndex, new ISemanticNode[0]));
                }

                ISemanticNode first  = recurse(args.GetDescendant(0));
                ISemanticNode[] rest = args
                                       .GetDescendant(1)
                                       .Elements
                                       .Select(n => recurse(n.GetDescendant(1)))
                                       .ToArray();

                return(new BranchSemanticNode((int)JsNodeType.ArgumentList, branch.StartIndex, new[] { first }.Concat(rest)));
            });

            grammar.AttachAction("dotRef", (branch, recurse) =>
            {
                ISemanticNode ident = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)JsNodeType.DotReference, ident));
            });

            grammar.AttachAction("key", (branch, recurse) =>
            {
                ISemanticNode key = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)JsNodeType.KeyReference, key));
            });

            grammar.AttachAction("functionCall", RuleActions.FunctionCall);

            grammar.AttachAction("constructor", RuleActions.Constructor);

            grammar.AttachAction("expressionFragment", RuleActions.Unwrap);

            grammar.AttachAction("object", (branch, recurse) =>
            {
                BranchParseNode firstNode = branch.GetDescendant(1, 0);

                if (firstNode == null)
                {
                    return(new BranchSemanticNode((int)JsNodeType.Object, branch.StartIndex, new ISemanticNode[0]));
                }

                ISemanticNode first  = recurse(firstNode);
                ISemanticNode[] rest = branch.GetDescendant(1, 1)
                                       .Elements
                                       .Select(n => recurse(n.GetDescendant(1)))
                                       .ToArray();

                return(new BranchSemanticNode((int)JsNodeType.Object, branch.StartIndex, first, rest));
            });

            grammar.AttachAction("propertyDef", (branch, recurse) =>
            {
                ISemanticNode ident = recurse(branch.GetDescendant(0));
                ISemanticNode value = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)JsNodeType.PropertyDefinition, ident, value));
            });

            grammar.AttachAction("anonFunction", (branch, recurse) =>
            {
                ISemanticNode paramList = recurse(branch.GetDescendant(1));
                ISemanticNode body      = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)JsNodeType.AnonymousFunction, paramList, body));
            });

            grammar.AttachAction("namedFunction", (branch, recurse) =>
            {
                ISemanticNode name      = recurse(branch.GetDescendant(1));
                ISemanticNode paramList = recurse(branch.GetDescendant(2));
                ISemanticNode body      = recurse(branch.GetDescendant(3));

                return(new BranchSemanticNode((int)JsNodeType.NamedFunction, paramList, body));
            });

            grammar.AttachAction("paramList", (branch, recurse) =>
            {
                ISemanticNode first  = recurse(branch.GetDescendant(1, 0));
                ISemanticNode[] rest = branch.GetDescendant(1, 1)
                                       .Elements
                                       .Select(n => recurse(n.GetDescendant(1)))
                                       .ToArray();

                return(new BranchSemanticNode((int)JsNodeType.ParameterList, first, rest));
            });

            grammar.AttachAction("block", (branch, recurse) =>
            {
                ISemanticNode[] stmts = branch.GetDescendant(1)
                                        .Elements
                                        .Select(recurse)
                                        .ToArray();

                return(new BranchSemanticNode((int)JsNodeType.Block, branch.StartIndex, stmts));
            });

            grammar.AttachAction("bitwise", (branch, recurse) =>
            {
                ISemanticNode left  = recurse(branch.GetDescendant(0));
                ISemanticNode right = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)JsNodeType.Bitwise, left, right));
            });

            grammar.AttachAction("bitNegation", (branch, recurse) =>
            {
                ISemanticNode operand = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)JsNodeType.BitwiseNegation, operand));
            });

            grammar.AttachAction("logic", (branch, recurse) =>
            {
                ISemanticNode left  = recurse(branch.GetDescendant(0));
                ISemanticNode right = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)JsNodeType.Logic, left, right));
            });

            grammar.AttachAction("logicNegation", (branch, recurse) =>
            {
                ISemanticNode operand = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)JsNodeType.LogicNegation, operand));
            });

            grammar.AttachAction("math", (branch, recurse) =>
            {
                ISemanticNode left  = recurse(branch.GetDescendant(0));
                ISemanticNode right = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)JsNodeType.Math, left, right));
            });

            grammar.AttachAction("unaryMath", (branch, recurse) =>
            {
                ISemanticNode operand = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)JsNodeType.UnaryMath, operand));
            });

            grammar.AttachAction("paren", (branch, recurse) =>
            {
                ISemanticNode operand = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)JsNodeType.Parenthetical, operand));
            });

            grammar.AttachAction("validIdent", (branch, recurse) =>
            {
                branch = branch.GetDescendant(1);

                var ident      = branch.Leaf.MatchedText;
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)JsNodeType.Identifier, startIndex, ident));
            });

            grammar.AttachAction("doubleString", (branch, recurse) =>
            {
                var text = branch.Leaf.MatchedText;
                text     = text
                           .Substring(1, text.Length - 2)
                           .Replace(@"\\", @"\")
                           .Replace(@"\""", @"""");
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)JsNodeType.String, startIndex, text));
            });

            grammar.AttachAction("singleString", (branch, recurse) =>
            {
                var text = branch.Leaf.MatchedText;
                text     = text
                           .Substring(1, text.Length - 2)
                           .Replace(@"\\", @"\")
                           .Replace(@"\'", @"'");
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)JsNodeType.String, startIndex, text));
            });

            grammar.AttachAction("string", RuleActions.Unwrap);

            grammar.AttachAction("regex", (branch, recurse) =>
            {
                var pattern = branch.Leaf.MatchedText;
                pattern     = pattern
                              .Substring(1, pattern.Length - 2)
                              .Replace(@"\\", @"\")
                              .Replace(@"\/", @"/");
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)JsNodeType.RegularExpression, startIndex, pattern));
            });

            grammar.AttachAction("number", (branch, recurse) =>
            {
                var number     = branch.Leaf.MatchedText;
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)JsNodeType.Number, startIndex, number));
            });

            grammar.AttachAction("expr0", RuleActions.Unwrap);
            grammar.AttachAction("expr1", RuleActions.Unwrap);
            grammar.AttachAction("expr2", RuleActions.Unwrap);
            grammar.AttachAction("expr3", RuleActions.Unwrap);
            grammar.AttachAction("assignment", RuleActions.Unwrap);

            return(grammar);
        }
Exemple #24
0
        public void CreateParser()
        {
            Assembly assembly = Assembly.GetAssembly(typeof(Form1));

            var grammar = new Grammar();

            grammar.Load(assembly, "Calculator");
            grammar.LoadRules(assembly, "Calculator");
            grammar.Resolve();

            Trace.WriteLine("TERMINALS");
            foreach (var terminal in grammar.GetTerminals())
            {
                Trace.WriteLine(terminal.Name);
                var sb = new StringBuilder();
                sb.Append("  First:");
                foreach (var first in terminal.First)
                {
                    sb.Append(" ");
                    sb.Append(first == null ? "e" : first.Name);
                }
                Trace.WriteLine(sb.ToString());
            }

            Trace.WriteLine("NONTERMINALS");
            foreach (var nonterminal in grammar.GetNonterminals())
            {
                Trace.WriteLine(nonterminal.Name);

                foreach (var rule in nonterminal.Rules)
                {
                    Trace.WriteLine("  " + rule.ToString());
                }

                var sb = new StringBuilder();
                sb.Append("  First:");
                foreach (var first in nonterminal.First)
                {
                    sb.Append(" ");
                    sb.Append(first == null ? "e" : first.Name);
                }
                Trace.WriteLine(sb.ToString());

                sb = new StringBuilder();
                sb.Append("  Follow:");
                foreach (var first in nonterminal.Follow)
                {
                    sb.Append(" ");
                    sb.Append(first == null ? "e" : first.Name);
                }
                Trace.WriteLine(sb.ToString());
            }

            ITerminalReaderGenerator      terminalReaderGenerator       = new TerminalReaderGenerator();
            TerminalReaderGeneratorResult terminalReaderGeneratorResult =
                terminalReaderGenerator.GenerateTerminalReader(grammar);

            this.m_terminalReader = (TerminalReader)terminalReaderGeneratorResult.TerminalReader;

            IParserGenerator      parserGenerator       = new ParserGenerator();
            ParserGeneratorResult parserGeneratorResult = parserGenerator.GenerateParser(grammar);

            this.m_parser = (Parser)parserGeneratorResult.Parser;

            ITerminalReader terminalReader = terminalReaderGeneratorResult.TerminalReader;

            terminalReader.Open("(123 + 34) / 52");

            IParser parser = parserGeneratorResult.Parser;

            parser.Parse(terminalReader);

            var token = terminalReader.ReadTerminal();

            while (token != null)
            {
                if (!token.ElementType.Ignore)
                {
                    Console.WriteLine("{0}: {1}", token.ElementType.Name, token.Text);
                }
                token = terminalReader.ReadTerminal();
            }

            //Console.WriteLine("Press Enter to exit.");
            //Console.ReadLine();
        }
        public static string Build(bool generateImplementation)
        {
            var ID           = id("Developer.LanguageServices.NativeX.NativeXTokenizer.IdToken");
            var TYPE_KEYWORD = id("Developer.LanguageServices.NativeX.NativeXTokenizer.TypeKeywordToken");
            var STRING       = id("Developer.LanguageServices.NativeX.NativeXTokenizer.StringToken");
            var NUMBER       = id("Developer.LanguageServices.NativeX.NativeXTokenizer.NumberToken");
            var ATTID        = id("Developer.LanguageServices.NativeX.NativeXTokenizer.AttributeToken");

            var REFERENCE_TYPE    = rule <NativeXReferenceType>("ReferenceType");
            var FUNCTION_TYPE     = rule <NativeXFunctionType>("FunctionType");
            var INSTANCIATED_TYPE = rule <NativeXInstanciatedType>("InstanciatedType");
            var PRIMITIVE_TYPE    = rule <NativeXType>("PrimitiveType");
            var TYPEOFE           = rule <NativeXTypeofExpressionType>("TypeofExpression");
            var TYPEOFM           = rule <NativeXTypeofMemberType>("TypeofMember");
            var TYPE = rule <NativeXType>("Type");

            var STRICT_INSTANCE_FUNCTION_REFERENCE = rule <NativeXInstanceFunctionExpression>("StrictInstanceFunctionReference");
            var STRICT_INSTANCIATED_REFERENCE      = rule <NativeXInstanciatedExpression>("StrictInstanciatedReference");
            var STRICT_IDENTIFIER_REFERENCE        = rule <NativeXReferenceExpression>("StrictIdentifierReference");
            var STRICT_REFERENCE = rule <NativeXExpression>("StrictReference");

            var PRIMITIVE = rule <NativeXPrimitiveExpression>("Primitive");
            var INSTANCE_FUNCTION_REFERENCE = rule <NativeXInstanceFunctionExpression>("InstanceFunctionReference");
            var INSTANCIATED_REFERENCE      = rule <NativeXInstanciatedExpression>("InstanciatedReference");
            var IDENTIFIER_REFERENCE        = rule <NativeXReferenceExpression>("IdentifierReference");
            var REFERENCE  = rule <NativeXExpression>("Reference");
            var RESULT     = rule <NativeXFunctionResultExpression>("Result");
            var EXCEPTION  = rule <NativeXExceptionExpression>("Exception");
            var CAST       = rule <NativeXCastingExpression>("Casting");
            var SIZEOF     = rule <NativeXSizeofTypeExpression>("SizeofType");
            var OFFSETOF   = rule <NativeXOffsetofMemberExpression>("OffsetofMember");
            var EXP0       = rule <NativeXExpression>("EXP0");
            var EXP1       = rule <NativeXExpression>("EXP1");
            var UNARY      = rule <NativeXUnaryExpression>("Unary");
            var EXP2       = rule <NativeXExpression>("EXP2");
            var EXP_BINS   = Enumerable.Range(3, 11).Select(i => rule <NativeXExpression>("EXP" + i.ToString())).ToArray();
            var EXPRESSION = rule <NativeXExpression>("Expression");

            var EMPTY_STATEMENT      = rule <NativeXEmptyStatement>("EmptyStatement");
            var EXPRESSION_STATEMENT = rule <NativeXExpressionStatement>("ExpressionStatement");
            var VARIABLE_STATEMENT   = rule <NativeXVariableStatement>("VariableStatement");
            var IF_STATEMENT         = rule <NativeXIfStatement>("IfStatement");
            var BREAK_STATEMENT      = rule <NativeXBreakStatement>("BreakStatement");
            var CONTINUE_STATEMENT   = rule <NativeXContinueStatement>("ContinueStatement");
            var EXIT_STATEMENT       = rule <NativeXReturnStatement>("ExitStatement");
            var COMPOSITE_STATEMENT  = rule <NativeXCompositeStatement>("CompositeStatement");
            var DO_WHILE_STATEMENT   = rule <NativeXWhileStatement>("DoWhileStatement");
            var LOOP_STATEMENT       = rule <NativeXWhileStatement>("LoopStatement");
            var WHILE_DO_STATEMENT   = rule <NativeXWhileStatement>("WhileDoStatement");
            var FOR_STATEMENT        = rule <NativeXForStatement>("ForStatement");
            var TRY_CATCH_STATEMENT  = rule <NativeXTryCatchStatement>("TryCatchStatement");
            var THROW_STATEMENT      = rule <NativeXThrowStatement>("ThrowStatement");
            var STATEMENT            = rule <NativeXStatement>("Statement");

            var FUNCTION_PARAMETER = rule <NativeXNameTypePair>("FunctionParameterItem");
            var STRUCTURE_MEMBER   = rule <NativeXNameTypePair>("StructureMemberItem");
            var INSTANCE_FUNCTION  = rule <NativeXNameExpressionPair>("InstanceFunctionItem");
            var CONCEPT_FUNCTION   = rule <NativeXNameTypePair>("ConceptFunctionItem");
            var GENERIC_PARAMETER  = rule <NativeXGenericParameter>("GenericParameterItem");
            var GENERIC_CONSTRAINT = rule <NativeXGenericConstraint>("GenericConstraintItem");
            var LINKING            = rule <NativeXLinking>("Linking");

            var FUNCTION_DECLARATION    = rule <NativeXFunctionDeclaration>("FunctionDeclaration");
            var TYPE_RENAME_DECLARATION = rule <NativeXTypeRenameDeclaration>("TypeRenameDeclaration");
            var VARIABLE_DECLARATION    = rule <NativeXVariableDeclaration>("VariableDeclaration");
            var STRUCTURE_DECLARATION   = rule <NativeXStructureDeclaration>("StructureDeclaration");
            var INSTANCE_DECLARATION    = rule <NativeXInstanceDeclaration>("InstanceDeclaration");
            var CONCEPT_DECLARATION     = rule <NativeXConceptDeclaration>("ConceptDeclaration");

            var GENERIC_DECLARATION     = rule <NativeXDeclaration>("GenericDeclaration");
            var NON_GENERIC_DECLARATION = rule <NativeXDeclaration>("NonGenericDeclaration");
            var DECLARATION_CANDIDATE   = rule <NativeXDeclaration>("DeclarationCandidate");
            var ATTRIBUTE   = rule <NativeXAttribute>("Attribute");
            var DECLARATION = rule <NativeXDeclaration>("Declaration");

            var USE  = rule <NativeXUses>("UseUnitItem");
            var UNIT = rule <NativeXUnit>("Unit");
            var CONCEPT_REFERENCE   = rule <NativeXConceptReference>("ConceptReference");
            var EDITING_DECLARATION = rule <NativeXEditingDeclarations>("EditingDeclarations");

            {
                USE.Infer(
                    ID["UnitName"]
                    );

                UNIT.Infer(
                    opt(!tok("unit") + ID["Name"] + tok(";"))
                    + opt(!tok("uses") + list <NativeXUses>(tok(","), USE)["UsesUnits"] + tok(";"))
                    + list_hard <NativeXDeclaration>(DECLARATION)["Declarations"]
                    );

                CONCEPT_REFERENCE.Infer(
                    ID["ReferenceName"]
                    );

                EDITING_DECLARATION.Infer(
                    list_hard <NativeXDeclaration>(DECLARATION)["Declarations"]
                    );
            }
            {
                FUNCTION_PARAMETER.Infer(
                    !TYPE["Type"] + ID["Name"]
                    );

                STRUCTURE_MEMBER.Infer(
                    !TYPE["Type"] + ID["Name"] + tok(";")
                    );

                INSTANCE_FUNCTION.Infer(
                    !ID["Name"] + tok("=") + STRICT_REFERENCE["Expression"] + tok(";")
                    );

                CONCEPT_FUNCTION.Infer(
                    !ID["Name"] + tok("=") + TYPE["Type"] + tok(";")
                    );

                GENERIC_PARAMETER.Infer(
                    !ID["ParameterName"]
                    );

                GENERIC_CONSTRAINT.Infer(
                    !ID["ParameterName"] + tok(":") + CONCEPT_REFERENCE["ConceptName"]
                    );

                LINKING.Infer(
                    !tok("alias") + ID["LinkingAssembly"] + tok(".") + ID["LinkingSymbol"]
                    );
            }
            {
                FUNCTION_DECLARATION.Infer(
                    opt(tok("foreign")["Foreign", "true"])
                    + !tok("function") + TYPE["ReturnType"] + ID["Name"] + tok("(") + list <NativeXNameTypePair>(tok(","), FUNCTION_PARAMETER)["Parameters"] + tok(")")
                    + opt(LINKING["Linking"])
                    + (tok(";") | STATEMENT["Statement"])
                    );

                VARIABLE_DECLARATION.Infer(
                    !tok("variable") + TYPE["Type"] + ID["Name"] + opt(LINKING["Linking"]) + opt(!tok("=") + EXPRESSION["Initializer"]) + tok(";")
                    );

                TYPE_RENAME_DECLARATION.Infer(
                    !tok("type") + ID["Name"] + tok("=") + TYPE["Type"] + tok(";")
                    );

                STRUCTURE_DECLARATION.Infer(
                    !tok("structure") + ID["Name"]
                    + (
                        tok(";")
                        | (
                            opt(LINKING["Linking"]) + !tok("{") + list <NativeXNameTypePair>(STRUCTURE_MEMBER, "}")["Members"] + tok("}")
                            )
                        )
                    );

                INSTANCE_DECLARATION.Infer(
                    !tok("instance") + REFERENCE_TYPE["Type"] + tok(":") + CONCEPT_REFERENCE["ConceptName"]
                    + (
                        tok(";")
                        | (
                            !tok("{") + list <NativeXNameExpressionPair>(INSTANCE_FUNCTION, "}")["Functions"] + tok("}")
                            )
                        )
                    );

                CONCEPT_DECLARATION.Infer(
                    !tok("concept") + GENERIC_PARAMETER["ConceptType"] + tok(":") + ID["Name"] + opt(LINKING["Linking"]) + tok("{") + list <NativeXNameTypePair>(CONCEPT_FUNCTION, "}")["Functions"] + tok("}")
                    );
            }
            {
                DECLARATION_CANDIDATE.Infer(
                    ret(FUNCTION_DECLARATION)
                    | ret(TYPE_RENAME_DECLARATION)
                    | ret(VARIABLE_DECLARATION)
                    | ret(STRUCTURE_DECLARATION)
                    | ret(INSTANCE_DECLARATION)
                    | ret(CONCEPT_DECLARATION)
                    );

                NON_GENERIC_DECLARATION.Infer(
                    list <NativeXAttribute>(ATTRIBUTE)["Attributes"] + ret(DECLARATION_CANDIDATE)
                    );

                GENERIC_DECLARATION.Infer(
                    !tok("generic") + tok("<") + list <NativeXGenericParameter>(tok(","), GENERIC_PARAMETER)["GenericParameters"] + tok(">")
                    + opt(!tok("where") + list <NativeXGenericConstraint>(tok(","), GENERIC_CONSTRAINT)["GenericConstraints"])
                    + ret(NON_GENERIC_DECLARATION)
                    );

                ATTRIBUTE.Infer(
                    ATTID["Name"]
                    );

                DECLARATION.Infer(
                    ret(GENERIC_DECLARATION) | ret(NON_GENERIC_DECLARATION)
                    );
            }
            {
                EMPTY_STATEMENT.Infer(
                    tok(";")
                    );

                EXPRESSION_STATEMENT.Infer(
                    !EXPRESSION["Expression"] + tok(";")
                    );

                VARIABLE_STATEMENT.Infer(
                    !tok("variable") + TYPE["Type"] + ID["Name"] + opt(!tok("=") + EXPRESSION["Initializer"]) + tok(";")
                    );

                IF_STATEMENT.Infer(
                    !tok("if") + tok("(") + EXPRESSION["Condition"] + tok(")") + STATEMENT["TrueStatement"] + opt(!tok("else") + STATEMENT["FalseStatement"])
                    );

                BREAK_STATEMENT.Infer(
                    !tok("break") + tok(";")
                    );

                CONTINUE_STATEMENT.Infer(
                    !tok("continue") + tok(";")
                    );

                EXIT_STATEMENT.Infer(
                    !tok("exit") + tok(";")
                    );

                COMPOSITE_STATEMENT.Infer(
                    !tok("{") + list <NativeXStatement>(STATEMENT, "}")["Statements"] + tok("}")
                    );

                DO_WHILE_STATEMENT.Infer(
                    !tok("do") + STATEMENT["Statement"] + tok("while") + tok("(") + EXPRESSION["EndCondition"] + tok(")") + tok(";")
                    );

                LOOP_STATEMENT.Infer(
                    !tok("loop") + STATEMENT["Statement"]
                    );

                WHILE_DO_STATEMENT.Infer(
                    !tok("while") + tok("(") + EXPRESSION["BeginCondition"] + tok(")") + STATEMENT["Statement"] + opt(!tok("when") + tok("(") + EXPRESSION["EndCondition"] + tok(")") + tok(";"))
                    );

                FOR_STATEMENT.Infer(
                    !tok("for") + tok("(") + list <NativeXStatement>(STATEMENT)["Initializer"]
                    + tok("when") + tok("(") + EXPRESSION["Condition"] + tok(")")
                    + tok("with") + list <NativeXStatement>(STATEMENT)["SideEffect"]
                    + tok(")") + tok("do") + STATEMENT["Statement"]
                    );

                TRY_CATCH_STATEMENT.Infer(
                    !tok("try") + STATEMENT["TryStatement"] + tok("catch") + STATEMENT["CatchStatement"]
                    );

                THROW_STATEMENT.Infer(
                    !tok("throw") + opt(EXPRESSION["ExceptionExpression"]) + tok(";")
                    );

                STATEMENT.Infer(
                    ret(EMPTY_STATEMENT)
                    | ret(VARIABLE_STATEMENT)
                    | ret(IF_STATEMENT)
                    | ret(BREAK_STATEMENT)
                    | ret(CONTINUE_STATEMENT)
                    | ret(EXIT_STATEMENT)
                    | ret(COMPOSITE_STATEMENT)
                    | ret(DO_WHILE_STATEMENT)
                    | ret(LOOP_STATEMENT)
                    | ret(WHILE_DO_STATEMENT)
                    | ret(FOR_STATEMENT)
                    | ret(TRY_CATCH_STATEMENT)
                    | ret(THROW_STATEMENT)
                    | ret(EXPRESSION_STATEMENT)
                    );
            }
            {
                STRICT_INSTANCE_FUNCTION_REFERENCE.Infer(
                    CONCEPT_REFERENCE["ConceptName"] + tok("<") + TYPE["Type"] + tok(">") + !tok(":") + tok(":") + ID["FunctionName"]
                    );

                STRICT_INSTANCIATED_REFERENCE.Infer(
                    ID["ReferencedName"] + !tok("<") + list <NativeXType>(tok(","), TYPE)["GenericArguments"] + tok(">")
                    );

                STRICT_IDENTIFIER_REFERENCE.Infer(
                    !ID["ReferencedName"]
                    );

                STRICT_REFERENCE.Infer(
                    ret(STRICT_INSTANCE_FUNCTION_REFERENCE) | ret(STRICT_INSTANCIATED_REFERENCE) | ret(STRICT_IDENTIFIER_REFERENCE)
                    );
            }
            {
                INSTANCE_FUNCTION_REFERENCE.Infer(
                    CONCEPT_REFERENCE["ConceptName"] + tok("<") + TYPE["Type"] + tok(">") + !tok(":") + tok(":") + ID["FunctionName"]
                    );

                INSTANCIATED_REFERENCE.Infer(
                    ID["ReferencedName"] + tok("<") + list <NativeXType>(tok(","), TYPE)["GenericArguments"] + tok(">")
                    );

                IDENTIFIER_REFERENCE.Infer(
                    !ID["ReferencedName"]
                    );

                REFERENCE.Infer(
                    ret(INSTANCE_FUNCTION_REFERENCE) | ret(INSTANCIATED_REFERENCE) | ret(IDENTIFIER_REFERENCE)
                    );

                PRIMITIVE.Infer(
                    STRING["Code"] | NUMBER["Code"] | toks("true", "false", "null")["Code"]
                    );

                RESULT.Infer(
                    !tok("result")
                    );

                EXCEPTION.Infer(
                    !tok("exception")
                    );

                CAST.Infer(
                    !tok("cast") + tok("<") + TYPE["Type"] + tok(">") + tok("(") + EXPRESSION["Operand"] + tok(")")
                    );

                SIZEOF.Infer(
                    !tok("sizeof") + tok("(") + TYPE["Type"] + tok(")")
                    );

                OFFSETOF.Infer(
                    !tok("offsetof") + tok("(") + TYPE["Type"] + tok(":") + tok(":") + ID["MemberName"] + tok(")")
                    );

                EXP0.Infer(
                    ret(SIZEOF) | ret(OFFSETOF) | ret(RESULT) | ret(EXCEPTION) | ret(CAST) | ret(PRIMITIVE) | ret(REFERENCE) | !tok("(") + ret(EXPRESSION) + tok(")")
                    );

                EXP1.Infer(
                    ret(leftrecg(
                            EXP0,
                            g <NativeXSubscribeExpression>("Operand", !tok("[") + EXPRESSION["Subscribe"] + tok("]")),
                            g <NativeXInvokeExpression>("Function", !tok("(") + list <NativeXExpression>(tok(","), EXPRESSION)["Arguments"] + tok(")")),
                            g <NativeXMemberExpression>("Operand", !tok(".") + ID["MemberName"]),
                            g <NativeXPointerMemberExpression>("Operand", !tok("->") + ID["MemberName"]),
                            g <NativeXPostUnaryExpression>("Operand", !toks("++", "--")["Operator"])
                            ))
                    );

                UNARY.Infer(
                    ((!toks("++", "--", "&", "*", "-", "!", "~")["Operator"])) + EXP2["Operand"]
                    );

                EXP2.Infer(
                    ret(EXP1) | ret(UNARY)
                    );

                {
                    string[][] binaryOperators = new string[][] {
                        new string[] { "*", "/", "%" },
                        new string[] { "+", "-" },
                        new string[] { "<<", ">>" },
                        new string[] { "<", "<=", ">", ">=" },
                        new string[] { "==", "!=" },
                        new string[] { "&" },
                        new string[] { "^" },
                        new string[] { "|" },
                        new string[] { "&&" },
                        new string[] { "||" },
                        new string[] { "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", "&=", "/=", "&&=", "||=", "=" }
                    };
                    ParserNode   shiftNode     = (tok("<") + !tok("<"))["Operator", "\"<<\""] | (tok(">") + !tok(">"))["Operator", "\">>\""];
                    ParserNode[] operatorNodes = binaryOperators
                                                 .Select(ops => ops.First() == "<<" ? shiftNode : !toks(ops)["Operator"])
                                                 .ToArray();
                    ParserNode[] previousNode = new ParserNode[] { EXP2 }
                    .Concat(EXP_BINS.Take(EXP_BINS.Length - 1))
                    .ToArray();
                    for (int i = 0; i < EXP_BINS.Length; i++)
                    {
                        EXP_BINS[i].Infer(
                            ret(leftrec <NativeXBinaryExpression>(previousNode[i]["LeftOperand"], operatorNodes[i] + previousNode[i]["RightOperand"]))
                            );
                    }
                }

                EXPRESSION.Infer(
                    ret(EXP_BINS.Last())
                    );
            }
            {
                REFERENCE_TYPE.Infer(
                    (ID["ReferencedName"] | TYPE_KEYWORD["ReferencedName"])
                    );

                FUNCTION_TYPE.Infer(
                    !tok("function") + TYPE["ReturnType"] + tok("(") + list <NativeXType>(tok(","), TYPE)["Parameters"] + tok(")")
                    );

                INSTANCIATED_TYPE.Infer(
                    REFERENCE_TYPE["ElementType"] + !tok("<") + list <NativeXType>(tok(","), TYPE)["GenericArguments"] + tok(">")
                    );

                TYPEOFM.Infer(
                    tok("typeof") + tok("(") + TYPE["Type"] + !tok(":") + tok(":") + ID["MemberName"] + tok(")")
                    );

                TYPEOFE.Infer(
                    !tok("typeof") + tok("(") + EXPRESSION["Expression"] + tok(")")
                    );

                PRIMITIVE_TYPE.Infer(
                    ret(TYPEOFM) | ret(TYPEOFE) | ret(FUNCTION_TYPE) | ret(INSTANCIATED_TYPE) | ret(REFERENCE_TYPE)
                    );

                TYPE.Infer(
                    ret(leftrecg(
                            PRIMITIVE_TYPE,
                            g <NativeXPointerType>("ElementType", tok("*")),
                            g <NativeXArrayType>("ElementType", !tok("[") + PRIMITIVE["Size"] + tok("]"))
                            ))
                    );
            }

            if (generateImplementation)
            {
                return(ParserGenerator.GenerateCSharpCode("Developer.LanguageServices.NativeX", "NativeXCodeParser", UNIT, EDITING_DECLARATION));
            }
            else
            {
                return(ParserGenerator.GenerateCSharpCodeWithoutImplementation("Developer.LanguageServices.NativeX", "NativeXCodeParser", UNIT, EDITING_DECLARATION));
            }
        }
Exemple #26
0
        /// <summary>
        /// SRCAL의 파서제너레이터를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ExtendedShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var script   = gen.CreateNewProduction("script", false);
            var line     = gen.CreateNewProduction("line", false);
            var lines    = gen.CreateNewProduction("lines", false);
            var expr     = gen.CreateNewProduction("expr", false);
            var block    = gen.CreateNewProduction("block", false);
            var iblock   = gen.CreateNewProduction("iblock", false);
            var index    = gen.CreateNewProduction("index", false);
            var variable = gen.CreateNewProduction("variable", false);
            var argument = gen.CreateNewProduction("argument", false);
            var function = gen.CreateNewProduction("function", false);
            var runnable = gen.CreateNewProduction("runnable", false);

            // Terminals
            var name     = gen.CreateNewProduction("name");
            var _const   = gen.CreateNewProduction("const"); // number | string
            var loop     = gen.CreateNewProduction("loop");
            var op_open  = gen.CreateNewProduction("op_open");
            var op_close = gen.CreateNewProduction("op_close");
            var pp_open  = gen.CreateNewProduction("pp_open");  // [
            var pp_close = gen.CreateNewProduction("pp_close"); // ]
            var equal    = gen.CreateNewProduction("equal");
            var to       = gen.CreateNewProduction("to");
            var scolon   = gen.CreateNewProduction("scolon");
            var comma    = gen.CreateNewProduction("comma");
            var plus     = gen.CreateNewProduction("plus");     // +
            var minus    = gen.CreateNewProduction("minus");    // -
            var multiple = gen.CreateNewProduction("multiple"); // *
            var divide   = gen.CreateNewProduction("divide");   // /
            var _foreach = gen.CreateNewProduction("foreach");
            var _if      = gen.CreateNewProduction("if");
            var _else    = gen.CreateNewProduction("else");

            script |= lines + ParserAction.Create((m, f, b, x) => {
                var module = new LPModule();
                var sfunc  = module.CreateFunction("start");
                var bb     = sfunc.CreateBasicBlock();
                x.Childs[0].Action(module, sfunc, bb, x.Childs[0]);
                x.UserContents = module;
            });
            script |= ParserGenerator.EmptyString + ParserAction.Create((m, f, b, x) => {
                x.UserContents = new LPModule();
            });

            block |= pp_open + iblock + pp_close + ParserAction.Create((m, f, b, x) => { });
            block |= line + ParserAction.Create((m, f, b, x) => { });

            iblock |= block + ParserAction.Create((m, f, b, x) => { });
            iblock |= lines + ParserAction.Create((m, f, b, x) => { });
            iblock |= ParserGenerator.EmptyString + ParserAction.Create((m, f, b, x) => { });

            line |= expr + ParserAction.Create((m, f, b, x) => { });

            lines |= expr + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x.Childs[0]);
            });
            lines |= expr + lines + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x.Childs[0]);
                x.Childs[1].Action(m, f, b, x.Childs[1]);
            });

            expr |= function + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x.Childs[0]);
            });
            expr |= name + equal + index + ParserAction.Create((m, f, b, x) => { });
            expr |= runnable + ParserAction.Create((m, f, b, x) => { });

            function |= name + op_open + op_close + ParserAction.Create((m, f, b, x) => {
                var caller      = m.CreateFunction(x.Childs[0].Contents);
                caller.IsExtern = true;
                var ci          = LPCallOperator.Create(caller, new List <LPUser>());
                b.Insert(ci);
                x.UserContents = ci;
            });
            function |= name + op_open + argument + op_close + ParserAction.Create((m, f, b, x) => {
                var caller      = m.CreateFunction(x.Childs[0].Contents);
                caller.IsExtern = true;
                x.Childs[2].Action(m, f, b, x);
                var ci = LPCallOperator.Create(caller, x.Childs[2].UserContents as List <LPUser>);
                b.Insert(ci);
                x.UserContents = ci;
            });

            argument |= index + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x);
                x.UserContents = new List <LPUser> {
                    x.Childs[0].UserContents as LPUser
                };
            });
            argument |= index + comma + argument + ParserAction.Create((m, f, b, x) => { });

            index |= variable + ParserAction.Create((m, f, b, x) => { });
            index |= variable + pp_open + variable + pp_close + ParserAction.Create((m, f, b, x) => { });
            index |= index + plus + index + ParserAction.Create((m, f, b, x) => { });
            index |= index + minus + index + ParserAction.Create((m, f, b, x) => { });
            index |= index + multiple + index + ParserAction.Create((m, f, b, x) => { });
            index |= index + divide + index + ParserAction.Create((m, f, b, x) => { });
            index |= minus + index + ParserAction.Create((m, f, b, x) => { });
            index |= op_open + index + op_close + ParserAction.Create((m, f, b, x) => { });

            variable |= name + ParserAction.Create((m, f, b, x) => { });
            variable |= function + ParserAction.Create((m, f, b, x) => { });
            variable |= _const + ParserAction.Create((m, f, b, x) => { x.UserContents = LPConstant.Create(x.Childs[0].Contents); });

            runnable |= loop + op_open + name + equal + index + to + index + op_close + block + ParserAction.Create((m, f, b, x) => { });
            runnable |= _foreach + op_open + name + scolon + index + op_close + block + ParserAction.Create((m, f, b, x) => { });
            runnable |= _if + op_open + index + op_close + block + ParserAction.Create((m, f, b, x) => { });
            runnable |= _if + op_open + index + op_close + block + _else + block + ParserAction.Create((m, f, b, x) => { });

            gen.PushConflictSolver(true, _else);
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(runnable, 2));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(index, 6));
            gen.PushConflictSolver(false, multiple, divide);
            gen.PushConflictSolver(false, plus, minus);

            //gen.PushConflictSolver(true, new Tuple<ParserProduction, int>(index, 1));
            gen.PushConflictSolver(false, pp_open);
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(index, 0));

            try
            {
                gen.PushStarts(script);
                gen.PrintProductionRules();
                gen.GenerateLALR2();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateExtendedShiftReduceParserInstance());
        }
Exemple #27
0
        public Parser(INonterminalSymbol <Result> grammar, ParserGenerator algorithm, params Terminal[] whitespace)
        {
            strategy = algorithm switch
            {
                ParserGenerator.LR0 => new LR0ParserGenerator(),
                ParserGenerator.SLR => new SLRParserGenerator(),
                ParserGenerator.CLR => new CLRParserGenerator(),
                ParserGenerator.LALR => new LALRParserGenerator(),
                _ => throw new ArgumentException(nameof(algorithm))
            };

            visitedStates = new HashSet <State>(strategy);

            eof = Terminal.Eof;

            // Set up symbol metadata
            startSymbol = new Symbol <Result, Context>("start");
            startSymbol.Match(grammar, eof, (x, y) => x);

            symbols      = startSymbol.ReachableSymbols.ToList();
            terminals    = grammar.ReachableTerminals.ToList();
            nonterminals = symbols.OfType <INonterminalSymbol>().ToList();

            tokenizer = grammar.MakeTokenizer(whitespace);
            terminals.Add(eof);  // Ensure it's at the end

            // Set up terminals
            epsilon = Terminal.Empty;  // !! Dont think this is needed ??

            // Mark potentially empty symbols
            MarkCanBeEmpty();

            ComputeFirstSets();

            // Index all the rules

            int index = 0;

            rules = new List <ProductionRule>();
            rules.AddRange(nonterminals.SelectMany(s => s.Rules));

            foreach (var r in rules)
            {
                r.Index = index++;
            }

            index = 0;
            foreach (var t in terminals)
            {
                t.TerminalIndex = index++;
            }

            index = 0;
            foreach (var t in nonterminals)
            {
                t.GotoIndex = index++;
            }

            // Compute the state tables

            // The initial state.

            initialState = strategy.CreateInitialState(startSymbol);
            strategy.ExpandClosure(initialState);
            visitedStates.Add(initialState);

            // Compute transitions for the state

            ComputeGotos(initialState);
            // ComputeActions(initialState);

            // Compute actions for all states.

            foreach (var state in visitedStates)
            {
                ComputeActions(state);
            }
        }

        HashSet <State> visitedStates;
Exemple #28
0
        /// <summary>
        ///
        /// </summary>
        static void ProcessTest(string[] args)
        {
            switch (args[0].ToInt32())
            {
            case 1:
                var c2c = new CALtoCS();
                c2c.Compile(File.ReadAllLines("script/danbooru-pages.srcal"));
                break;

            case 2:
                var cal = new ESRCAL();
                cal.Compile(new[] { "5+4-(-4*(2-4)*2)/3+-(-(2*2+3)-2)*(3+1)" });
                //cal.Compile(new[] { "(2*2+3)" });
                break;

            case 3:
                var x = new HTMLParser();

                break;

            case 4:
                var p = JSParserGenerator.Parser;

                break;

            case 5:
                var s = JSScannerGenerator.Scanner;
                break;

            case 6:

                var sg = new ScannerGenerator();

                sg.PushRule("", @"[\t\r\n ]");
                sg.PushRule("comma", "\\,");
                sg.PushRule("v_pair", "\\:");
                sg.PushRule("object_starts", "\\{");
                sg.PushRule("object_ends", "\\}");
                sg.PushRule("array_starts", "\\[");
                sg.PushRule("array_ends", "\\]");
                sg.PushRule("v_true", "true");
                sg.PushRule("v_false", "false");
                sg.PushRule("v_null", "null");

                var vv = new List <StringBuilder>(5);
                vv.Add(new StringBuilder());     // 6
                vv.Add(new StringBuilder());     // 5
                vv.Add(new StringBuilder());     // 4
                vv.Add(new StringBuilder());     // 3
                vv.Add(new StringBuilder());     // 2

                for (int cc = 0xc0; cc < 0xff; cc++)
                {
                    if ((cc & 0xfc) == 0xfc)
                    {
                        vv[0].Append("\\x" + cc.ToString("X2"));
                    }
                    else if ((cc & 0xf8) == 0xf8)
                    {
                        vv[1].Append("\\x" + cc.ToString("X2"));
                    }
                    else if ((cc & 0xf0) == 0xf0)
                    {
                        vv[2].Append("\\x" + cc.ToString("X2"));
                    }
                    else if ((cc & 0xe0) == 0xe0)
                    {
                        vv[3].Append("\\x" + cc.ToString("X2"));
                    }
                    else if ((cc & 0xc0) == 0xc0)
                    {
                        vv[4].Append("\\x" + cc.ToString("X2"));
                    }
                }

                var bb = new StringBuilder();
                for (int i = 0, j = 5; i < 5; i++, j--)
                {
                    bb.Append("[" + vv[i].ToString() + "]" + new string('.', j));

                    if (i != 4)
                    {
                        bb.Append("|");
                    }
                }

                //SimpleRegex sr = new SimpleRegex();
                //sr.MakeNFA($"\"({bb.ToString()}|[^\\\"]|\\\")*\"");
                //sr.OptimizeNFA();
                //sr.NFAtoDFA();
                //sr.MinimizeDFA();
                //Console.Instance.WriteLine(sr.PrintDiagram());

                //sg.PushRule("v_string", $"\"({bb.ToString()}|[^\\\"]|\\\")*\"");
                sg.PushRule("v_string", $"\"([^\\\"]|\\\")*\"");
                sg.PushRule("v_number", @"-?[0-9]+(\.[0-9]+)?([Ee][\+\-]?[0-9]+)?");

                sg.Generate();
                Console.Instance.WriteLine(sg.PrintDiagram());

                var s3 = sg.CreateScannerInstance();
                Console.Instance.WriteLine(s3.ToCSCode("json_lexer"));

                var gen = new ParserGenerator();

                var JSON     = gen.CreateNewProduction("JSON", false);
                var ARRAY    = gen.CreateNewProduction("ARRAY", false);
                var OBJECT   = gen.CreateNewProduction("OBJECT", false);
                var MEMBERS  = gen.CreateNewProduction("MEMBERS", false);
                var PAIR     = gen.CreateNewProduction("PAIR", false);
                var ELEMENTS = gen.CreateNewProduction("ELEMENTS", false);
                var VALUE    = gen.CreateNewProduction("VALUE", false);

                var object_starts = gen.CreateNewProduction("object_starts");
                var object_ends   = gen.CreateNewProduction("object_ends");
                var comma         = gen.CreateNewProduction("comma");
                var v_pair        = gen.CreateNewProduction("v_pair");
                var array_starts  = gen.CreateNewProduction("array_starts");
                var array_ends    = gen.CreateNewProduction("array_ends");
                var v_true        = gen.CreateNewProduction("v_true");
                var v_false       = gen.CreateNewProduction("v_false");
                var v_null        = gen.CreateNewProduction("v_null");
                var v_string      = gen.CreateNewProduction("v_string");
                var v_number      = gen.CreateNewProduction("v_number");

                JSON     |= OBJECT;
                JSON     |= ARRAY;
                OBJECT   |= object_starts + object_ends;
                OBJECT   |= object_starts + MEMBERS + object_ends;
                MEMBERS  |= PAIR;
                MEMBERS  |= PAIR + comma + MEMBERS;
                PAIR     |= v_string + v_pair + VALUE;
                ARRAY    |= array_starts + array_ends;
                ARRAY    |= array_starts + ELEMENTS + array_ends;
                ELEMENTS |= VALUE;
                ELEMENTS |= VALUE + comma + ELEMENTS;
                VALUE    |= v_string;
                VALUE    |= v_number;
                VALUE    |= OBJECT;
                VALUE    |= ARRAY;
                VALUE    |= v_true;
                VALUE    |= v_false;
                VALUE    |= v_null;

                gen.PushStarts(JSON);
                gen.PrintProductionRules();
                gen.GenerateLALR2();
                gen.PrintStates();
                gen.PrintTable();

                Console.Instance.WriteLine(gen.GlobalPrinter.ToString());
                Console.Instance.WriteLine(gen.CreateExtendedShiftReduceParserInstance().ToCSCode("json_parser"));

                break;
            }
        }
Exemple #29
0
        static void ProcessPGSample()
        {
            var gen = new ParserGenerator();

            // Non-Terminals
            var E = gen.CreateNewProduction("E", false);
            //var T = gen.CreateNewProduction("T", false);
            //var F = gen.CreateNewProduction("F", false);
            //var func = gen.CreateNewProduction("func", false);
            //var arguments = gen.CreateNewProduction("args", false);

            // Terminals
            var plus     = gen.CreateNewProduction("+");   // +
            var minus    = gen.CreateNewProduction("-");   // -
            var multiple = gen.CreateNewProduction("*");   // *
            var divide   = gen.CreateNewProduction("/");   // /
            //var id = gen.CreateNewProduction("id");             // [_$a-zA-Z][_$a-zA-Z0-9]*
            var op_open  = gen.CreateNewProduction("(");   // (
            var op_close = gen.CreateNewProduction(")");   // )
            var num      = gen.CreateNewProduction("num"); // [0-9]+

            //var split = gen.CreateNewProduction("split");       // ,

            //exp |= exp + plus + term;
            //exp |= exp + minus + term;
            //exp |= term;
            //term |= term + multiple + factor;
            //term |= term + divide + factor;
            //term |= factor;
            //factor |= op_open + exp + op_close;
            //factor |= num;
            //factor |= id;
            //factor |= func;
            //func |= id + op_open + arguments + op_close;
            //arguments |= id;
            //arguments |= arguments + split + id;
            //arguments |= ParserGenerator.EmptyString;

            E |= E + plus + E + ParserAction.Create(x => { });;
            E |= E + minus + E + ParserAction.Create(x => { });;
            E |= E + multiple + E + ParserAction.Create(x => { });;
            E |= E + divide + E + ParserAction.Create(x => { });;
            E |= minus + E + ParserAction.Create(x => { });;
            E |= op_open + E + op_close + ParserAction.Create(x => { });;
            E |= num + ParserAction.Create(x => { });;

            gen.PushConflictSolver(false, new Tuple <ParserProduction, int>(E, 4));
            gen.PushConflictSolver(true, multiple, divide);
            gen.PushConflictSolver(true, plus, minus);

            gen.PushStarts(E);
            gen.PrintProductionRules();
            gen.GenerateLALR2();
            gen.PrintStates();
            gen.PrintTable();

            Console.Instance.WriteLine(gen.GlobalPrinter.ToString());
            Console.Instance.WriteLine(gen.CreateShiftReduceParserInstance().ToCSCode("Calculator"));

            //////////////////////////////////////////////////////

            //var scanner_gen = new ScannerGenerator();
            //
            //scanner_gen.PushRule("", @"[\r\n ]");  // Skip characters
            //scanner_gen.PushRule("+", @"\+");
            //scanner_gen.PushRule("-", @"\-");
            //scanner_gen.PushRule("*", @"\*");
            //scanner_gen.PushRule("/", @"\/");
            //scanner_gen.PushRule("(", @"\(");
            //scanner_gen.PushRule(")", @"\)");
            //scanner_gen.PushRule("num", @"[0-9]+(\.[0-9]+)?([Ee][\+\-]?[0-9]+)?");
            //scanner_gen.Generate();
            //var ss = scanner_gen.CreateScannerInstance();
            //var pp = gen.CreateShiftReduceParserInstance();
            //
            //Action<string, string, int, int> insert = (string x, string y, int a, int b) =>
            //{
            //    pp.Insert(x, y);
            //    if (pp.Error()) throw new Exception($"[COMPILER] Parser error! L:{a}, C:{b}");
            //    while (pp.Reduce())
            //    {
            //        var l = pp.LatestReduce();
            //        Console.Instance.Write(l.Production.PadLeft(8) + " => ");
            //        Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Production)));
            //        Console.Instance.Write(l.Production.PadLeft(8) + " => ");
            //        Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Contents)));
            //        pp.Insert(x, y);
            //        if (pp.Error()) throw new Exception($"[COMPILER] Parser error! L:{a}, C:{b}");
            //    }
            //};
            //
            //try
            //{
            //    int ll = 0;
            //    var line = "5-(4+2*3-1)/(6+-5)";
            //        ss.AllocateTarget(line.Trim());
            //
            //        while (ss.Valid())
            //        {
            //            var tk = ss.Next();
            //            if (ss.Error())
            //                throw new Exception("[COMPILER] Tokenize error! '" + tk + "'");
            //            insert(tk.Item1, tk.Item2, ll, tk.Item4);
            //        }
            //
            //    if (pp.Error()) throw new Exception();
            //    insert("$", "$", -1, -1);
            //
            //    var tree = pp.Tree;
            //    CALtoCS.PrintTree(tree.root, "", true);
            //}
            //catch (Exception e)
            //{
            //    Console.Instance.WriteLine(e.Message);
            //}
        }
Exemple #30
0
        public CommandParser(Parameters parameters)
        {
            command = new Command("", parameters);

            var grammar = $@"
equals = ""="";

shortOptions = /(?<= )-[_\w]+/;
shortOption = /(?<= )-[_\w]/;
longOption = /(?<= )--[_\w][-_\w]*/;
endOptions = /(?<= )--(?= )/;
doubleString = /""(?:\\\\""|\\\\[^""]|[^""\\\\])*""/;
singleString = /'(?:\\\\'|\\\\[^']|[^'\\\\])*'/;
identifier = /[_\w][-_\w]*/;
literal = /.+/;
ws = /\s+/;
path = /(([A-Za-z]:)?[\/\\\\])?[-_\\w.]+([\/\\\\][-_\\w.]+)*[\/\\\\]?/;

string = doubleString | singleString;
shortOptionWithValue = shortOption equals (identifier | string);
longOptionWithValue = longOption equals (identifier | string);

options = *(shortOptionWithValue | longOptionWithValue | shortOptions | longOption | identifier | string);

details = options ?(endOptions literal);

root = (string | path) ?details;
";

            var parserGen = new ParserGenerator();
            var settings  = new ParserSettings
            {
                Algorithm   = Algorithm.LL,
                NestingType = NestingType.Stack,
                Unit        = Unit.Character,
            };

            parser = parserGen.SpawnParser(settings, grammar, "ws");

            parser.AttachAction("shortOptions", (branch, recurse) =>
            {
                var startIndex = branch.Leaf.StartIndex;
                IEnumerable <BranchSemanticNode> nodes = branch.Leaf.MatchedText
                                                         .Skip(1)
                                                         .Select((c, i) =>
                {
                    return(new BranchSemanticNode((int)CommandNodeType.Argument,
                                                  new LeafSemanticNode((int)CommandNodeType.ShortOption, startIndex + 1 + i, c.ToString())));
                });

                return(new BranchSemanticNode((int)CommandNodeType.Arguments, startIndex, nodes));
            });

            parser.AttachAction("shortOption", (branch, recurse) =>
            {
                LeafParseNode nameNode = branch.Leaf;
                var startIndex         = nameNode.StartIndex;
                var name = nameNode.MatchedText[1].ToString();

                return(new BranchSemanticNode((int)CommandNodeType.Argument,
                                              new LeafSemanticNode((int)CommandNodeType.ShortOption, startIndex, name)));
            });

            parser.AttachAction("shortOptionWithValue", (branch, recurse) =>
            {
                LeafParseNode nameNode = branch.GetDescendant(0).Leaf;
                var startIndex         = nameNode.StartIndex;
                var name            = nameNode.MatchedText[1].ToString();
                ISemanticNode value = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)CommandNodeType.Argument,
                                              new LeafSemanticNode((int)CommandNodeType.ShortOption, startIndex, name),
                                              value));
            });

            parser.AttachAction("longOption", (branch, recurse) =>
            {
                LeafParseNode nameNode = branch.Leaf;
                var startIndex         = nameNode.StartIndex;
                var name = nameNode.MatchedText.Substring(2);

                return(new BranchSemanticNode((int)CommandNodeType.Argument,
                                              new LeafSemanticNode((int)CommandNodeType.LongOption, startIndex, name)));
            });

            parser.AttachAction("longOptionWithValue", (branch, recurse) =>
            {
                LeafParseNode nameNode = branch.GetDescendant(0).Leaf;
                var startIndex         = nameNode.StartIndex;
                var name            = nameNode.MatchedText.Substring(2);
                ISemanticNode value = recurse(branch.GetDescendant(2));

                return(new BranchSemanticNode((int)CommandNodeType.Argument,
                                              new LeafSemanticNode((int)CommandNodeType.LongOption, startIndex, name),
                                              value));
            });

            parser.AttachAction("identifier", (branch, recurse) =>
            {
                LeafParseNode nameNode = branch.Leaf;
                var startIndex         = nameNode.StartIndex;
                var name = nameNode.MatchedText;

                return(new LeafSemanticNode((int)CommandNodeType.String, startIndex, name));
            });

            parser.AttachAction("doubleString", (branch, recurse) =>
            {
                var text = branch.Leaf.MatchedText;
                text     = text
                           .Substring(1, text.Length - 2)
                           .Replace(@"\\", @"\")
                           .Replace(@"\""", @"""");
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)CommandNodeType.String, startIndex, text));
            });

            parser.AttachAction("singleString", (branch, recurse) =>
            {
                var text = branch.Leaf.MatchedText;
                text     = text
                           .Substring(1, text.Length - 2)
                           .Replace(@"\\", @"\")
                           .Replace(@"\'", @"'");
                var startIndex = branch.Leaf.StartIndex;

                return(new LeafSemanticNode((int)CommandNodeType.String, startIndex, text));
            });

            parser.AttachAction("string", (branch, recurse) => recurse(branch.GetDescendant(0)));

            parser.AttachAction("options", (branch, recurse) =>
            {
                IEnumerable <ISemanticNode> options = branch.GetDescendant(0)
                                                      ?.Elements
                                                      ?.Select(recurse);

                return(new BranchSemanticNode((int)CommandNodeType.Options, branch.StartIndex, options ?? new ISemanticNode[0]));
            });

            parser.AttachAction("literal", (branch, recurse) =>
            {
                var value = branch.Leaf.MatchedText;

                return(new LeafSemanticNode((int)CommandNodeType.String, branch.StartIndex, value));
            });

            parser.AttachAction("details", (branch, recurse) =>
            {
                BranchParseNode optionsNode = branch.GetDescendant(0);
                BranchParseNode literalNode = branch.GetDescendant(1, 1);

                var results = new List <ISemanticNode>();

                if (optionsNode != null)
                {
                    results.Add(recurse(optionsNode));
                }
                if (literalNode != null)
                {
                    results.Add(recurse(literalNode));
                }

                return(new BranchSemanticNode((int)CommandNodeType.Details, branch.StartIndex, results));
            });

            parser.AttachAction("path", (branch, recurse) =>
            {
                var value = branch.MatchedText;

                return(new LeafSemanticNode((int)CommandNodeType.String, branch.StartIndex, value));
            });

            parser.AttachAction("root", (branch, recurse) =>
            {
                ISemanticNode path    = recurse(branch.GetDescendant(0));
                ISemanticNode details = recurse(branch.GetDescendant(1));

                return(new BranchSemanticNode((int)CommandNodeType.Root, path, details));
            });
        }
        public void TestQuotedStringValue()
        {
            LanguageGrammar<string> g = new LanguageGrammar<string>();
            g.StringLiteralRule.Action = (s) => s;

            // Spin up a parser for our language.
            // TODO: Package this up and simplify it.
            var expressionHelper = new ExpressionHelper();
            //var classifierGen = new TerminalClassifier<char>();
            var classifierSession = new TerminalClassifierSession<char, ParserState, int>()
                .AddSkipTerminal(new Terminal<char> { Name = "Whitespace", InitialState = RegexCharNFABuilder.RegexCompiler(@"\s+") })
                .CurrentCharExprIs(x => x.CurrentChar())
                .GetFromMarkExprIs(x => x.GetFromMarkedPos())
                .HasCurrentCharExprIs(x => x.HasCurrentChar())
                .MarkPosExprIs(x => x.MarkPos())
                .MoveNextCharExprIs(x => x.MoveNextChar())
                .UnmarkPosExprIs(x => x.UnmarkPos());

            var parserGen = new ParserGenerator<char>(expressionHelper);
            var parseTableBuilder = new LRParseTableBuilder();
            var parseTable = parseTableBuilder.BuildParseTable(g);
            var session = parserGen.NewSession<ParserState>()
                .NonTerminalValueExprIs<object>(x => x.NonTerminalValue)
                .TerminalValueExprIs<string>(x => x.TerminalStringValue)
                .TerminalValueExprIs<int>(x => x.TerminalIntValue)
                .TerminalValueExprIs<double>(x => x.TerminalDoubleValue)
                .TerminalIs(x => x.Terminal)
                .NonTerminalIs(x => x.NonTerminal)
                .IncludeSymbols(true)
                .UseDefaultValue(true)
                .DebugOutputIs(x => Debug.WriteLine(x))
                .Generate("LanguageParser", parseTable, classifierSession);
            // At this point, session is an Expression<ParserState,int> representing our parser.
            // We can compile it into a delegate or a MethodBuilder.  For the examples, we'll use a delegate.
            var compiler = session.Compile();

            ParserState ps = new ParserState("\"This is a quoted string\"");
            Assert.AreEqual(0, compiler(ps));
            Assert.AreEqual("This is a quoted string", ps.NonTerminalValue);

            ps = new ParserState("\"Here are some \\t escape characters\\r\\netc...\"");
            Assert.AreEqual(0, compiler(ps));
            Assert.AreEqual("Here are some \t escape characters\r\netc...", ps.NonTerminalValue);

            ps = new ParserState("\"And more \\\\ escape \\\" characters\"");
            Assert.AreEqual(0, compiler(ps));
            Assert.AreEqual("And more \\ escape \" characters", ps.NonTerminalValue);
        }
Exemple #32
0
        // TODO: Add Rules with more symbols
        // TODO: Ensure we have the context version of these.

        public IParser <Result, Context> MakeParser(ParserGenerator algorithm = ParserGenerator.LALR) => new Parser <Result, Context>(this, algorithm);
Exemple #33
0
        /// <summary>
        /// Create JavaScript Parser
        /// </summary>
        private static void create_parser()
        {
            //parser = new JSParser().Parser;

            var gen = new ParserGenerator();

            // https://github.com/antlr/grammars-v4/blob/master/javascript/JavaScriptParser.g4
            var program                     = gen.CreateNewProduction("program", false);
            var sourceElement               = gen.CreateNewProduction("sourceElement", false);
            var statement                   = gen.CreateNewProduction("statement", false);
            var block                       = gen.CreateNewProduction("block", false);
            var statementList               = gen.CreateNewProduction("statementList", false);
            var statementListE              = gen.CreateNewProduction("statementListE", false);
            var variableStatement           = gen.CreateNewProduction("variableStatement", false);
            var variableDeclarationList     = gen.CreateNewProduction("variableDeclarationList", false);
            var variableDeclarationListArgs = gen.CreateNewProduction("variableDeclarationListArgs", false);
            var variableDeclaration         = gen.CreateNewProduction("variableDeclaration", false);
            var variableDeclarationT        = gen.CreateNewProduction("variableDeclarationT", false);
            var emptyStatement              = gen.CreateNewProduction("emptyStatement", false);
            var expressionStatement         = gen.CreateNewProduction("expressionStatement", false);
            var ifStatement                 = gen.CreateNewProduction("ifStatement", false);
            var expressionSequenceE         = gen.CreateNewProduction("expressionSequenceE", false);
            var iterationStatement          = gen.CreateNewProduction("iterationStatement", false);
            var varModifier                 = gen.CreateNewProduction("varModifier", false);
            var continueStatement           = gen.CreateNewProduction("continueStatement", false);
            var breakStatement              = gen.CreateNewProduction("breakStatement", false);
            var returnStatement             = gen.CreateNewProduction("returnStatement", false);
            var withStatement               = gen.CreateNewProduction("withStatement", false);
            var switchStatement             = gen.CreateNewProduction("switchStatement", false);
            var caseBlock                   = gen.CreateNewProduction("caseBlock", false);
            var caseClauses                 = gen.CreateNewProduction("caseClauses", false);
            var caseClausesE                = gen.CreateNewProduction("caseClausesE", false);
            var caseClause                  = gen.CreateNewProduction("caseClause", false);
            var defaultClause               = gen.CreateNewProduction("defaultClause", false);
            var labelledStatement           = gen.CreateNewProduction("labelledStatement", false);
            var throwStatement              = gen.CreateNewProduction("throwStatement", false);
            var tryStatement                = gen.CreateNewProduction("tryStatement", false);
            var catchProduction             = gen.CreateNewProduction("catchProduction", false);
            var finallyProduction           = gen.CreateNewProduction("finallyProduction", false);
            var debuggerStatement           = gen.CreateNewProduction("debuggerStatement", false);
            var functionDeclaration         = gen.CreateNewProduction("functionDeclaration", false);
            var classDeclaration            = gen.CreateNewProduction("classDeclaration", false);
            var classTail                   = gen.CreateNewProduction("classTail", false);
            var classElement                = gen.CreateNewProduction("classElement", false);
            var classElements               = gen.CreateNewProduction("classElements", false);
            var methodDefinition            = gen.CreateNewProduction("methodDefinition", false);
            var generatorMethod             = gen.CreateNewProduction("generatorMethod", false);
            var formalParameterList         = gen.CreateNewProduction("formalParameterList", false);
            var formalParameterArg          = gen.CreateNewProduction("formalParameterArg", false);
            var formalParameterArgS         = gen.CreateNewProduction("formalParameterArgS", false);
            var lastFormalParameterArg      = gen.CreateNewProduction("lastFormalParameterArg", false);
            var functionBody                = gen.CreateNewProduction("functionBody", false);
            var sourceElements              = gen.CreateNewProduction("sourceElements", false);
            var arrayLiteral                = gen.CreateNewProduction("arrayLiteral", false);
            var elementList                 = gen.CreateNewProduction("elementList", false);
            var lastElement                 = gen.CreateNewProduction("lastElement", false);
            var objectLiteral               = gen.CreateNewProduction("objectLiteral", false);
            var propertyAssignment          = gen.CreateNewProduction("propertyAssignment", false);
            var propertyAssignmentS         = gen.CreateNewProduction("propertyAssignmentS", false);
            var propertyName                = gen.CreateNewProduction("propertyName", false);
            var arguments                   = gen.CreateNewProduction("arguments", false);
            var lastArgument                = gen.CreateNewProduction("lastArgument", false);
            var expressionSequence          = gen.CreateNewProduction("expressionSequence", false);
            var singleExpression            = gen.CreateNewProduction("singleExpression", false);
            var singleExpressionS           = gen.CreateNewProduction("singleExpressionS", false);
            var arrowFunctionParameters     = gen.CreateNewProduction("arrowFunctionParameters", false);
            var arrowFunctionBody           = gen.CreateNewProduction("arrowFunctionBody", false);
            var assignmentOperator          = gen.CreateNewProduction("assignmentOperator", false);
            var literal                     = gen.CreateNewProduction("literal", false);
            var numericLiteral              = gen.CreateNewProduction("numericLiteral", false);
            var identifierName              = gen.CreateNewProduction("identifierName", false);
            var reservedWord                = gen.CreateNewProduction("reservedWord", false);
            var keyword                     = gen.CreateNewProduction("keyword", false);
            var getter                      = gen.CreateNewProduction("getter", false);
            var setter                      = gen.CreateNewProduction("setter", false);
            var eos  = gen.CreateNewProduction("eos", false);
            var star = gen.CreateNewProduction("star", false);

            program |= sourceElements;
            program |= ParserGenerator.EmptyString;

            sourceElements |= sourceElements + sourceElement;
            sourceElements |= ParserGenerator.EmptyString;

            sourceElement |= "Export" + statement;
            sourceElement |= statement;

            statement |= block;
            statement |= variableStatement;
            statement |= emptyStatement;
            statement |= classDeclaration;
            statement |= expressionStatement;
            statement |= ifStatement;
            statement |= iterationStatement;
            statement |= continueStatement;
            statement |= breakStatement;
            statement |= returnStatement;
            statement |= withStatement;
            statement |= labelledStatement;
            statement |= switchStatement;
            statement |= throwStatement;
            statement |= tryStatement;
            statement |= debuggerStatement;
            statement |= functionDeclaration;

            block |= "{" + statementList + "}";

            statementList  |= statementListE + statement;
            statementListE |= statementListE + statement;
            statementListE |= ParserGenerator.EmptyString;

            variableStatement |= varModifier + variableDeclarationList + eos;

            variableDeclarationList     |= variableDeclaration + variableDeclarationListArgs;
            variableDeclarationListArgs |= "," + variableDeclarationListArgs;
            variableDeclarationListArgs |= ParserGenerator.EmptyString;

            variableDeclaration |= "Identifier" + variableDeclarationT;
            variableDeclaration |= arrayLiteral + variableDeclarationT;
            variableDeclaration |= objectLiteral + variableDeclarationT;

            variableDeclarationT |= "=" + singleExpression;
            variableDeclarationT |= ParserGenerator.EmptyString;

            emptyStatement |= "SemiColon";

            expressionStatement |= expressionSequence + eos; // TODO: 90: {this.notOpenBraceAndNotFunction()}? expressionSequence eos

            ifStatement |= gen.TryCreateNewProduction("If") + "(" + expressionSequence + ")" + statement;
            ifStatement |= gen.TryCreateNewProduction("If") + "(" + expressionSequence + ")" + statement + "Else" + statement;

            expressionSequenceE |= expressionSequence;
            expressionSequenceE |= ParserGenerator.EmptyString;

            iterationStatement |= "Do" + statement + "While" + "(" + expressionSequence + ")" + eos;
            iterationStatement |= gen.TryCreateNewProduction("While") + "(" + expressionSequence + ")" + statement;
            iterationStatement |= gen.TryCreateNewProduction("For") + "(" + expressionSequenceE + ";" + expressionSequenceE + ";" + expressionSequenceE + ")" + statement;
            iterationStatement |= gen.TryCreateNewProduction("For") + "(" + varModifier + variableDeclarationList + ";" + expressionSequenceE + ";" + expressionSequenceE + ")" + statement;
            iterationStatement |= gen.TryCreateNewProduction("For") + "(" + singleExpression + "In" + expressionSequence + ")" + statement;
            iterationStatement |= gen.TryCreateNewProduction("For") + "(" + singleExpression + "Identifier" + expressionSequence + ")" + statement;
            iterationStatement |= gen.TryCreateNewProduction("For") + "(" + varModifier + variableDeclarationList + "In" + expressionSequence + ")" + statement;
            iterationStatement |= gen.TryCreateNewProduction("For") + "(" + varModifier + variableDeclarationList + "Identifier" + expressionSequence + ")" + statement;

            varModifier |= "Var";
            varModifier |= "Let";
            varModifier |= "Const";

            continueStatement |= "Continue" + eos;  // TODO
            continueStatement |= "Continue" + identifierName + eos;

            breakStatement |= "Break" + eos; // TODO
            breakStatement |= "Break" + identifierName + eos;

            returnStatement |= "Return" + eos; // TODO
            returnStatement |= "Return" + expressionSequence + eos;

            withStatement |= gen.TryCreateNewProduction("With") + "(" + expressionSequence + ")" + statement;

            switchStatement |= gen.TryCreateNewProduction("Switch") + "(" + expressionSequence + ")" + caseBlock;

            caseBlock |= gen.TryCreateNewProduction("{") + "}";
            caseBlock |= "{" + caseClauses + "}";
            caseBlock |= "{" + caseClauses + defaultClause + caseClauses + "}";
            caseBlock |= "{" + defaultClause + caseClauses + "}";
            caseBlock |= "{" + caseClauses + defaultClause + "}";
            caseBlock |= "{" + defaultClause + "}";

            caseClauses  |= caseClausesE + caseClause;
            caseClausesE |= caseClausesE + caseClause;
            caseClausesE |= ParserGenerator.EmptyString;

            caseClause |= "Case" + expressionSequence + ":";
            caseClause |= "Case" + expressionSequence + ":" + statementList;

            defaultClause |= gen.TryCreateNewProduction("Default") + ":";
            defaultClause |= gen.TryCreateNewProduction("Default") + ":" + statementList;

            labelledStatement |= gen.TryCreateNewProduction("Identifier") + ":" + statement;

            throwStatement |= "Throw" + expressionSequence + eos; // TODO

            tryStatement |= gen.TryCreateNewProduction("Try") + block + catchProduction;
            tryStatement |= gen.TryCreateNewProduction("Try") + block + catchProduction + finallyProduction;
            tryStatement |= gen.TryCreateNewProduction("Try") + block + finallyProduction;

            catchProduction |= gen.TryCreateNewProduction("Catch") + "(" + gen.TryCreateNewProduction("Identifier") + ")" + block;

            finallyProduction |= "Finally" + block;

            debuggerStatement |= "Debugger" + eos;

            functionDeclaration |= "Function" + gen.TryCreateNewProduction("Identifier") + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            functionDeclaration |= "Function" + gen.TryCreateNewProduction("Identifier") + "(" + formalParameterList + ")" + gen.TryCreateNewProduction("{") + functionBody + "}";

            classDeclaration |= gen.TryCreateNewProduction("Class") + "Identifier" + classTail;

            classTail     |= "{" + classElements + "}";
            classTail     |= "Extends" + singleExpression + "{" + classElements + "}";
            classElements |= classElements + classElement;

            classElement |= methodDefinition;
            classElement |= "Static" + methodDefinition;
            classElement |= "Identifier" + methodDefinition;
            classElement |= "Static" + "Identifier" + methodDefinition;
            classElement |= emptyStatement;

            methodDefinition |= propertyName + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            methodDefinition |= propertyName + "(" + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            methodDefinition |= getter + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            methodDefinition |= setter + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            methodDefinition |= setter + "(" + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            methodDefinition |= generatorMethod;

            generatorMethod |= "Identifier" + gen.TryCreateNewProduction("(") + ")" + gen.TryCreateNewProduction("{") + functionBody + "}";
            generatorMethod |= "*" + gen.TryCreateNewProduction("Identifier") + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            generatorMethod |= gen.TryCreateNewProduction("Identifier") + "(" + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            generatorMethod |= gen.TryCreateNewProduction("*") + "Identifier" + "(" + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";

            formalParameterList |= formalParameterArg + formalParameterArgS;
            formalParameterList |= formalParameterArg + "," + lastFormalParameterArg;
            formalParameterList |= formalParameterArg + formalParameterArgS + "," + lastFormalParameterArg;
            formalParameterList |= lastFormalParameterArg;
            formalParameterList |= arrayLiteral;
            formalParameterList |= objectLiteral;

            formalParameterArgS |= "," + formalParameterArg + formalParameterArgS;
            formalParameterArgS |= ParserGenerator.EmptyString;

            formalParameterArg |= "Identifier";
            formalParameterArg |= gen.TryCreateNewProduction("Identifier") + "=" + singleExpression;

            lastFormalParameterArg |= gen.TryCreateNewProduction("Ellipsis") + "Identifier";

            functionBody |= sourceElements;
            functionBody |= ParserGenerator.EmptyString;

            arrayLiteral |= "[" + star + "]";
            arrayLiteral |= "[" + star + elementList + star + "]";

            star |= "*" + star;
            star |= ParserGenerator.EmptyString;

            elementList |= singleExpression + singleExpressionS;
            elementList |= singleExpression + singleExpressionS + "," + lastElement;

            singleExpressionS |= "," + singleExpression + singleExpressionS;
            singleExpressionS |= ParserGenerator.EmptyString;

            lastElement |= gen.TryCreateNewProduction("Ellipsis") + "Identifier";

            objectLiteral |= gen.TryCreateNewProduction("{") + "}";
            objectLiteral |= "{" + gen.TryCreateNewProduction(",") + "}";
            objectLiteral |= "{" + propertyAssignment + propertyAssignmentS + "}";
            objectLiteral |= "{" + propertyAssignment + propertyAssignmentS + gen.TryCreateNewProduction(",") + "}";

            propertyAssignmentS |= "," + propertyAssignment + propertyAssignmentS;
            propertyAssignmentS |= ParserGenerator.EmptyString;

            propertyAssignment |= propertyName + ":" + singleExpression;
            propertyAssignment |= propertyName + "=" + singleExpression;
            propertyAssignment |= "[" + singleExpression + "]" + gen.TryCreateNewProduction(":") + singleExpression;
            propertyAssignment |= getter + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            propertyAssignment |= setter + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            propertyAssignment |= setter + "(" + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            propertyAssignment |= generatorMethod;
            propertyAssignment |= identifierName;

            propertyName |= identifierName;
            propertyName |= "StringLiteral";
            propertyName |= numericLiteral;

            arguments |= gen.TryCreateNewProduction("(") + ")";

            arguments |= "(" + singleExpression + singleExpressionS + ")";
            arguments |= "(" + singleExpression + singleExpressionS + "," + lastArgument + ")";

            lastArgument |= gen.TryCreateNewProduction("Ellipsis") + "Identifier";

            expressionSequence |= singleExpression + singleExpressionS;

            singleExpression |= "Function" + gen.TryCreateNewProduction("(") + ")" + gen.TryCreateNewProduction("{") + functionBody + "}";
            singleExpression |= "Function" + gen.TryCreateNewProduction("Identifier") + "(" + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            singleExpression |= "Function" + gen.TryCreateNewProduction("(") + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            singleExpression |= "Function" + gen.TryCreateNewProduction("Identifier") + "(" + formalParameterList + gen.TryCreateNewProduction(")") + "{" + functionBody + "}";
            singleExpression |= "Class" + classTail;
            singleExpression |= gen.TryCreateNewProduction("Class") + "Identifier" + classTail;
            singleExpression |= singleExpression + "[" + expressionSequence + "]";
            singleExpression |= singleExpression + "." + identifierName;
            singleExpression |= singleExpression + arguments;
            singleExpression |= "New" + singleExpression;
            singleExpression |= "New" + singleExpression + arguments;
            singleExpression |= singleExpression + "++"; // TODO
            singleExpression |= singleExpression + "--"; // TODO
            singleExpression |= "Delete" + singleExpression;
            singleExpression |= "Void" + singleExpression;
            singleExpression |= "Typeof" + singleExpression;
            singleExpression |= "++" + singleExpression;
            singleExpression |= "--" + singleExpression;
            singleExpression |= "+" + singleExpression;
            singleExpression |= "-" + singleExpression;
            singleExpression |= "~" + singleExpression;
            singleExpression |= "!" + singleExpression;
            singleExpression |= singleExpression + "*" + singleExpression;
            singleExpression |= singleExpression + "/" + singleExpression;
            singleExpression |= singleExpression + "%" + singleExpression;
            singleExpression |= singleExpression + "+" + singleExpression;
            singleExpression |= singleExpression + "-" + singleExpression;
            singleExpression |= singleExpression + "<<" + singleExpression;
            singleExpression |= singleExpression + ">>" + singleExpression;
            singleExpression |= singleExpression + ">>>" + singleExpression;
            singleExpression |= singleExpression + "<" + singleExpression;
            singleExpression |= singleExpression + ">" + singleExpression;
            singleExpression |= singleExpression + "<=" + singleExpression;
            singleExpression |= singleExpression + ">=" + singleExpression;

            singleExpression |= singleExpression + "Instanceof" + singleExpression;
            singleExpression |= singleExpression + "In" + singleExpression;
            singleExpression |= singleExpression + "==" + singleExpression;
            singleExpression |= singleExpression + "!=" + singleExpression;
            singleExpression |= singleExpression + "===" + singleExpression;
            singleExpression |= singleExpression + "!==" + singleExpression;
            singleExpression |= singleExpression + "&" + singleExpression;
            singleExpression |= singleExpression + "^" + singleExpression;
            singleExpression |= singleExpression + "|" + singleExpression;
            singleExpression |= singleExpression + "&&" + singleExpression;
            singleExpression |= singleExpression + "||" + singleExpression;
            singleExpression |= singleExpression + "?" + singleExpression + ":" + singleExpression;
            singleExpression |= singleExpression + "=" + singleExpression;
            singleExpression |= singleExpression + assignmentOperator + singleExpression;
            singleExpression |= singleExpression + "TemplateStringLiteral";
            singleExpression |= "This";
            singleExpression |= "Identifier";
            singleExpression |= "Super";
            singleExpression |= literal;
            singleExpression |= arrayLiteral;
            singleExpression |= objectLiteral;
            singleExpression |= "(" + expressionSequence + ")";
            singleExpression |= arrowFunctionParameters + "=>" + arrowFunctionBody;

            arrowFunctionParameters |= "Identifier";
            arrowFunctionParameters |= gen.TryCreateNewProduction("(") + ")";
            arrowFunctionParameters |= "(" + formalParameterList + ")";

            arrowFunctionBody |= singleExpression;
            arrowFunctionBody |= "{" + functionBody + "}";

            assignmentOperator |= "*=";
            assignmentOperator |= "/=";
            assignmentOperator |= "%=";
            assignmentOperator |= "+=";
            assignmentOperator |= "-=";
            assignmentOperator |= "<<=";
            assignmentOperator |= ">>=";
            assignmentOperator |= ">>>=";
            assignmentOperator |= "&=";
            assignmentOperator |= "^=";
            assignmentOperator |= "|=";

            literal |= "NullLiteral";
            literal |= "BooleanLiteral";
            literal |= "StringLiteral";
            literal |= "TemplateStringLiteral";
            literal |= "RegularExpressionLiteral";
            literal |= "numericLiteral";

            numericLiteral |= "DecimalLiteral";
            numericLiteral |= "HexIntegerLiteral";
            numericLiteral |= "OctalIntegerLiteral";
            numericLiteral |= "OctalIntegerLiteral2";
            numericLiteral |= "BinaryIntegerLiteral";

            identifierName |= "Identifier";
            identifierName |= reservedWord;

            reservedWord |= keyword;
            reservedWord |= "NullLiteral";
            reservedWord |= "BooleanLiteral";

            keyword |= "Class";
            keyword |= "Break";
            keyword |= "Do";
            keyword |= "Instanceof";
            keyword |= "Typeof";
            keyword |= "Case";
            keyword |= "Else";
            keyword |= "New";
            keyword |= "Var";
            keyword |= "Catch";
            keyword |= "Finally";
            keyword |= "Return";
            keyword |= "Void";
            keyword |= "Continue";
            keyword |= "For";
            keyword |= "Switch";
            keyword |= "While";
            keyword |= "Debugger";
            keyword |= "Function";
            keyword |= "This";
            keyword |= "With";
            keyword |= "Default";
            keyword |= "If";
            keyword |= "Throw";
            keyword |= "Delete";
            keyword |= "In";
            keyword |= "Try";
            keyword |= "Enum";
            keyword |= "Extends";
            keyword |= "Super";
            keyword |= "Const";
            keyword |= "Export";
            keyword |= "Import";
            keyword |= "Implements";
            keyword |= "Let";
            keyword |= "Private";
            keyword |= "Public";
            keyword |= "Interface";
            keyword |= "Package";
            keyword |= "Protected";
            keyword |= "Static";
            keyword |= "Yield";

            //getter |= propertyName; // TODO

            //setter |= propertyName; // TODO

            eos |= "SemiColon"; // TODO
            //eos |= "$";
            //eos |= ParserGenerator.EmptyString;


            gen.PushConflictSolver(true, gen.TryCreateNewProduction("Break"),
                                   gen.TryCreateNewProduction("Do"),
                                   gen.TryCreateNewProduction("Typeof"),
                                   gen.TryCreateNewProduction("Case"),
                                   gen.TryCreateNewProduction("Else"),
                                   gen.TryCreateNewProduction("New"),
                                   gen.TryCreateNewProduction("Var"),
                                   gen.TryCreateNewProduction("Catch"),
                                   gen.TryCreateNewProduction("Finally"),
                                   gen.TryCreateNewProduction("Return"),
                                   gen.TryCreateNewProduction("Void"),
                                   gen.TryCreateNewProduction("Continue"),
                                   gen.TryCreateNewProduction("For"),
                                   gen.TryCreateNewProduction("Switch"),
                                   gen.TryCreateNewProduction("While"),
                                   gen.TryCreateNewProduction("Debugger"),
                                   gen.TryCreateNewProduction("Function"),
                                   gen.TryCreateNewProduction("This"),
                                   gen.TryCreateNewProduction("With"),
                                   gen.TryCreateNewProduction("Default"),
                                   gen.TryCreateNewProduction("If"),
                                   gen.TryCreateNewProduction("Throw"),
                                   gen.TryCreateNewProduction("Delete"),
                                   gen.TryCreateNewProduction("Try"),
                                   gen.TryCreateNewProduction("Enum"),
                                   gen.TryCreateNewProduction("Class"),
                                   gen.TryCreateNewProduction("Extends"),
                                   gen.TryCreateNewProduction("Super"),
                                   gen.TryCreateNewProduction("Const"),
                                   gen.TryCreateNewProduction("Export"),
                                   gen.TryCreateNewProduction("Import"),
                                   gen.TryCreateNewProduction("Implements"),
                                   gen.TryCreateNewProduction("Let"),
                                   gen.TryCreateNewProduction("Private"),
                                   gen.TryCreateNewProduction("Public"),
                                   gen.TryCreateNewProduction("Interface"),
                                   gen.TryCreateNewProduction("Package"),
                                   gen.TryCreateNewProduction("Protected"),
                                   gen.TryCreateNewProduction("Static"),
                                   gen.TryCreateNewProduction("Yield"));

            gen.PushConflictSolver(true, gen.TryCreateNewProduction("Identifier"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("NullLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("BooleanLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("StringLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("TemplateStringLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("RegularExpressionLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("numericLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("DecimalLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("HexIntegerLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("OctalIntegerLiteral"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("OctalIntegerLiteral2"));
            gen.PushConflictSolver(true, gen.TryCreateNewProduction("BinaryIntegerLiteral"));

            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(ifStatement, 0));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(keyword, 0));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(block, 0));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(statementListE, 1));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(caseClausesE, 1));
            //gen.PushConflictSolver(true, new Tuple<ParserProduction, int>(eos, 1));
            //gen.PushConflictSolver(false, gen.TryCreateNewProduction("Class"));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("["));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("("));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("{"));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("."));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("++"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("--"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("~"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("!"));

            // +, -
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(singleExpression, 16), new Tuple <ParserProduction, int>(singleExpression, 17));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("*"), gen.TryCreateNewProduction("/"), gen.TryCreateNewProduction("%"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("+"), gen.TryCreateNewProduction("-"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("<<"), gen.TryCreateNewProduction(">>"), gen.TryCreateNewProduction(">>>"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("<"), gen.TryCreateNewProduction(">"), gen.TryCreateNewProduction("<="), gen.TryCreateNewProduction(">="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("Instanceof"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("In"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("=="), gen.TryCreateNewProduction("!="), gen.TryCreateNewProduction("==="), gen.TryCreateNewProduction("!=="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("&"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("^"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("|"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("&&"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("||"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("?"), gen.TryCreateNewProduction(":"));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("="));

            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(singleExpression, 47));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("*="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("/="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("%="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("+="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("-="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("<<="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction(">>="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction(">>>="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("&="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("^="));
            gen.PushConflictSolver(false, gen.TryCreateNewProduction("|="));

            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(formalParameterArgS, 0));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(formalParameterArgS, 1));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(arrowFunctionBody, 0));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction(","));

            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(singleExpressionS, 1));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(propertyAssignmentS, 1));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("SemiColon"));

            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(sourceElements, 1));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(caseBlock, 0));

            gen.PushConflictSolver(false, gen.TryCreateNewProduction("}"));

            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(functionBody, 1));


            try
            {
                gen.PushStarts(program);
                gen.PrintProductionRules();

                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
                gen.Generate();
                var end = sw.ElapsedMilliseconds;
                sw.Stop();
                Log.Logs.Instance.Push($"{end.ToString("#,#")}");
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Log.Logs.Instance.PushError(e.Message + "\r\n" + e.StackTrace);
            }

            File.WriteAllText(DateTime.Now.Ticks + ".txt", gen.GlobalPrinter.ToString());

            parser = gen.CreateExtendedShiftReduceParserInstance();
            File.WriteAllText("jsparser.cs", parser.ToCSCode("JSParser"));
        }
        public void TestParserSucceedsWithoutAValue()
        {
            LanguageGrammar<Expression> g = new LanguageGrammar<Expression>();

            // Spin up a parser for our language.
            // TODO: Package this up and simplify it.
            var expressionHelper = new ExpressionHelper();
            //var classifierGen = new TerminalClassifier<char>();
            var classifierSession = new TerminalClassifierSession<char, ParserState, int>()
                .CurrentCharExprIs(x => x.CurrentChar())
                .GetFromMarkExprIs(x => x.GetFromMarkedPos())
                .HasCurrentCharExprIs(x => x.HasCurrentChar())
                .MarkPosExprIs(x => x.MarkPos())
                .MoveNextCharExprIs(x => x.MoveNextChar())
                .UnmarkPosExprIs(x => x.UnmarkPos());

            var parserGen = new ParserGenerator<char>(expressionHelper);
            var parseTableBuilder = new LRParseTableBuilder();
            var parseTable = parseTableBuilder.BuildParseTable(g);
            var session = parserGen.NewSession<ParserState>()
                .NonTerminalValueExprIs<object>(x => x.NonTerminalValue)
                .TerminalValueExprIs<string>(x => x.TerminalStringValue)
                .TerminalValueExprIs<int>(x => x.TerminalIntValue)
                .TerminalValueExprIs<double>(x => x.TerminalDoubleValue)
                .TerminalIs(x => x.Terminal)
                .NonTerminalIs(x => x.NonTerminal)
                .IncludeSymbols(true)
                .UseDefaultValue(true)
                .DebugOutputIs(x => Debug.WriteLine(x))
                .Generate("LanguageParser", parseTable, classifierSession);
            // At this point, session is an Expression<ParserState,int> representing our parser.
            // We can compile it into a delegate or a MethodBuilder.  For the examples, we'll use a delegate.
            var compiler = session.Compile();

            // Create a parser state object and initialize it.
            ParserState ps = new ParserState("x*y+2.0");
            Assert.AreEqual(0, compiler(ps));
        }