コード例 #1
0
            void CompileRelational(XPathRelationExpr expr)
            {
                // Are we comparing two literals?
                if (expr.Left.IsLiteral && expr.Right.IsLiteral)
                {
                    // Do the comparison at compile time
                    this.CompileLiteralRelation(expr);
                    return;
                }

                // != is not optimized in M5
                if (expr.Op != RelationOperator.Ne)
                {
                    // Number relations are handled in a special way
                    if (XPathExprType.Number == expr.Left.Type || XPathExprType.Number == expr.Right.Type)
                    {
                        this.CompileNumberRelation(expr);
                        return;
                    }

                    // Equality tests with string literals are handled in a special way
                    if (expr.Op == RelationOperator.Eq && (XPathExprType.String == expr.Left.Type || XPathExprType.String == expr.Right.Type))
                    {
                        this.CompileStringLiteralEquality(expr);
                        return;
                    }
                }

                // Can't optimize. Use a general purpose relation opcode
                this.CompileExpression(expr.Left);
                this.CompileExpression(expr.Right);
                this.codeBlock.Append(new RelationOpcode(expr.Op));
            }
コード例 #2
0
 private void CompileRelational(XPathRelationExpr expr)
 {
     if (expr.Left.IsLiteral && expr.Right.IsLiteral)
     {
         this.CompileLiteralRelation(expr);
     }
     else
     {
         if (expr.Op != RelationOperator.Ne)
         {
             if ((XPathExprType.Number == expr.Left.Type) || (XPathExprType.Number == expr.Right.Type))
             {
                 this.CompileNumberRelation(expr);
                 return;
             }
             if ((expr.Op == RelationOperator.Eq) && ((XPathExprType.String == expr.Left.Type) || (XPathExprType.String == expr.Right.Type)))
             {
                 this.CompileStringLiteralEquality(expr);
                 return;
             }
         }
         this.CompileExpression(expr.Left);
         this.CompileExpression(expr.Right);
         this.codeBlock.Append(new RelationOpcode(expr.Op));
     }
 }
コード例 #3
0
            void CompileNumberRelation(XPathRelationExpr expr)
            {
                if (expr.Op == RelationOperator.Eq)
                {
                    this.CompileNumberLiteralEquality(expr);
                    return;
                }

                bool leftNumber  = (XPathExprType.Number == expr.Left.Type);
                bool rightNumber = (XPathExprType.Number == expr.Right.Type);

                Fx.Assert(leftNumber || rightNumber, "");
                Fx.Assert(!(leftNumber && rightNumber), "");

                this.CompileExpression(leftNumber ? expr.Right : expr.Left);
                XPathNumberExpr litExpr = leftNumber ? (XPathNumberExpr)expr.Left : (XPathNumberExpr)expr.Right;
                double          literal = litExpr.Number;

                if (litExpr.Negate)
                {
                    litExpr.Negate = false;
                    literal        = -literal;
                }

                // To maximize code branch commonality, we canonacalize the relation expressions so that the non-literal
                // is always to the left and the literal to the right. If this makes us swap expressions, we must also flip
                // relation operators appropriately.
                if (leftNumber)
                {
                    // Flip operators
                    switch (expr.Op)
                    {
                    case RelationOperator.Gt:
                        expr.Op = RelationOperator.Lt;
                        break;

                    case RelationOperator.Ge:
                        expr.Op = RelationOperator.Le;
                        break;

                    case RelationOperator.Lt:
                        expr.Op = RelationOperator.Gt;
                        break;

                    case RelationOperator.Le:
                        expr.Op = RelationOperator.Ge;
                        break;
                    }
                }

                if (0 != (this.compiler.flags & QueryCompilerFlags.InverseQuery))
                {
                    this.codeBlock.Append(new NumberIntervalOpcode(literal, expr.Op));
                }
                else
                {
                    this.codeBlock.Append(new NumberRelationOpcode(literal, expr.Op));
                }
            }
コード例 #4
0
            private void CompileLiteralRelation(XPathRelationExpr expr)
            {
                XPathLiteralExpr left    = (XPathLiteralExpr)expr.Left;
                XPathLiteralExpr right   = (XPathLiteralExpr)expr.Right;
                bool             literal = QueryValueModel.CompileTimeCompare(left.Literal, right.Literal, expr.Op);

                this.codeBlock.Append(new PushBooleanOpcode(literal));
            }
