Пример #1
0
        public void ExitRule(ExprAST argument)
        {
            string ruleName = this.descentStack.Pop();

            this.ascentStack.Push(new ASTContext(IParserListenerType.GetMethod("Exit" + ruleName), this.listener, argument));
            this.ascentStack.Push(new ASTContext(IParserListenerType.GetMethod("Enter" + ruleName), this.listener, argument));
        }
Пример #2
0
        private ExprAST ParseBinary(ExprAST lhs)
        {
            var token      = Advance();
            var precedence = _binaryOperatorPrecedence[token.Type];
            var rhs        = Expression(precedence);

            return(new BinaryExprAST(token.Type, lhs, rhs));
        }
Пример #3
0
        // expression
        //   ::= primary binoprhs
        //
        private ExprAST ParseExpression()
        {
            ExprAST lhs = this.ParsePrimary();

            if (lhs == null)
            {
                return(null);
            }

            return(this.ParseBinOpRHS(0, lhs));
        }
Пример #4
0
        /// toplevelexpr ::= expression
        private FunctionAST ParseTopLevelExpr()
        {
            ExprAST e = this.ParseExpression();

            if (e == null)
            {
                return(null);
            }

            // Make an anonymous proto.
            PrototypeAST proto = new PrototypeAST(string.Empty, new List <string>());

            return(new FunctionAST(proto, e));
        }
Пример #5
0
        // identifierexpr
        //   ::= identifier
        //   ::= identifier '(' expression* ')'
        private ExprAST ParseIdentifierExpr()
        {
            string idName = this.scanner.GetLastIdentifier();

            this.scanner.GetNextToken();          // eat identifier.

            if (this.scanner.CurrentToken != '(') // Simple variable ref.
            {
                return(new VariableExprAST(idName));
            }

            // Call.
            this.scanner.GetNextToken();  // eat (
            List <ExprAST> args = new List <ExprAST>();

            if (this.scanner.CurrentToken != ')')
            {
                while (true)
                {
                    ExprAST arg = this.ParseExpression();
                    if (arg == null)
                    {
                        return(null);
                    }

                    args.Add(arg);

                    if (this.scanner.CurrentToken == ')')
                    {
                        break;
                    }

                    if (this.scanner.CurrentToken != ',')
                    {
                        Console.WriteLine("Expected ')' or ',' in argument list");
                        return(null);
                    }

                    this.scanner.GetNextToken();
                }
            }

            // Eat the ')'.
            this.scanner.GetNextToken();

            return(new CallExprAST(idName, args));
        }
Пример #6
0
        // definition ::= 'def' prototype expression
        private FunctionAST ParseDefinition()
        {
            this.scanner.GetNextToken(); // eat def.
            PrototypeAST proto = this.ParsePrototype();

            if (proto == null)
            {
                return(null);
            }

            ExprAST body = this.ParseExpression();

            if (body == null)
            {
                return(null);
            }

            return(new FunctionAST(proto, body));
        }
Пример #7
0
        // ifexpr ::= 'if' expression 'then' expression 'else' expression
        public ExprAST ParseIfExpr()
        {
            this.scanner.GetNextToken(); // eat the if.

            // condition
            ExprAST cond = this.ParseExpression();

            if (cond == null)
            {
                return(null);
            }

            if (this.scanner.CurrentToken != (int)Token.THEN)
            {
                Console.WriteLine("expected then");
            }

            this.scanner.GetNextToken(); // eat the then

            ExprAST then = this.ParseExpression();

            if (then == null)
            {
                return(null);
            }

            if (this.scanner.CurrentToken != (int)Token.ELSE)
            {
                Console.WriteLine("expected else");
                return(null);
            }

            this.scanner.GetNextToken();

            ExprAST @else = this.ParseExpression();

            if (@else == null)
            {
                return(null);
            }

            return(new IfExpAST(cond, then, @else));
        }
Пример #8
0
        // parenexpr ::= '(' expression ')'
        private ExprAST ParseParenExpr()
        {
            this.scanner.GetNextToken();  // eat (.
            ExprAST v = this.ParseExpression();

            if (v == null)
            {
                return(null);
            }

            if (this.scanner.CurrentToken != ')')
            {
                Console.WriteLine("expected ')'");
                return(null);
            }

            this.scanner.GetNextToken(); // eat ).

            return(v);
        }
