Parse() public method

public Parse ( ParseContext context, IAstNode parent ) : bool
context Microsoft.R.Core.Parser.ParseContext
parent IAstNode
return bool
Esempio n. 1
0
        public override bool Parse(ParseContext context, IAstNode parent) {
            TokenStream<RToken> tokens = context.Tokens;

            Debug.Assert(context.Tokens.CurrentToken.TokenType == RTokenType.Identifier || 
                         context.Tokens.CurrentToken.TokenType == RTokenType.String);

            this.Identifier = RParser.ParseToken(context, this);
            this.EqualsSign = RParser.ParseToken(context, this);

            if (context.Tokens.CurrentToken.TokenType != RTokenType.Comma && context.Tokens.CurrentToken.TokenType != RTokenType.CloseBrace) {
                Expression exp = new Expression(inGroup: true);
                if (exp.Parse(context, this)) {
                    this.DefaultValue = exp;
                }
            } else {
                this.DefaultValue = new NullExpression();
                if (context.Tokens.IsEndOfStream()) {
                    context.AddError(new ParseError(ParseErrorType.ExpressionExpected, ErrorLocation.Token, context.Tokens.CurrentToken));
                } else {
                    context.AddError(new ParseError(ParseErrorType.ExpressionExpected, ErrorLocation.Token, EqualsSign));
                }
            }

            return base.Parse(context, parent);
        }
Esempio n. 2
0
        private ParseErrorType HandleOperator(ParseContext context, out OperationType operationType)
        {
            var currentOperator = new TokenOperator(firstInExpression: _operands.Count == 0);

            currentOperator.Parse(context, null);
            var isUnary = currentOperator.IsUnary;

            operationType = isUnary ? OperationType.UnaryOperator : OperationType.BinaryOperator;

            if (currentOperator.OperatorType == OperatorType.Not)
            {
                //This comes from the fact that
                //  x < -1
                //  y < -1
                //  2 + !x + y
                // yields 2 (i.e. bang applies to the entire expression that follows
                isUnary = true;
                if (!IsInGroup && context.Tokens.IsLineBreakAfter(context.TextProvider, context.Tokens.Position - 1))
                {
                    // Make sure expression that follows is not empty
                    return(ParseErrorType.RightOperandExpected);
                }

                var exp = new Expression(IsInGroup);
                if (!exp.Parse(context, null))
                {
                    return(ParseErrorType.RightOperandExpected);
                }

                _operators.Push(currentOperator);
                _operands.Push(exp);
                operationType = OperationType.Operand;
                return(ParseErrorType.None);
            }
            return(HandleOperatorPrecedence(context, currentOperator));
        }
Esempio n. 3
0
        private ParseErrorType HandleOperator(ParseContext context, IAstNode parent, out bool isUnary) {
            ParseErrorType errorType = ParseErrorType.None;

            // If operands stack is empty the operator is unary.
            // If operator is preceded by another operator, 
            // it is interpreted as unary.

            TokenOperator currentOperator = new TokenOperator(_operands.Count == 0);

            currentOperator.Parse(context, null);
            isUnary = currentOperator.IsUnary;

            IOperator lastOperator = _operators.Peek();
            if (isUnary && lastOperator != null && lastOperator.IsUnary) {
                // !!!x is treated as !(!(!x)))
                // Step back and re-parse as expression
                context.Tokens.Position -= 1;
                var exp = new Expression(inGroup: false);
                if (exp.Parse(context, null)) {
                    _operands.Push(exp);
                    return ParseErrorType.None;
                }
            }

            if (currentOperator.Precedence <= lastOperator.Precedence &&
                !(currentOperator.OperatorType == lastOperator.OperatorType && currentOperator.Association == Association.Right)) {
                // New operator has lower or equal precedence. We need to make a tree from
                // the topmost operator and its operand(s). Example: a*b+c. + has lower priority
                // and a and b should be on the stack along with * on the operator stack.
                // Repeat until there are no more higher precendece operators on the stack.

                errorType = this.ProcessHigherPrecendenceOperators(context, currentOperator);
            }

            if (errorType == ParseErrorType.None) {
                _operators.Push(currentOperator);
            }

            return errorType;
        }