public void ParseTest() { LexicalRule digit = LexicalRule.Range('0', '9'); LexerBuilder lexb = new LexerBuilder(); var blank = lexb.DefineLexeme(0, true, LexicalRule.Chars(" \n\t\r").Repeat()); var number = lexb.DefineLexeme(1, digit.Repeat() + (LexicalRule.Char('.') + digit.Repeat() | LexicalRule.Empty)); var plus = lexb.DefineLexeme(2, LexicalRule.Char('+')); var minus = lexb.DefineLexeme(2, LexicalRule.Char('-')); var times = lexb.DefineLexeme(2, LexicalRule.Char('*')); var divide = lexb.DefineLexeme(2, LexicalRule.Char('/')); var bra = lexb.DefineLexeme(3, LexicalRule.Char('(')); var ket = lexb.DefineLexeme(3, LexicalRule.Char(')')); var plu = plus.GetParsingRule(); var min = minus.GetParsingRule(); var mul = times.GetParsingRule(); var div = divide.GetParsingRule(); var br = bra.GetParsingRule(); var ke = ket.GetParsingRule(); var num = number.GetParsingRule(i => double.Parse(i.Text)); ParsingRuleContainer <double> expr = new ParsingRuleContainer <double>(); ParsingRuleContainer <double> term = new ParsingRuleContainer <double>(); ParsingRuleContainer <double> factor = new ParsingRuleContainer <double>(); // ParsingRuleContainer<int, double> bracket = new ParsingRuleContainer<int, double>(); expr.Content = term.Concat((plu.Concat(term, (t, y) => y) | min.Concat(term, (t, y) => - y)).Repeat(i => i.Sum()), (x, y) => x + y) | term; term.Content = factor.Concat((mul.Concat(term, (s, y) => y) | (div.Concat(term, (s, y) => 1 / y))).Repeat(t => t.Count() == 0 ? 1 : t.Aggregate((x, y) => x * y)), (x, y) => x * y) | factor; factor.Content = br.Concat(expr, (s, x) => x).Concat(ke, (x, s) => x) | num; string str = "1 * 5 + 2 * 3 / 5 - 3"; BranchedLexer lexer = lexb.GetBranchedLexer(str); double r; expr.TryParse(lexer, out r); Assert.AreEqual(1.0 * 5.0 + 2.0 * 3.0 / 5.0 - 3.0, r); }
public void LexerTest() { LexicalRule letter = LexicalRule.Range('A', 'Z') | LexicalRule.Range('a', 'z'); LexicalRule digit = LexicalRule.Range('0', '9'); LexerBuilder lexb = new LexerBuilder(); Lexeme blank = lexb.DefineLexeme(0, true, LexicalRule.Chars(" \n\t\r").Repeat()); Lexeme id = lexb.DefineLexeme(1, letter + (letter | digit).Repeat()); Lexeme keyword = lexb.DefineLexeme(2, LexicalRule.Literal("var") | LexicalRule.Literal("function") | LexicalRule.Literal("new") | LexicalRule.Literal("this") | LexicalRule.Literal("for") | LexicalRule.Literal("return")); Lexeme number = lexb.DefineLexeme(3, digit.Repeat() + (LexicalRule.Char('.') + digit.Repeat() | LexicalRule.Empty)); Lexeme inc = lexb.DefineLexeme(4, LexicalRule.Literal("++")); Lexeme oper = lexb.DefineLexeme(4, LexicalRule.Chars("+-*/^=<>")); Lexeme str = lexb.DefineLexeme(5, LexicalRule.Char('\'') + (LexicalRule.NotChar('\'') | LexicalRule.Literal(@"\'")).Repeat() + LexicalRule.Char('\'')); Lexeme bracket = lexb.DefineLexeme(6, LexicalRule.Chars("()[]{}")); Lexeme deli = lexb.DefineLexeme(7, LexicalRule.Chars(",;:")); Lexeme comm = lexb.DefineLexeme(10, true, LexicalRule.Literal("//") + LexicalRule.NotChars("\n\r").Repeat() + LexicalRule.Chars("\n\r")); Lexeme commul = lexb.DefineLexeme(10, true, LexicalRule.Literal("/*") + (LexicalRule.Char('/') | LexicalRule.Char('*').Repeat() + LexicalRule.NotChars("/*")).Repeat() + LexicalRule.Char('*') + LexicalRule.Char('/')); var input = System.IO.File.ReadAllText("test_data/1.input.txt"); var expected = System.IO.File.ReadAllText("test_data/1.expected.txt"); string actual; { var sb = new System.Text.StringBuilder(); BranchedLexer blexer = lexb.GetBranchedLexer(input); Token t; while ((t = blexer.Read()) != null) { sb.AppendLine(t.ToString()); } actual = sb.ToString(); } if (expected != actual) { System.IO.File.WriteAllText("test_data/1.actual.txt", actual); Assert.Fail(); } }