Пример #9
0
        // binoprhs
        //   ::= ('+' primary)*
        private ExprAST ParseBinOpRHS(int exprPrec, ExprAST lhs)
        {
            // If this is a binop, find its precedence.
            while (true)
            {
                int tokPrec = this.scanner.GetTokPrecedence();

                // If this is a binop that binds at least as tightly as the current binop,
                // consume it, otherwise we are done.
                if (tokPrec < exprPrec)
                {
                    return(lhs);
                }

                // Okay, we know this is a binop.
                int binOp = this.scanner.CurrentToken;
                this.scanner.GetNextToken();  // eat binop

                // Parse the primary expression after the binary operator.
                ExprAST rhs = this.ParsePrimary();
                if (rhs == null)
                {
                    return(null);
                }

                // If BinOp binds less tightly with RHS than the operator after RHS, let
                // the pending operator take RHS as its LHS.
                int nextPrec = this.scanner.GetTokPrecedence();
                if (tokPrec < nextPrec)
                {
                    rhs = this.ParseBinOpRHS(tokPrec + 1, rhs);
                    if (rhs == null)
                    {
                        return(null);
                    }
                }

                // Merge LHS/RHS.
                lhs = new BinaryExprAST((char)binOp, lhs, rhs);
            }
        }
Пример #10
0
        private ExprAST For()
        {
            var id = Identifier();

            Consume(EQUAL, "Expect '=' after identifier");
            var start = Expression();

            Consume(COMMA, "Expect ',' after initial value");
            var     end  = Expression();
            ExprAST step = null;

            if (Check(COMMA))
            {
                Consume(COMMA, "");
                step = Expression();
            }

            Consume(IN, "Expect 'in' after for definition");
            var body = Expression();

            return(new ForExprAST(id, start, end, step, body));
        }
Пример #11
0
 public BinaryExprAST(char @operator, ExprAST left, ExprAST right)
 {
     Operator = @operator;
     Left     = left ?? throw new ArgumentNullException(nameof(left));
     Right    = right ?? throw new ArgumentNullException(nameof(right));
 }
Пример #12
0
 public FunctionAST(PrototypeAST protptype, ExprAST body)
 {
     Protptype = protptype ?? throw new ArgumentNullException(nameof(protptype));
     Body      = body ?? throw new ArgumentNullException(nameof(body));
 }
Пример #13
0
 public ASTContext(MethodInfo methodInfo, object instance, ExprAST argument)
 {
     this.MethodInfo = methodInfo;
     this.Instance   = instance;
     this.Argument   = argument;
 }
Пример #14
0
        // forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
        public ExprAST ParseForExpr()
        {
            this.scanner.GetNextToken(); // eat the for.

            if (this.scanner.CurrentToken != (int)Token.IDENTIFIER)
            {
                Console.WriteLine("expected identifier after for");
                return(null);
            }

            string idName = this.scanner.GetLastIdentifier();

            this.scanner.GetNextToken(); // eat identifier.

            if (this.scanner.CurrentToken != '=')
            {
                Console.WriteLine("expected '=' after for");
                return(null);
            }

            this.scanner.GetNextToken(); // eat '='.

            ExprAST start = this.ParseExpression();

            if (start == null)
            {
                return(null);
            }

            if (this.scanner.CurrentToken != ',')
            {
                Console.WriteLine("expected ',' after for start value");
                return(null);
            }

            this.scanner.GetNextToken();

            ExprAST end = this.ParseExpression();

            if (end == null)
            {
                return(null);
            }

            // The step value is optional;
            ExprAST step = null;

            if (this.scanner.CurrentToken == ',')
            {
                this.scanner.GetNextToken();
                step = this.ParseExpression();
                if (step == null)
                {
                    return(null);
                }
            }

            if (this.scanner.CurrentToken != (int)Token.IN)
            {
                Console.WriteLine("expected 'in' after for");
                return(null);
            }

            this.scanner.GetNextToken();
            ExprAST body = this.ParseExpression();

            if (body == null)
            {
                return(null);
            }

            return(new ForExprAST(idName, start, end, step, body));
        }