Esempio n. 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);
        }
Esempio n. 2
0
        private void InitializeMemberParsers()
        {
            var modifier
                = lex_kw_public.GetParsingRule(t => Modifier.Public)
                  | lex_kw_private.GetParsingRule(t => Modifier.Private)
                  | lex_kw_protected.GetParsingRule(t => Modifier.Protected)
                  | ParsingRule <Modifier> .Empty(Modifier.Public);

            var mem_modifier
                = lex_kw_static.GetParsingRule(t => true)
                  .Concat(modifier, (t, u) => Tuple.Create(t, u))
                  | modifier
                  .Concat(lex_kw_static.GetParsingRule(t => true) | ParsingRule <bool> .Empty(false), (u, t) => Tuple.Create(t, u))
                  | ParsingRule <Tuple <bool, Modifier> > .Empty(Tuple.Create(false, Modifier.Public));

            var mem_field
                = (lex_op_assign.GetParsingRule()
                   .Concat(p_expression.OrFail(ExceptionResource.ExpressionExpected), (t, e) => e)
                   | PCE.Empty(null))
                  .Map(e => Tuple.Create(0, e, (ParameterCollection)null, (StatementCollection)null,
                                         (Tuple <Accessor, Accessor>)null));

            var mem_method
                = p_paras
                  .Concat(p_stats.OrFail(ExceptionResource.StatementsExpected),
                          (t, stats) => Tuple.Create(1, (Expression)null, t, stats,
                                                     (Tuple <Accessor, Accessor>)null));

            var mem_constructor
                = lex_kw_constructor.GetParsingRule()
                  .Concat(p_paras.OrFail(ExceptionResource.ParemetersExpected), (t, paras) => paras)
                  .Concat(p_stats.OrFail(ExceptionResource.StatementsExpected),
                          (t, stats) => Tuple.Create(2, (Expression)null, t, stats,
                                                     (Tuple <Accessor, Accessor>)null));

            var modifier1
                = lex_kw_public.GetParsingRule(t => (Modifier?)Modifier.Public)
                  | lex_kw_private.GetParsingRule(t => (Modifier?)Modifier.Private)
                  | lex_kw_protected.GetParsingRule(t => (Modifier?)Modifier.Protected)
                  | ParsingRule <Modifier?> .Empty(null);

            var getter
                = modifier1
                  .Concat(lex_kw_get.GetParsingRule(), (t, g) => Tuple.Create(t, g))
                  .Concat(
                      lex_op_semicolon.GetParsingRule(t => (StatementCollection)null)
                      | p_stats.OrFail(ExceptionResource.StatementsExpected),
                      (t, stats) => new Accessor(t.Item2.LinePragma, t.Item1, stats));
            var setter
                = modifier1
                  .Concat(lex_kw_set.GetParsingRule(), (t, g) => Tuple.Create(t, g))
                  .Concat(
                      lex_op_semicolon.GetParsingRule(t => (StatementCollection)null)
                      | p_stats.OrFail(ExceptionResource.StatementsExpected),
                      (t, stats) => new Accessor(t.Item2.LinePragma, t.Item1, stats));
            var prop_stats
                = getter.Concat(setter | ParsingRule <Accessor> .Empty(null), (g, s) => Tuple.Create(g, s))
                  | setter.Concat(getter | ParsingRule <Accessor> .Empty(null), (s, g) => Tuple.Create(g, s));

            var mem_property
                = lex_op_leftBrace.GetParsingRule()
                  .Concat(prop_stats, (t, s) => s)
                  .Concat(lex_op_rightBrace.GetParsingRule().OrFailExpected("}"), (t, b) => t)
                  .Map(t =>
            {
                return(Tuple.Create(3, (Expression)null, (ParameterCollection)null, (StatementCollection)null, t));
            });

            ParsingRule <Tuple <int, Expression, ParameterCollection, StatementCollection, Tuple <Accessor, Accessor> > > mem_indexer
                = lex_kw_this.GetParsingRule()
                  .Concat(lex_op_leftBracket.GetParsingRule(), (t, b) => t)
                  .Concat(p_paraList, (t, p) => p)
                  .Concat(lex_op_rightBracket.GetParsingRule().OrFailExpected("]"), (t, b) => t)
                  .Concat(lex_op_leftBrace.GetParsingRule().OrFailExpected("{"), (t, b) => t)
                  .Concat(prop_stats, (t, s) => Tuple.Create(t, s))
                  .Concat(lex_op_rightBrace.GetParsingRule().OrFailExpected("}"), (t, b) => t)
                  .Map(t =>
            {
                return(Tuple.Create(4, (Expression)null, t.Item1, (StatementCollection)null, t.Item2));
            });


            p_linePragma.Content
                = ParsingRuleContainer <LinePragma> .Custom(lexer =>
            {
                var t = lexer.Peek();
                if (t != null)
                {
                    return(Tuple.Create(true, t.LinePragma));
                }
                else
                {
                    return(Tuple.Create(false, (LinePragma)null));
                }
            });

            p_member.Content
                = p_linePragma
                  .Concat(mem_modifier, (t, m) => Tuple.Create(t, m))
                  .Concat(
                      mem_constructor.Map((t) => Tuple.Create((Token)null, t))
                      | lex_identifer.GetParsingRule()
                      .Concat(mem_method | mem_property | mem_field,
                              (t, m) => Tuple.Create(t, m))
                      | mem_indexer.Map(t => Tuple.Create((Token)null, t)),
                      (t, m) =>
            {
                var lp     = t.Item1;
                var mod    = t.Item2;
                var type   = m.Item2.Item1;
                var id     = m.Item1;
                var exp    = m.Item2.Item2;
                var para   = m.Item2.Item3;
                var stat   = m.Item2.Item4;
                var getset = m.Item2.Item5;
                if (type == 0)
                {
                    return((Member) new Field(lp, mod.Item1, mod.Item2, id.Text, exp));
                }
                else if (type == 1)
                {
                    return((Member) new Method(lp, mod.Item1, mod.Item2, id.Text, para, stat));
                }
                else if (type == 2)
                {
                    return((Member) new Constructor(lp, mod.Item1, mod.Item2, para, stat));
                }
                else if (type == 3)
                {
                    var g = getset.Item1;
                    var s = getset.Item2;
                    return((Member) new Property(lp, mod.Item1, mod.Item2, id.Text, g, s));
                }
                else if (type == 4)
                {
                    var g = getset.Item1;
                    var s = getset.Item2;
                    return((Member) new Indexer(lp, mod.Item1, mod.Item2, para, g, s));
                }
                else
                {
                    throw new Exception();
                }
            });

            var member_semicolon
                = PM.Custom(lex =>
            {
                Member m;
                if (p_member.TryParse(lex, out m))
                {
                    if (m is Field)
                    {
                        var t = lex.Peek();
                        if (t == null)
                        {
                            return(Tuple.Create(true, m));
                        }
                        else if (t.Lexeme == lex_op_semicolon)
                        {
                            lex.Read();
                            return(Tuple.Create(true, m));
                        }
                        else if (t.Lexeme == lex_op_rightBrace)
                        {
                            return(Tuple.Create(true, m));
                        }
                        else if (t.LinePragma.Line > m.LinePragma.Line)
                        {
                            return(Tuple.Create(true, m));
                        }
                        else
                        {
                            Util.Fail <Member>(string.Format(ExceptionResource.Expected, ";")).TryParse(lex, out m);
                        }
                    }
                    else
                    {
                        return(Tuple.Create(true, m));
                    }
                }
                return(Tuple.Create(false, (Member)null));
            });

            p_members.Content
                = member_semicolon.Repeat(i => new MemberCollection(i));
        }