示例#1
0
文件: Parser.cs 项目: donreamey/vmeex
        /// <summary>
        /// Parses the statements in the function body
        /// recursively and calls other statemetents as needed
        /// </summary>
        private void ParseStatementExpression()
        {
            Token t = _scanner.GetToken();

            var identfiers = new Stack<Expr>();
            var operators = new Stack<Expr>();
            var functionParameters = new Stack<Expr>();

            bool foundLeftParen = false;
            bool functionHasParameters = false;

            while (!t.IdentiferName.Equals(constants.SEMICOLON))
            {
                if (t.isOperator)
                {
                    if (t.IdentiferName.Equals(constants.LPAREN))
                    {
                        foundLeftParen = true;
                    }

                    if (operators.Count > 0)
                    {
                        OperatorPrecedenceTable.ShiftReduceEval sre = OperatorPrecedenceTable.IdOperation.Validate(operators.Peek().GetToken(), t);

                        switch (sre)
                        {
                            case OperatorPrecedenceTable.ShiftReduceEval.Shift:
                                {
                                    if (t.IdentiferName.Equals(constants.RPAREN))
                                    {
                                        foundLeftParen = false;
                                        functionHasParameters = false;

                                        var parameterList = new List<Expr>();

                                        while (functionParameters.Count > 0)
                                        {
                                            parameterList.Add(functionParameters.Pop());
                                        }

                                        if (operators.Peek().GetToken().IdentiferName.Equals(constants.LPAREN))
                                        {
                                            operators.Pop();
                                        }
                                        else
                                        {
                                            throw new NireExecutionException("mismatched parens");
                                        }

                                        var funcCall = new FunctionCallExpression(identfiers.Pop().GetToken(), parameterList);
                                        identfiers.Push(funcCall);

                                        break;
                                    }
                                    operators.Push(new OperatorExpression(t));
                                    break;
                                }
                            case OperatorPrecedenceTable.ShiftReduceEval.Reduce:
                                {
                                    Expr operation = operators.Pop();
                                    var oe = new OperatorExpression(operation.GetToken());

                                    if (identfiers.Count < 2)
                                    {
                                        throw new NireException();
                                    }

                                    Expr rvalue = identfiers.Pop();
                                    Expr lvalue = identfiers.Pop();

                                    switch (operation.GetToken().Kind)
                                    {
                                        case ByteCodeIdentifiers.TokenCode.Equal:
                                            {

                                                var ae = new AssignmentExpr(oe, lvalue, rvalue);
                                                if (ae.IsValidBinaryExpression())
                                                {
                                                    identfiers.Push(ae);
                                                }
                                                break;
                                            }
                                        case ByteCodeIdentifiers.TokenCode.Multiply:
                                        case ByteCodeIdentifiers.TokenCode.Divide:
                                        case ByteCodeIdentifiers.TokenCode.EqualEqual:
                                        case ByteCodeIdentifiers.TokenCode.Plus:
                                        case ByteCodeIdentifiers.TokenCode.Minus:
                                            {
                                                var boe = new ArithmeticBinaryExpr(oe, lvalue, rvalue);
                                                if (boe.IsValidBinaryExpression())
                                                {
                                                    identfiers.Push(boe);
                                                }
                                                break;
                                            }
                                    }

                                    if (t.Kind != ByteCodeIdentifiers.TokenCode.SemiColon &&
                                        t.Kind != ByteCodeIdentifiers.TokenCode.LParen &&
                                        t.Kind != ByteCodeIdentifiers.TokenCode.RParen)
                                    {
                                        operators.Push(new OperatorExpression(t));
                                    }
                                    break;
                                }
                        }
                    }
                    else
                    {
                        if (t.Kind != ByteCodeIdentifiers.TokenCode.RParen)
                        {
                            operators.Push(new OperatorExpression(t));
                        }
                    }
                }
                else
                {
                    if (foundLeftParen)
                    {
                        functionHasParameters = true;
                    }

                    if (functionHasParameters)
                    {
                        if (!t.Value.Equals(constants.COMMA))
                        {
                            var ie = new IdentifierExpression(t);
                            var symbolTable = SymbolTable.CreateInstance();

                            if (!symbolTable.IsTokenDefinedInScope(_expressionScopeStack.Peek(), ie))
                            {
                                functionParameters.Push(new IdentifierExpression(t));
                            }
                        }
                    }
                    else
                    {
                        identfiers.Push(DetermineNextToken(t));
                    }
                }

                t = _scanner.GetToken();
            }

            ConstructAst(operators, identfiers);
        }
示例#2
0
 internal AssignmentExpr(OperatorExpression operation,
     Expr left,
     Expr right)
     : base(operation, left, right)
 {
 }
示例#3
0
 internal BinaryOperatorExpression(
     OperatorExpression operation,
     Expr left,
     Expr right)
     : this()
 {
     this.left = left;
     this.right = right;
     this.operation = operation;
 }
示例#4
0
 internal ArithmeticBinaryExpr(OperatorExpression operation,
     Expr left,
     Expr right)
     : base(operation, left, right)
 {
 }
示例#5
0
 internal BinaryOperatorExpression(OperatorExpression operation)
     : base()
 {
     this.operation = operation;
 }