コード例 #5
0
            private void CompileStringLiteralEquality(XPathRelationExpr expr)
            {
                bool          flag = XPathExprType.String == expr.Left.Type;
                XPathExprType type = expr.Right.Type;

                this.CompileExpression(flag ? expr.Right : expr.Left);
                string literal = flag ? ((XPathStringExpr)expr.Left).String : ((XPathStringExpr)expr.Right).String;

                this.codeBlock.Append(new StringEqualsOpcode(literal));
            }
コード例 #6
0
ファイル: XPathParser.cs プロジェクト: dox0/DotNet471RS3
        XPathExpr ParseRelationalExpression()
        {
            XPathExpr leftExpr = this.ParseAdditiveExpression();

            if (null != leftExpr)
            {
                RelationOperator op;

                do
                {
                    op = RelationOperator.None;

                    XPathToken token = this.NextToken();

                    if (null != token)
                    {
                        switch (token.TokenID)
                        {
                        default:
                            this.PushToken(token);
                            break;

                        case XPathTokenID.Lt:
                            op = RelationOperator.Lt;
                            break;

                        case XPathTokenID.Lte:
                            op = RelationOperator.Le;
                            break;

                        case XPathTokenID.Gt:
                            op = RelationOperator.Gt;
                            break;

                        case XPathTokenID.Gte:
                            op = RelationOperator.Ge;
                            break;
                        }
                        if (RelationOperator.None != op)
                        {
                            XPathExpr rightExpr = this.ParseAdditiveExpression();

                            if (null == rightExpr)
                            {
                                this.ThrowError(QueryCompileError.InvalidExpression);
                            }

                            leftExpr = new XPathRelationExpr(op, leftExpr, rightExpr);
                        }
                    }
                } while (RelationOperator.None != op);
            }

            return(leftExpr);
        }
コード例 #7
0
            private void CompileNumberRelation(XPathRelationExpr expr)
            {
                if (expr.Op == RelationOperator.Eq)
                {
                    this.CompileNumberLiteralEquality(expr);
                }
                else
                {
                    bool          flag = XPathExprType.Number == expr.Left.Type;
                    XPathExprType type = expr.Right.Type;
                    this.CompileExpression(flag ? expr.Right : expr.Left);
                    XPathNumberExpr expr2  = flag ? ((XPathNumberExpr)expr.Left) : ((XPathNumberExpr)expr.Right);
                    double          number = expr2.Number;
                    if (expr2.Negate)
                    {
                        expr2.Negate = false;
                        number       = -number;
                    }
                    if (flag)
                    {
                        switch (expr.Op)
                        {
                        case RelationOperator.Gt:
                            expr.Op = RelationOperator.Lt;
                            break;

                        case RelationOperator.Ge:
                            expr.Op = RelationOperator.Le;
                            break;

                        case RelationOperator.Lt:
                            expr.Op = RelationOperator.Gt;
                            break;

                        case RelationOperator.Le:
                            expr.Op = RelationOperator.Ge;
                            break;
                        }
                    }
                    if ((this.compiler.flags & QueryCompilerFlags.InverseQuery) != QueryCompilerFlags.None)
                    {
                        this.codeBlock.Append(new NumberIntervalOpcode(number, expr.Op));
                    }
                    else
                    {
                        this.codeBlock.Append(new NumberRelationOpcode(number, expr.Op));
                    }
                }
            }
コード例 #8
0
        private XPathExpr ParseRelationalExpression()
        {
            XPathExpr left = this.ParseAdditiveExpression();

            if (left != null)
            {
                RelationOperator none;
                do
                {
                    none = RelationOperator.None;
                    XPathToken token = this.NextToken();
                    if (token != null)
                    {
                        switch (token.TokenID)
                        {
                        case XPathTokenID.Gt:
                            none = RelationOperator.Gt;
                            break;

                        case XPathTokenID.Gte:
                            none = RelationOperator.Ge;
                            break;

                        case XPathTokenID.Lt:
                            none = RelationOperator.Lt;
                            break;

                        case XPathTokenID.Lte:
                            none = RelationOperator.Le;
                            break;

                        default:
                            this.PushToken(token);
                            break;
                        }
                        if (none != RelationOperator.None)
                        {
                            XPathExpr right = this.ParseAdditiveExpression();
                            if (right == null)
                            {
                                this.ThrowError(QueryCompileError.InvalidExpression);
                            }
                            left = new XPathRelationExpr(none, left, right);
                        }
                    }
                }while (none != RelationOperator.None);
            }
            return(left);
        }
