Beispiel #1
0
        /// <summary>
        /// 处理逻辑非"!"运算符
        /// </summary>
        /// <returns></returns>
        private ExpTreeNode DoSgOP(ParsingContext context)
        {
            SkipSpaces(context);

            ExpTreeNode node = null;

            char ch = context.CurrentChar;

            if (ch == '!')
            {
                OutputID(context, Operation_IDs.OI_NOT, "!", context.Position);

                int nPos = context.Position;

                context.Position++;

                ExpTreeNode node2 = DoSgOP(context);
                node = NewTreeNode(context, null, node2, Operation_IDs.OI_NOT, nPos);
            }
            else
            {
                node = DoFactor(context);
            }

            return(node);
        }
Beispiel #2
0
        /// <summary>
        /// 处理加减运算
        /// </summary>
        /// <returns></returns>
        private ExpTreeNode DoAddSub(ParsingContext context)
        {
            ExpTreeNode node  = null;
            ExpTreeNode node1 = DoMulDiv(context);
            ExpTreeNode node2 = null;

            char ch = context.CurrentChar;

            while (ch == '-' || ch == '+')
            {
                Operation_IDs oID = Operation_IDs.OI_NONE;

                oID = (ch == '-') ? Operation_IDs.OI_MINUS : Operation_IDs.OI_ADD;

                OutputID(context, oID, ch.ToString(), context.Position);

                int nPos = context.Position;

                context.Position++;

                node2 = DoMulDiv(context);

                node = NewTreeNode(context, node1, node2, oID, nPos);

                node1 = node;

                ch = context.CurrentChar;
            }

            return(node1);
        }
Beispiel #3
0
        /// <summary>
        /// 处理乘除运算
        /// </summary>
        /// <returns></returns>
        private ExpTreeNode DoMulDiv(ParsingContext context)
        {
            ExpTreeNode node1 = DoSgOP(context);

            char ch = context.CurrentChar;

            while (ch == '*' || ch == '/')
            {
                Operation_IDs oID = Operation_IDs.OI_NONE;

                oID = (ch == '*') ? Operation_IDs.OI_MUL : Operation_IDs.OI_DIV;

                OutputID(context, oID, ch.ToString(), context.Position);

                int nPos = context.Position;

                context.Position++;
                ExpTreeNode node2 = DoSgOP(context);

                node1 = NewTreeNode(context, node1, node2, oID, nPos);

                ch = context.CurrentChar;
            }

            return(node1);
        }
Beispiel #4
0
        private static ExpTreeNode DoLogical_AND_OR(ParsingContext context, char chSensitive, Operation_IDs oID, Func <ParsingContext, ExpTreeNode> doNextOP)
        {
            ExpTreeNode node  = null;
            ExpTreeNode node1 = doNextOP(context);
            ExpTreeNode node2 = null;

            while (context.CurrentChar == chSensitive)
            {
                int  nPos = context.Position;
                char op   = context.ExpressionChars[context.Position++];

                if (op == chSensitive)
                {
                    OutputID(context, oID, chSensitive.ToString() + chSensitive.ToString(), nPos);
                    context.Position++;
                }

                node2 = doNextOP(context);

                node = NewTreeNode(context, node1, node2, oID, nPos);

                node1 = node;
            }

            return(node1);
        }
Beispiel #5
0
        private object DoInFunction(ExpTreeNode funcNode, IReadOnlyList <ExpTreeNode> arrParams, CalculateContext calcContext)
        {
            bool result = false;

            if (arrParams.Count > 0)
            {
                object sourceData = this.VExp(arrParams[0], calcContext);

                if (sourceData != null)
                {
                    for (int i = 1; i < arrParams.Count; i++)
                    {
                        object itemValue = this.VExp(arrParams[i], calcContext);

                        if (itemValue != null)
                        {
                            if ((bool)CompareEqualOP(sourceData, itemValue, 0))
                            {
                                result = true;
                                break;
                            }
                        }
                    }
                }
            }

            return(result);
        }
