Beispiel #1
0
 public BinOpParser(string name, Parser parser, BinOpParser descender)
 {
     this.name      = name;
     this.parser    = parser;
     this.descender = descender.Descend;
 }
Beispiel #2
0
        public Parser(Tokenizer tokenizer)
        {
            if (tokenizer == null)
            {
                throw new ArgumentNullException(nameof(tokenizer));
            }

            this.tokenizer = tokenizer;

            trace = new Trace(this, Console.Error);

            // Factor
            // ^-- Primary
            //     ^-- Unary
            //         ^-- Multiplicitive
            //             ^-- Additive
            //                 ^-- ... etc BinOpParsers below ...
            //                     ^ Assign

            var multiplicitive = new BinOpParser("Multiplicive", this, Unary)
            {
                new BinOpParserEntry(TokenType.Multiply),
                new BinOpParserEntry(TokenType.Divide),
                new BinOpParserEntry(TokenType.Modulo)
            };

            var additive = new BinOpParser("Additive", this, multiplicitive)
            {
                new BinOpParserEntry(TokenType.Add),
                new BinOpParserEntry(TokenType.Subtract),
            };

            var shift = new BinOpParser("Shift", this, additive)
            {
                new BinOpParserEntry(TokenType.LeftShift),
                new BinOpParserEntry(TokenType.RightShift)
            };

            var relational = new BinOpParser("Relational", this, shift)
            {
                new BinOpParserEntry(TokenType.LessThan),
                new BinOpParserEntry(TokenType.GreaterThan),
                new BinOpParserEntry(TokenType.LessThanOrEqual),
                new BinOpParserEntry(TokenType.GreaterThanOrEqual),
                // is, as, in
            };

            var equality = new BinOpParser("Equality", this, relational)
            {
                new BinOpParserEntry(TokenType.Equal),
                new BinOpParserEntry(TokenType.NotEqual)
            };

            var logicalAnd = new BinOpParser("LogicalAnd", this, equality)
            {
                new BinOpParserEntry(TokenType.And)
            };

            var logicalExclusiveOr = new BinOpParser("LogicalExclusiveOr", this, logicalAnd)
            {
                new BinOpParserEntry(TokenType.ExclusiveOr)
            };

            var logicalOr = new BinOpParser("LogicalOr", this, logicalExclusiveOr)
            {
                new BinOpParserEntry(TokenType.Or)
            };

            var andAlso = new BinOpParser("ConditionalAnd", this, logicalOr)
            {
                new BinOpParserEntry(TokenType.AndAlso)
            };

            var orElse = new BinOpParser("ConditionalOr", this, andAlso)
            {
                new BinOpParserEntry(TokenType.OrElse)
            };

            Func <Expression> conditional = () => {
                try {
                    trace.Enter("Conditional");
                    var expr = orElse.Descend();
                    if (current.Type == TokenType.QuestionMark)
                    {
                        Read();
                        var trueExpr = Expr();
                        Match(TokenType.Colon);
                        expr = new ConditionalExpression(
                            expr, trueExpr, Expr());
                    }
                    return(expr);
                } finally {
                    trace.Leave();
                }
            };

            var assign = new BinOpParser("Assign", this, conditional)
            {
                new BinOpParserEntry(TokenType.Assign),
                new BinOpParserEntry(TokenType.MultiplyAssign),
                new BinOpParserEntry(TokenType.DivideAssign),
                new BinOpParserEntry(TokenType.ModuloAssign),
                new BinOpParserEntry(TokenType.AddAssign),
                new BinOpParserEntry(TokenType.SubtractAssign),
                new BinOpParserEntry(TokenType.LeftShiftAssign),
                new BinOpParserEntry(TokenType.RightShiftAssign),
                new BinOpParserEntry(TokenType.AndAssign),
                new BinOpParserEntry(TokenType.ExclusiveOrAssign),
                new BinOpParserEntry(TokenType.OrAssign),
            };

            lowestPrecedenceOpParser = assign.Descend;
        }