コード例 #9
0
            void CompileStringLiteralEquality(XPathRelationExpr expr)
            {
                Fx.Assert(expr.Op == RelationOperator.Eq, "");

                bool leftString  = (XPathExprType.String == expr.Left.Type);
                bool rightString = (XPathExprType.String == expr.Right.Type);

                Fx.Assert(leftString || rightString, "");
                Fx.Assert(!(leftString && rightString), "");

                this.CompileExpression(leftString ? expr.Right : expr.Left);
                string literal = leftString ? ((XPathStringExpr)expr.Left).String : ((XPathStringExpr)expr.Right).String;

                this.codeBlock.Append(new StringEqualsOpcode(literal));
            }
コード例 #10
0
            private void CompileNumberLiteralEquality(XPathRelationExpr expr)
            {
                bool          flag = XPathExprType.Number == expr.Left.Type;
                XPathExprType type = expr.Right.Type;

                this.CompileExpression(flag ? expr.Right : expr.Left);
                XPathNumberExpr expr2  = flag ? ((XPathNumberExpr)expr.Left) : ((XPathNumberExpr)expr.Right);
                double          number = expr2.Number;

                if (expr2.Negate)
                {
                    expr2.Negate = false;
                    number       = -number;
                }
                this.codeBlock.Append(new NumberEqualsOpcode(number));
            }
コード例 #11
0
            void CompileNumberLiteralEquality(XPathRelationExpr expr)
            {
                Fx.Assert(expr.Op == RelationOperator.Eq, "");

                bool leftNumber  = (XPathExprType.Number == expr.Left.Type);
                bool rightNumber = (XPathExprType.Number == expr.Right.Type);

                Fx.Assert(leftNumber || rightNumber, "");
                Fx.Assert(!(leftNumber && rightNumber), "");

                this.CompileExpression(leftNumber ? expr.Right : expr.Left);
                XPathNumberExpr litExpr = leftNumber ? (XPathNumberExpr)expr.Left : (XPathNumberExpr)expr.Right;
                double          literal = litExpr.Number;

                if (litExpr.Negate)
                {
                    litExpr.Negate = false;
                    literal        = -literal;
                }
                this.codeBlock.Append(new NumberEqualsOpcode(literal));
            }
コード例 #12
0
        private XPathExpr ParseRelationalExpression()
        {
            XPathExpr left = this.ParseAdditiveExpression();
            if (left != null)
            {
                RelationOperator none;
                do
                {
                    none = RelationOperator.None;
                    XPathToken token = this.NextToken();
                    if (token != null)
                    {
                        switch (token.TokenID)
                        {
                            case XPathTokenID.Gt:
                                none = RelationOperator.Gt;
                                break;

                            case XPathTokenID.Gte:
                                none = RelationOperator.Ge;
                                break;

                            case XPathTokenID.Lt:
                                none = RelationOperator.Lt;
                                break;

                            case XPathTokenID.Lte:
                                none = RelationOperator.Le;
                                break;

                            default:
                                this.PushToken(token);
                                break;
                        }
                        if (none != RelationOperator.None)
                        {
                            XPathExpr right = this.ParseAdditiveExpression();
                            if (right == null)
                            {
                                this.ThrowError(QueryCompileError.InvalidExpression);
                            }
                            left = new XPathRelationExpr(none, left, right);
                        }
                    }
                }
                while (none != RelationOperator.None);
            }
            return left;
        }
コード例 #13
0
            void CompileStringLiteralEquality(XPathRelationExpr expr)
            {
                Fx.Assert(expr.Op == RelationOperator.Eq, "");

                bool leftString = (XPathExprType.String == expr.Left.Type);
                bool rightString = (XPathExprType.String == expr.Right.Type);

                Fx.Assert(leftString || rightString, "");
                Fx.Assert(!(leftString && rightString), "");

                this.CompileExpression(leftString ? expr.Right : expr.Left);
                string literal = leftString ? ((XPathStringExpr)expr.Left).String : ((XPathStringExpr)expr.Right).String;
                this.codeBlock.Append(new StringEqualsOpcode(literal));
            }
