System.Data.ExpressionParser.BuildExpression C# (CSharp) Method

BuildExpression() private method

Builds expression tree for higher-precedence operator to be used as left operand of current operator. May cause errors - always do ErrorCheck() upin return.
private BuildExpression ( int pri ) : void
pri int
return void
        private void BuildExpression(int pri)
        {
            ExpressionNode expr = null;

            Debug.Assert(pri > Operators.priStart && pri <= Operators.priMax, "Invalid priority value");

            /* For all operators of higher or same precedence (we are always
            left-associative) */
            while (true)
            {
                Debug.Assert(_topOperator > 0, "Empty operator stack!!");
                OperatorInfo opInfo = _ops[_topOperator - 1];

                if (opInfo._priority < pri)
                    goto end_loop;

                Debug.Assert(opInfo._priority >= pri, "Invalid prioriry value");
                _topOperator--;

                ExpressionNode nodeLeft;
                ExpressionNode nodeRight;
                switch (opInfo._type)
                {
                    case Nodes.Binop:
                        {
                            // get right, left operands. Bind them.

                            nodeRight = NodePop();
                            nodeLeft = NodePop();

                            /* This is the place to do type and other checks */

                            switch (opInfo._op)
                            {
                                case Operators.Between:
                                case Operators.BetweenAnd:
                                case Operators.BitwiseAnd:
                                case Operators.BitwiseOr:
                                case Operators.BitwiseXor:
                                case Operators.BitwiseNot:
                                    throw ExprException.UnsupportedOperator(opInfo._op);

                                case Operators.Is:
                                case Operators.Or:
                                case Operators.And:
                                case Operators.EqualTo:
                                case Operators.NotEqual:
                                case Operators.Like:
                                case Operators.LessThen:
                                case Operators.LessOrEqual:
                                case Operators.GreaterThen:
                                case Operators.GreaterOrEqual:
                                case Operators.In:
                                    break;

                                default:
                                    Debug.Assert(opInfo._op == Operators.Plus ||
                                                 opInfo._op == Operators.Minus ||
                                                 opInfo._op == Operators.Multiply ||
                                                 opInfo._op == Operators.Divide ||
                                                 opInfo._op == Operators.Modulo,
                                                 "Invalud Binary operation");

                                    break;
                            }
                            Debug.Assert(nodeLeft != null, "Invalid left operand");
                            Debug.Assert(nodeRight != null, "Invalid right operand");

                            if (opInfo._op == Operators.Like)
                            {
                                expr = new LikeNode(_table, opInfo._op, nodeLeft, nodeRight);
                            }
                            else
                            {
                                expr = new BinaryNode(_table, opInfo._op, nodeLeft, nodeRight);
                            }

                            break;
                        }
                    case Nodes.Unop:
                        /* Unary operator: Pop and bind right op. */
                        nodeLeft = null;
                        nodeRight = NodePop();

                        /* Check for special cases */
                        switch (opInfo._op)
                        {
                            case Operators.Not:
                                break;

                            case Operators.BitwiseNot:
                                throw ExprException.UnsupportedOperator(opInfo._op);

                            case Operators.Negative:
                                break;
                        }

                        Debug.Assert(nodeLeft == null, "Invalid left operand");
                        Debug.Assert(nodeRight != null, "Invalid right operand");

                        expr = new UnaryNode(_table, opInfo._op, nodeRight);
                        break;

                    case Nodes.Zop:
                        /* Intrinsic constant: just create node. */
                        expr = new ZeroOpNode(opInfo._op);
                        break;

                    default:
                        Debug.Assert(false, "Unhandled operator type");
                        goto end_loop;
                }
                Debug.Assert(expr != null, "Failed to create expression");

                NodePush(expr);
                // countinue while loop;
            }
        end_loop:
            ;
        }