Beispiel #6
0
        private object DoIIFFunction(ExpTreeNode funcNode, IReadOnlyList <ExpTreeNode> arrParams, CalculateContext calcContext)
        {
            if (arrParams.Count != 3)
            {
                throw ParsingException.NewParsingException(ParseError.peInvalidParam,
                                                           funcNode.Position, funcNode.FunctionName, "3");
            }
            object result = false;

            if (arrParams.Count > 0)
            {
                object sourceData = this.VExp(arrParams[0], calcContext);

                if (sourceData != null)
                {
                    bool sourceCondition = (bool)DataConverter.ChangeType(sourceData, typeof(bool));

                    if (sourceCondition)
                    {
                        result = this.VExp(arrParams[1], calcContext);
                    }
                    else
                    {
                        result = this.VExp(arrParams[2], calcContext);
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// 分析表达式,
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>分析结果</returns>
        /// <remarks>
        /// 对传入的表达式进行分析
        /// <code source="..\Framework\TestProjects\DeluxeWorks.Library.Test\Expression\ExpressionParserTest.cs" region="parse" lang="cs" title="调用分析表达式的函数" />
        /// </remarks>
        public static ParseResult Parse(string expression)
        {
            ParseResult result = null;

            if (string.IsNullOrEmpty(expression) == false)
            {
                ParsingContext context = new ParsingContext(expression);

                context.OutputIdentifiers = true;
                ExpTreeNode tree = ExpressionParser.instance.DoExpression(context);

                if (context.CurrentChar != '\0')
                {
                    throw ParsingException.NewParsingException(ParseError.peInvalidOperator, context.Position, context.CurrentChar.ToString());
                }

                result = new ParseResult(tree, context.Identifiers);
            }
            else
            {
                result = new ParseResult(null, null);
            }

            return(result);
        }
Beispiel #8
0
        private static ExpTreeNode NewTreeNode(ParsingContext context, ExpTreeNode left, ExpTreeNode right, Operation_IDs oID, int nPosition)
        {
            ExpTreeNode node = NewTreeNode(context, left, right, oID);

            node.Position = nPosition;

            return(node);
        }
Beispiel #9
0
        /// <summary>
        /// 生成一个新的二叉树节点
        /// </summary>
        private static ExpTreeNode NewTreeNode(ParsingContext context)
        {
            ExpTreeNode node = new ExpTreeNode();

            node.Position = context.Position;

            return(node);
        }
Beispiel #10
0
        /// <summary>
        /// 处理各种系数、负数、括号等
        /// </summary>
        /// <returns></returns>
        private ExpTreeNode DoFactor(ParsingContext context)
        {
            SkipSpaces(context);

            ExpTreeNode node = null;

            char ch = context.CurrentChar;

            int nPos = context.Position;

            switch (ch)
            {
            case '-':       //处理负号
                OutputID(context, Operation_IDs.OI_NEG, "-", context.Position);

                context.Position++;

                ExpTreeNode node2 = DoExpression(context);

                ExpTreeNode left = NewTreeNode(context);
                left.OperationID = Operation_IDs.OI_NEG;
                left.Value       = (decimal) - 1;
                left.Position    = nPos;

                node = NewTreeNode(context, left, node2, Operation_IDs.OI_MUL, nPos);
                break;

            case '(':
                OutputID(context, Operation_IDs.OI_LBRACKET, "(", context.Position);
                context.Position++;
                node = DoExpression(context);

                SkipSpaces(context);

                if (context.CurrentChar != ')')
                {
                    if (context.ThrowParseException)
                    {
                        throw ParsingException.NewParsingException(ParseError.peCharExpected, context.Position, ")");
                    }
                }
                else
                {
                    OutputID(context, Operation_IDs.OI_RBRACKET, ")", context.Position);
                }

                context.Position++;
                break;

            default:
                node = DoIdentifier(context);
                break;
            }

            SkipSpaces(context);

            return(node);
        }
Beispiel #11
0
        /// <summary>
        /// 生成一个新的二叉树节点
        /// </summary>
        /// <param name="context">运行上下文</param>
        /// <param name="left">左子树</param>
        /// <param name="right">右子树</param>
        /// <param name="oID">操作类型</param>
        /// <returns></returns>
        private static ExpTreeNode NewTreeNode(ParsingContext context, ExpTreeNode left, ExpTreeNode right, Operation_IDs oID)
        {
            ExpTreeNode node = NewTreeNode(context);

            node.Left        = left;
            node.Right       = right;
            node.OperationID = oID;

            return(node);
        }
Beispiel #12
0
        private static ExpTreeNode DoDatetime(ParsingContext context)
        {
            int  nPos = context.Position;
            char ch   = context.ExpressionChars[++context.Position];

            StringBuilder strB = new StringBuilder(256);

            strB.Append("#");

            while (ch != '\0')
            {
                strB.Append(ch);

                if (ch == '#')
                {
                    context.Position++;
                    break;
                }

                ch = context.ExpressionChars[++context.Position];
            }

            if (ch == '\0')
            {
                if (context.ThrowParseException)
                {
                    throw ParsingException.NewParsingException(ParseError.peCharExpected, context.Position, "#");
                }
            }

            ExpTreeNode node = NewTreeNode(context);

            node.Position    = nPos;
            node.OperationID = Operation_IDs.OI_DATETIME;

            try
            {
                string strID = strB.ToString();
                node.Value = DateTime.Parse(strID);

                OutputID(context, Operation_IDs.OI_DATETIME, strID, nPos);

                return(node);
            }
            catch (System.FormatException)
            {
                if (context.ThrowParseException)
                {
                    throw ParsingException.NewParsingException(ParseError.peFormatError, nPos);
                }

                return(null);
            }
        }
Beispiel #13
0
        private static ExpTreeNode DoString(ParsingContext context)
        {
            int  nPos = context.Position;
            char ch   = context.ExpressionChars[++context.Position];

            StringBuilder strB   = new StringBuilder(256);
            StringBuilder strIDB = new StringBuilder(256);

            strIDB.Append('"');

            while (ch != '\0')
            {
                if (ch != '"')
                {
                    strB.Append(ch);
                    strIDB.Append(ch);
                    context.Position++;
                }
                else
                if (context.ExpressionChars[context.Position + 1] == '"')
                {
                    strB.Append('"');
                    strIDB.Append("\"\"");
                    context.Position += 2;
                }
                else
                {
                    strIDB.Append('"');
                    context.Position++;
                    break;
                }

                ch = context.CurrentChar;
            }

            if (ch == '\0')
            {
                if (context.ThrowParseException)
                {
                    throw ParsingException.NewParsingException(ParseError.peCharExpected, context.Position, "\"");
                }
            }

            string strID = strIDB.ToString();

            OutputID(context, Operation_IDs.OI_STRING, strID, nPos);
            ExpTreeNode node = NewTreeNode(context);

            node.Position    = nPos;
            node.OperationID = Operation_IDs.OI_STRING;
            node.Value       = strB.ToString();

            return(node);
        }
Beispiel #14
0
        private ParamObjectCollection GetParams(List <ExpTreeNode> arrParams, CalculateContext calcContext)
        {
            List <ParamObject> list = new List <ParamObject>();

            for (int i = 0; i < arrParams.Count; i++)
            {
                ExpTreeNode node = (ExpTreeNode)arrParams[i];

                list.Add(new ParamObject(VExp(node, calcContext), node.Position, i));
            }

            return(new ParamObjectCollection(list));
        }
Beispiel #15
0
        /// <summary>
        /// 获取树结点值
        /// </summary>
        /// <param name="tree">二叉树节点</param>
        /// <param name="builtInFunctionsWrapper">包含内置函数的实现类</param>
        /// <param name="callerContext">调用者上下文</param>
        /// <param name="optimize">最优化选项</param>
        /// <returns>树结点值</returns>
        public object GetValue(ExpTreeNode tree, object builtInFunctionsWrapper, object callerContext, bool optimize)
        {
            object result = null;

            if (tree != null)
            {
                CalculateContext calcContext = new CalculateContext();

                calcContext.Optimize                = optimize;
                calcContext.CallerContxt            = callerContext;
                calcContext.BuiltInFunctionsWrapper = builtInFunctionsWrapper;

                result = VExp(tree, calcContext);
            }

            return(result);
        }
Beispiel #16
0
        /// <summary>
        /// 获取树结点值
        /// </summary>
        /// <param name="tree">二叉树节点</param>
        /// <param name="calcUDF">用户自定义函数的委托</param>
        /// <param name="callerContext">调用者上下文</param>
        /// <param name="optimize">最优化选项</param>
        /// <returns>树结点值</returns>
        public object GetValue(ExpTreeNode tree, CalculateUserFunction calcUDF, object callerContext, bool optimize)
        {
            object result = null;

            if (tree != null)
            {
                CalculateContext calcContext = new CalculateContext();

                calcContext.Optimize              = optimize;
                calcContext.CallerContxt          = callerContext;
                calcContext.CalculateUserFunction = calcUDF;

                result = VExp(tree, calcContext);
            }

            return(result);
        }
Beispiel #17
0
        private object CalculateFunction(ExpTreeNode funcNode, List <ExpTreeNode> arrParams, CalculateContext calcContext)
        {
            object oValue = null;

            switch (funcNode.FunctionName.ToLower())
            {
            case "in":
                oValue = this.DoInFunction(funcNode, arrParams, calcContext);
                break;

            case "iif":
                oValue = this.DoIIFFunction(funcNode, arrParams, calcContext);
                break;
            }

            return(oValue);
        }
Beispiel #18
0
        /// <summary>
        /// 处理各种数字、标识符、自定义函数、字符串等
        /// </summary>
        /// <returns></returns>
        private ExpTreeNode DoIdentifier(ParsingContext context)
        {
            ExpTreeNode result = null;

            SkipSpaces(context);

            char ch = context.CurrentChar;

            if (ch != '\0')
            {
                switch (ch)
                {
                case '#':       //datetime
                    result = DoDatetime(context);
                    break;

                case '"':       //string
                    result = DoString(context);
                    break;

                default:
                    if (Char.IsDigit(ch) || ch == '.')
                    {
                        result = DoNumber(context);
                    }
                    else
                    if (Char.IsLetter(ch) || ch == '_')
                    {
                        result = DoFunctionID(context);
                    }
                    else
                    {
                        if (context.ThrowParseException)
                        {
                            throw ParsingException.NewParsingException(ParseError.peInvalidOperator, context.Position, ch.ToString());
                        }
                    }
                    break;
                }

                SkipSpaces(context);
            }

            return(result);
        }
Beispiel #19
0
        /// <summary>
        /// 重载实现二叉树的反序列化
        /// </summary>
        /// <param name="info">The object to be populated with serialization information.</param>
        /// <param name="context">The destination context of the serialization.</param>
        /// <remarks>
        /// 二叉树的反序列化
        /// <code source="..\Framework\TestProjects\DeluxeWorks.Library.Test\Expression\ExpressionParserTest.cs" region="Serialization" lang="cs" />
        /// </remarks>
        private ExpTreeNode(SerializationInfo info, StreamingContext context)
        {
            this.left        = (ExpTreeNode)info.GetValue("Left", typeof(ExpTreeNode));
            this.right       = (ExpTreeNode)info.GetValue("Right", typeof(ExpTreeNode));
            this.position    = info.GetInt32("Position");
            this.operationID = (Operation_IDs)info.GetInt16("OperationID");

            string valueTypeName = info.GetString("ValueType");

            if (valueTypeName != "NullValue")
            {
                this.nodeValue = (Object)info.GetValue("Value", Type.GetType(valueTypeName));
            }
            else
            {
                this.nodeValue = (Object)info.GetValue("Value", typeof(Object));
            }
            this.functionParams = (List <ExpTreeNode>)info.GetValue("Params", typeof(ExpTreeNode));
            this.functionName   = info.GetString("FunctionName");
        }
Beispiel #20
0
        private ExpTreeNode DoFunction(ParsingContext context, string strId)
        {
            ExpTreeNode node = null;

            if (string.Compare(strId, "true", true) == 0 || string.Compare(strId, "false", true) == 0)
            {
                node             = NewTreeNode(context);
                node.Position    = context.Position - strId.Length;
                node.OperationID = Operation_IDs.OI_BOOLEAN;
                node.Value       = bool.Parse(strId.ToLower());

                OutputID(context, Operation_IDs.OI_BOOLEAN, strId, node.Position);
            }
            else
            {
                node = GetFunctionNode(context, Operation_IDs.OI_USERDEFINE, strId);
            }

            return(node);
        }
Beispiel #21
0
        private static ExpTreeNode DoNumber(ParsingContext context)
        {
            int  nPos = context.Position;
            char ch   = context.CurrentChar;

            while (Char.IsDigit(ch) || (ch == '.'))
            {
                ch = context.ExpressionChars[++context.Position];
            }

            ExpTreeNode node = NewTreeNode(context);

            node.Position    = nPos;
            node.OperationID = Operation_IDs.OI_NUMBER;

            string ns = new String(context.ExpressionChars, nPos, context.Position - nPos);

            node.Value = decimal.Parse(ns);

            OutputID(context, Operation_IDs.OI_NUMBER, ns, nPos);

            return(node);
        }
 /// <summary>
 /// 根据语法解析完的Tree,计算出结果
 /// </summary>
 /// <param name="tree"></param>
 /// <param name="calculateUserFunction">用户自定义函数的实现</param>
 /// <param name="callerContext"></param>
 /// <param name="optimize">是否进行bool运算优化,缺省为true</param>
 /// <returns></returns>
 /// <remarks>
 /// 对含自定义函数的表达式进行解析后生成的二叉树,调用该函数进行运算得出结果值
 /// <code source="..\Framework\TestProjects\DeluxeWorks.Library.Test\Expression\ExpressionParserTest.cs" region="parse" lang="cs" title="对解析生成的二叉树进行计算" />
 /// </remarks>
 public static object GetTreeValue(ExpTreeNode tree, CalculateUserFunction calculateUserFunction, object callerContext, bool optimize)
 {
     return(ExpTreeExecutor.Instance.GetValue(tree, calculateUserFunction, callerContext, optimize));
 }
 /// <summary>
 /// 根据语法解析完的Tree,计算出结果
 /// </summary>
 /// <param name="tree"></param>
 /// <param name="builtInFunctionsWrapper">包含内置函数的实现类</param>
 /// <param name="callerContext">调用者上下文</param>
 /// <param name="optimize">最优化选项</param>
 /// <returns>树结点值</returns>
 public static object GetTreeValue(ExpTreeNode tree, object builtInFunctionsWrapper, object callerContext, bool optimize)
 {
     return(ExpTreeExecutor.Instance.GetValue(tree, builtInFunctionsWrapper, callerContext, optimize));
 }
Beispiel #24
0
 internal ParseResult(ExpTreeNode tree, ParseIdentifier identifiers)
 {
     this.tree        = tree;
     this.identifiers = identifiers;
 }
Beispiel #25
0
        /// <summary>
        /// 逻辑比较运算
        /// </summary>
        /// <returns></returns>
        private ExpTreeNode DoLogicalOP(ParsingContext context)
        {
            ExpTreeNode node  = null;
            ExpTreeNode node1 = DoAddSub(context);
            ExpTreeNode node2 = null;

            char op = context.CurrentChar;

            string strID = string.Empty;

            while (op == '>' || op == '<' || op == '=')
            {
                int nPos = context.Position;

                Operation_IDs oID = Operation_IDs.OI_NONE;

                if (context.ExpressionChars[++context.Position] == '=')
                {
                    switch (op)
                    {
                    case '>':           //>=
                        oID   = Operation_IDs.OI_GREATEQUAL;
                        strID = ">=";
                        break;

                    case '<':           //<=
                        oID   = Operation_IDs.OI_LESSEQUAL;
                        strID = "<=";
                        break;

                    case '=':           //==
                        oID   = Operation_IDs.OI_EQUAL;
                        strID = "==";
                        break;

                    default:
                    {
                        if (context.ThrowParseException)
                        {
                            throw ParsingException.NewParsingException(ParseError.peInvalidOperator,
                                                                       context.Position, op.ToString());
                        }
                        break;
                    }
                    }

                    context.Position++;
                }
                else
                {
                    if (context.CurrentChar == '>')
                    {
                        if (op == '<')  //<>
                        {
                            strID = "<>";
                            oID   = Operation_IDs.OI_NOT_EQUAL;
                            context.Position++;
                        }
                        else
                        {
                            if (context.ThrowParseException)
                            {
                                throw ParsingException.NewParsingException(ParseError.peInvalidOperator,
                                                                           context.Position, op.ToString());
                            }
                        }
                    }
                    else
                    {
                        switch (op)
                        {
                        case '>':
                            oID   = Operation_IDs.OI_GREAT;
                            strID = ">";
                            break;

                        case '<':
                            oID   = Operation_IDs.OI_LESS;
                            strID = "<";
                            break;

                        default:
                        {
                            if (context.ThrowParseException)
                            {
                                throw ParsingException.NewParsingException(ParseError.peInvalidOperator,
                                                                           context.Position, op.ToString());
                            }

                            break;
                        }
                        }
                    }
                }

                OutputID(context, oID, strID, nPos);

                node2 = DoAddSub(context);

                node = NewTreeNode(context, node1, node2, oID, nPos);

                node1 = node;

                op = context.CurrentChar;
            }

            return(node1);
        }
Beispiel #26
0
        private ExpTreeNode GetFunctionNode(ParsingContext context, Operation_IDs funcID, string strID)
        {
            ExpTreeNode        node      = null;
            ExpTreeNode        nodeTemp  = null;
            List <ExpTreeNode> paramBase = new List <ExpTreeNode>(4);

            int nStartFunction = context.Position - strID.Length;

            OutputID(context, Operation_IDs.OI_USERDEFINE, strID, nStartFunction);

            if (context.CurrentChar == '(')     //有参数
            {
                OutputIDToSubLevel(context);
                OutputID(context, Operation_IDs.OI_LBRACKET, "(", context.Position);

                do
                {
                    context.Position++;
                    SkipSpaces(context);

                    nodeTemp = DoExpression(context);

                    if (nodeTemp != null)
                    {
                        paramBase.Add(nodeTemp);

                        SkipSpaces(context);
                    }
                    else
                    {
                        break;
                    }

                    if (context.CurrentChar == ',')
                    {
                        OutputID(context, Operation_IDs.OI_COMMA, ",", context.Position);
                    }
                }while (context.CurrentChar == ',');

                if (context.CurrentChar == ')')
                {
                    OutputID(context, Operation_IDs.OI_RBRACKET, ")", context.Position);
                    OutputIDToParentLevel(context);

                    context.Position++;
                    node             = NewTreeNode(context);
                    node.Position    = nStartFunction;
                    node.Params      = paramBase;
                    node.OperationID = funcID;

                    if (funcID == Operation_IDs.OI_USERDEFINE)
                    {
                        node.FunctionName = strID;
                    }
                }
                else
                {
                    if (context.ThrowParseException)
                    {
                        throw ParsingException.NewParsingException(ParseError.peCharExpected, context.Position, ")");
                    }
                }

                SkipSpaces(context);
            }
            else        //没有参数
            {
                node             = NewTreeNode(context);
                node.Position    = nStartFunction;
                node.Params      = paramBase;
                node.OperationID = funcID;

                if (funcID == Operation_IDs.OI_USERDEFINE)
                {
                    node.FunctionName = strID;
                }
            }

            return(node);
        }
 /// <summary>
 /// 根据语法解析完的Tree,计算出结果
 /// </summary>
 /// <param name="tree">解析生成的二叉树</param>
 /// <param name="calculateUserFunction">用户自定义函数的实现</param>
 /// <param name="callerContext">自定义函数上下文</param>
 /// <returns>运算结果</returns>
 /// <remarks>
 ///  对含自定义函数的表达式进行解析后生成的二叉树,调用该函数进行运算得出结果值
 /// <code source="..\Framework\TestProjects\DeluxeWorks.Library.Test\Expression\ExpressionParserTest.cs" region="parse" lang="cs" title="对解析生成的二叉树进行计算" />
 /// </remarks>
 public static object GetTreeValue(ExpTreeNode tree, CalculateUserFunction calculateUserFunction, object callerContext)
 {
     return(GetTreeValue(tree, calculateUserFunction, callerContext, true));
 }
Beispiel #28
0
        private object VExp(ExpTreeNode node, CalculateContext calcContext)
        {
            object oValue = null;

            if (node != null)
            {
                try
                {
                    switch (node.OperationID)
                    {
                    case Operation_IDs.OI_NUMBER:
                    case Operation_IDs.OI_STRING:
                    case Operation_IDs.OI_NEG:
                    case Operation_IDs.OI_BOOLEAN:
                    case Operation_IDs.OI_DATETIME:
                        oValue = node.Value;
                        break;

                    case Operation_IDs.OI_ADD:
                        oValue = AddOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_MINUS:
                    {
                        object p1 = VExp(node.Left, calcContext);
                        object p2 = VExp(node.Right, calcContext);

                        CheckOperandNull(p1, p2, node.Position);
                        oValue = NToD(p1) - NToD(p2);
                    }
                    break;

                    case Operation_IDs.OI_MUL:
                    {
                        object p1 = VExp(node.Left, calcContext);
                        object p2 = VExp(node.Right, calcContext);

                        CheckOperandNull(p1, p2, node.Position);
                        oValue = NToD(p1) * NToD(p2);
                    }
                    break;

                    case Operation_IDs.OI_DIV:
                    {
                        object p1 = VExp(node.Left, calcContext);
                        object p2 = VExp(node.Right, calcContext);

                        CheckOperandNull(p1, p2, node.Position);

                        if (NToD(p2) == 0.0M)
                        {
                            throw ParsingException.NewParsingException(ParseError.peFloatOverflow, node.Position);
                        }

                        oValue = NToD(p1) / NToD(p2);
                    }
                    break;

                    case Operation_IDs.OI_LOGICAL_OR:
                    {
                        oValue = (bool)VExp(node.Left, calcContext);
                        object oRight = (bool)false;

                        if ((bool)oValue == false)
                        {
                            oRight = VExp(node.Right, calcContext);
                        }

                        CheckOperandNull(oValue, oRight, node.Position);
                        oValue = (bool)oValue || (bool)oRight;
                    }
                    break;

                    case Operation_IDs.OI_LOGICAL_AND:
                    {
                        oValue = (bool)VExp(node.Left, calcContext);
                        object oRight = (bool)true;

                        if ((bool)oValue == true)
                        {
                            oRight = VExp(node.Right, calcContext);
                        }

                        CheckOperandNull(oValue, oRight, node.Position);
                        oValue = (bool)oValue && (bool)oRight;
                    }
                    break;

                    case Operation_IDs.OI_NOT:
                        oValue = VExp(node.Right, calcContext);
                        CheckOperandNull(oValue, node.Position);
                        oValue = !(bool)oValue;
                        break;

                    case Operation_IDs.OI_GREAT:
                        oValue = CompareGreatOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_GREATEQUAL:
                        oValue = CompareGreatEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_LESS:
                        oValue = CompareLessOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_LESSEQUAL:
                        oValue = CompareLessEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_NOT_EQUAL:
                        oValue = CompareNotEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_EQUAL:
                        oValue = CompareEqualOP(VExp(node.Left, calcContext), VExp(node.Right, calcContext), node.Position);
                        break;

                    case Operation_IDs.OI_USERDEFINE:
                    {
                        oValue = CalculateFunction(node, node.Params, calcContext);

                        if (oValue == null)
                        {
                            ParamObjectCollection funcParams = GetParams(node.Params, calcContext);

                            oValue = CalculateFunctionWithParameters(node.FunctionName, funcParams, calcContext);

                            if (oValue == null)
                            {
                                oValue = calcContext.GetUserFunctionValue(node.FunctionName, funcParams);
                            }

                            if (oValue == null)
                            {
                                oValue = CalculateExpressionDictionary(node.FunctionName, funcParams, calcContext);
                            }
                        }
                    }
                    break;

                    default:
                        throw ParsingException.NewParsingException(
                                  ParseError.peInvalidOperator,
                                  node.Position,
                                  EnumItemDescriptionAttribute.GetAttribute(node.OperationID).ShortName);
                    }
                }
                catch (System.InvalidCastException)
                {
                    throw ParsingException.NewParsingException(ParseError.peTypeMismatch, node.Position);
                }
            }

            return(oValue);
        }
 /// <summary>
 /// 根据语法解析完的Tree,计算出结果
 /// </summary>
 /// <param name="tree">语法解析树</param>
 /// <returns>结果返回值</returns>
 /// <remarks>
 /// 计算解析出的二叉树,得到运算结果
 /// <code source="..\Framework\TestProjects\DeluxeWorks.Library.Test\Expression\ExpressionParserTest.cs" region="getreevalue" lang="cs" title="对解析生成的二叉树进行计算" />
 /// </remarks>
 public static object GetTreeValue(ExpTreeNode tree)
 {
     return(GetTreeValue(tree, null, null, true));
 }