コード例 #14
0
            void CompileRelational(XPathRelationExpr expr)
            {
                // Are we comparing two literals?
                if (expr.Left.IsLiteral && expr.Right.IsLiteral)
                {
                    // Do the comparison at compile time
                    this.CompileLiteralRelation(expr);
                    return;
                }

                // != is not optimized in M5
                if (expr.Op != RelationOperator.Ne)
                {
                    // Number relations are handled in a special way
                    if (XPathExprType.Number == expr.Left.Type || XPathExprType.Number == expr.Right.Type)
                    {
                        this.CompileNumberRelation(expr);
                        return;
                    }

                    // Equality tests with string literals are handled in a special way
                    if (expr.Op == RelationOperator.Eq && (XPathExprType.String == expr.Left.Type || XPathExprType.String == expr.Right.Type))
                    {
                        this.CompileStringLiteralEquality(expr);
                        return;
                    }
                }

                // Can't optimize. Use a general purpose relation opcode
                this.CompileExpression(expr.Left);
                this.CompileExpression(expr.Right);
                this.codeBlock.Append(new RelationOpcode(expr.Op));
            }
コード例 #15
0
            void CompileNumberRelation(XPathRelationExpr expr)
            {
                if (expr.Op == RelationOperator.Eq)
                {
                    this.CompileNumberLiteralEquality(expr);
                    return;
                }

                bool leftNumber = (XPathExprType.Number == expr.Left.Type);
                bool rightNumber = (XPathExprType.Number == expr.Right.Type);
                Fx.Assert(leftNumber || rightNumber, "");
                Fx.Assert(!(leftNumber && rightNumber), "");

                this.CompileExpression(leftNumber ? expr.Right : expr.Left);
                XPathNumberExpr litExpr = leftNumber ? (XPathNumberExpr)expr.Left : (XPathNumberExpr)expr.Right;
                double literal = litExpr.Number;
                if (litExpr.Negate)
                {
                    litExpr.Negate = false;
                    literal = -literal;
                }

                // To maximize code branch commonality, we canonacalize the relation expressions so that the non-literal
                // is always to the left and the literal to the right. If this makes us swap expressions, we must also flip
                // relation operators appropriately.
                if (leftNumber)
                {
                    // Flip operators
                    switch (expr.Op)
                    {
                        case RelationOperator.Gt:
                            expr.Op = RelationOperator.Lt;
                            break;
                        case RelationOperator.Ge:
                            expr.Op = RelationOperator.Le;
                            break;
                        case RelationOperator.Lt:
                            expr.Op = RelationOperator.Gt;
                            break;
                        case RelationOperator.Le:
                            expr.Op = RelationOperator.Ge;
                            break;
                    }
                }

                if (0 != (this.compiler.flags & QueryCompilerFlags.InverseQuery))
                {
                    this.codeBlock.Append(new NumberIntervalOpcode(literal, expr.Op));
                }
                else
                {
                    this.codeBlock.Append(new NumberRelationOpcode(literal, expr.Op));
                }
            }
コード例 #16
0
            void CompileNumberLiteralEquality(XPathRelationExpr expr)
            {
                Fx.Assert(expr.Op == RelationOperator.Eq, "");

                bool leftNumber = (XPathExprType.Number == expr.Left.Type);
                bool rightNumber = (XPathExprType.Number == expr.Right.Type);

                Fx.Assert(leftNumber || rightNumber, "");
                Fx.Assert(!(leftNumber && rightNumber), "");

                this.CompileExpression(leftNumber ? expr.Right : expr.Left);
                XPathNumberExpr litExpr = leftNumber ? (XPathNumberExpr)expr.Left : (XPathNumberExpr)expr.Right;
                double literal = litExpr.Number;
                if (litExpr.Negate)
                {
                    litExpr.Negate = false;
                    literal = -literal;
                }
                this.codeBlock.Append(new NumberEqualsOpcode(literal));
            }
コード例 #17
0
            void CompileLiteralRelation(XPathRelationExpr expr)
            {
                XPathLiteralExpr left = (XPathLiteralExpr)expr.Left;
                XPathLiteralExpr right = (XPathLiteralExpr)expr.Right;

                bool result = QueryValueModel.CompileTimeCompare(left.Literal, right.Literal, expr.Op);
                this.codeBlock.Append(new PushBooleanOpcode(result));
            }