Beispiel #3
0
        public Parser()
        {
            // Factor
            // ^-- Primary
            //     ^-- Unary

            Multiplicitive = new BinOpParser("Multiplicive", this, Unary)
            {
                new BinOpParserEntry(TokenType.Multiply, Expression.Multiply),
                new BinOpParserEntry(TokenType.Divide, Expression.Divide),
                new BinOpParserEntry(TokenType.Modulo, Expression.Modulo)
            };

            Additive = new BinOpParser("Additive", this, Multiplicitive)
            {
                new BinOpParserEntry(TokenType.Add, Expression.Add(l, r)),
                new BinOpParserEntry(TokenType.Subtract, Expression.Subtract),
            };

            Shift = new BinOpParser("Shift", this, Additive)
            {
                new BinOpParserEntry(TokenType.LeftShift, Expression.LeftShift),
                new BinOpParserEntry(TokenType.RightShift, Expression.RightShift)
            };

            Relational = new BinOpParser("Relational", this, Shift)
            {
                new BinOpParserEntry(TokenType.LessThan, Expression.LessThan),
                new BinOpParserEntry(TokenType.GreaterThan, Expression.GreaterThan),
                new BinOpParserEntry(TokenType.LessThanOrEqual, Expression.LessThanOrEqual),
                new BinOpParserEntry(TokenType.GreaterThanOrEqual, Expression.GreaterThanOrEqual),
                new BinOpParserEntry(TokenType.Is,
                                     (l, r) => Expression.TypeIs(l, (Type)((ConstantExpression)r).Value)),
                new BinOpParserEntry(TokenType.As,
                                     (l, r) => Expression.TypeAs(l, (Type)((ConstantExpression)r).Value)),
                new BinOpParserEntry(TokenType.In,
                                     (l, r) => Expression.Call(enumerable_Contains.MakeGenericMethod(l.Type), r, l))
            };

            Equality = new BinOpParser("Equality", this, Relational)
            {
                new BinOpParserEntry(TokenType.Equal, Expression.Equal),
                new BinOpParserEntry(TokenType.NotEqual, Expression.NotEqual)
            };

            LogicalAnd = new BinOpParser("LogicalAnd", this, Equality)
            {
                new BinOpParserEntry(TokenType.And, Expression.And)
            };

            LogicalExclusiveOr = new BinOpParser("LogicalExclusiveOr", this, LogicalAnd)
            {
                new BinOpParserEntry(TokenType.ExclusiveOr, Expression.ExclusiveOr)
            };

            LogicalOr = new BinOpParser("LogicalOr", this, LogicalExclusiveOr)
            {
                new BinOpParserEntry(TokenType.Or, Expression.Or)
            };

            AndAlso = new BinOpParser("ConditionalAnd", this, LogicalOr)
            {
                new BinOpParserEntry(TokenType.AndAlso, Expression.AndAlso)
            };

            OrElse = new BinOpParser("ConditionalOr", this, AndAlso)
            {
                new BinOpParserEntry(TokenType.OrElse, Expression.OrElse)
            };

            Func <Expression> conditional = () => {
                try {
                    var expr = OrElse.Descend();
                    if (current.Type == TokenType.QuestionMark)
                    {
                        Read();
                        var trueExpr = Expr();
                        Match(TokenType.Colon);
                        expr = Expression.Condition(expr, trueExpr, Expr());
                    }
                    return(expr);
                } finally {
                    trace.Leave();
                }
            };

            var assign = new BinOpParser("Assign", this, conditional)
            {
                new BinOpParserEntry(TokenType.Assign, Expression.Assign),
                new BinOpParserEntry(TokenType.MultiplyAssign, Expression.MultiplyAssign),
                new BinOpParserEntry(TokenType.DivideAssign, Expression.DivideAssign),
                new BinOpParserEntry(TokenType.ModuloAssign, Expression.ModuloAssign),
                new BinOpParserEntry(TokenType.AddAssign, Expression.AddAssign),
                new BinOpParserEntry(TokenType.SubtractAssign, Expression.SubtractAssign),
                new BinOpParserEntry(TokenType.LeftShiftAssign, Expression.LeftShiftAssign),
                new BinOpParserEntry(TokenType.RightShiftAssign, Expression.RightShiftAssign),
                new BinOpParserEntry(TokenType.AndAssign, Expression.AndAssign),
                new BinOpParserEntry(TokenType.ExclusiveOrAssign, Expression.ExclusiveOrAssign),
                new BinOpParserEntry(TokenType.OrAssign, Expression.OrAssign),
            };

            lowestPrecedenceOpParser = assign.Descend;
        }