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); }
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); } }
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()); }
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()); }
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); }
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"); }
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); } }
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); } }
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; }
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(); }
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()); }
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; }
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); }
/// <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()); }
/// <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 }
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()); }
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); }
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)); } }
/// <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()); }
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;
/// <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; } }
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); //} }
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); }
// 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);
/// <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)); }