コード例 #18
0
        XPathExpr ParseRelationalExpression()
        {
            XPathExpr leftExpr = this.ParseAdditiveExpression();

            if (null != leftExpr)
            {
                RelationOperator op;

                do
                {
                    op = RelationOperator.None;

                    XPathToken token = this.NextToken();

                    if (null != token)
                    {
                        switch (token.TokenID)
                        {
                            default:
                                this.PushToken(token);
                                break;

                            case XPathTokenID.Lt:
                                op = RelationOperator.Lt;
                                break;

                            case XPathTokenID.Lte:
                                op = RelationOperator.Le;
                                break;

                            case XPathTokenID.Gt:
                                op = RelationOperator.Gt;
                                break;

                            case XPathTokenID.Gte:
                                op = RelationOperator.Ge;
                                break;
                        }
                        if (RelationOperator.None != op)
                        {
                            XPathExpr rightExpr = this.ParseAdditiveExpression();

                            if (null == rightExpr)
                            {
                                this.ThrowError(QueryCompileError.InvalidExpression);
                            }

                            leftExpr = new XPathRelationExpr(op, leftExpr, rightExpr);
                        }
                    }
                } while (RelationOperator.None != op);
            }

            return leftExpr;
        }
コード例 #19
0
 private void CompileStringLiteralEquality(XPathRelationExpr expr)
 {
     bool flag = XPathExprType.String == expr.Left.Type;
     XPathExprType type = expr.Right.Type;
     this.CompileExpression(flag ? expr.Right : expr.Left);
     string literal = flag ? ((XPathStringExpr) expr.Left).String : ((XPathStringExpr) expr.Right).String;
     this.codeBlock.Append(new StringEqualsOpcode(literal));
 }
コード例 #20
0
 private void CompileRelational(XPathRelationExpr expr)
 {
     if (expr.Left.IsLiteral && expr.Right.IsLiteral)
     {
         this.CompileLiteralRelation(expr);
     }
     else
     {
         if (expr.Op != RelationOperator.Ne)
         {
             if ((XPathExprType.Number == expr.Left.Type) || (XPathExprType.Number == expr.Right.Type))
             {
                 this.CompileNumberRelation(expr);
                 return;
             }
             if ((expr.Op == RelationOperator.Eq) && ((XPathExprType.String == expr.Left.Type) || (XPathExprType.String == expr.Right.Type)))
             {
                 this.CompileStringLiteralEquality(expr);
                 return;
             }
         }
         this.CompileExpression(expr.Left);
         this.CompileExpression(expr.Right);
         this.codeBlock.Append(new RelationOpcode(expr.Op));
     }
 }
コード例 #21
0
            private void CompileNumberRelation(XPathRelationExpr expr)
            {
                if (expr.Op == RelationOperator.Eq)
                {
                    this.CompileNumberLiteralEquality(expr);
                }
                else
                {
                    bool flag = XPathExprType.Number == expr.Left.Type;
                    XPathExprType type = expr.Right.Type;
                    this.CompileExpression(flag ? expr.Right : expr.Left);
                    XPathNumberExpr expr2 = flag ? ((XPathNumberExpr) expr.Left) : ((XPathNumberExpr) expr.Right);
                    double number = expr2.Number;
                    if (expr2.Negate)
                    {
                        expr2.Negate = false;
                        number = -number;
                    }
                    if (flag)
                    {
                        switch (expr.Op)
                        {
                            case RelationOperator.Gt:
                                expr.Op = RelationOperator.Lt;
                                break;

                            case RelationOperator.Ge:
                                expr.Op = RelationOperator.Le;
                                break;

                            case RelationOperator.Lt:
                                expr.Op = RelationOperator.Gt;
                                break;

                            case RelationOperator.Le:
                                expr.Op = RelationOperator.Ge;
                                break;
                        }
                    }
                    if ((this.compiler.flags & QueryCompilerFlags.InverseQuery) != QueryCompilerFlags.None)
                    {
                        this.codeBlock.Append(new NumberIntervalOpcode(number, expr.Op));
                    }
                    else
                    {
                        this.codeBlock.Append(new NumberRelationOpcode(number, expr.Op));
                    }
                }
            }
コード例 #22
0
 private void CompileNumberLiteralEquality(XPathRelationExpr expr)
 {
     bool flag = XPathExprType.Number == expr.Left.Type;
     XPathExprType type = expr.Right.Type;
     this.CompileExpression(flag ? expr.Right : expr.Left);
     XPathNumberExpr expr2 = flag ? ((XPathNumberExpr) expr.Left) : ((XPathNumberExpr) expr.Right);
     double number = expr2.Number;
     if (expr2.Negate)
     {
         expr2.Negate = false;
         number = -number;
     }
     this.codeBlock.Append(new NumberEqualsOpcode(number));
 }