예제 #1
0
        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);
        }
예제 #2
0
        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();
            }
        }