Пример #1
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));
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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;
        }
Пример #5
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;
        }
Пример #6
0
        private static object DoInFunction(ParamObjectCollection arrParams, CalculateContext calcContext)
        {
            bool result = false;

            if (arrParams.Count > 0)
            {
                object sourceData = arrParams[0].Value;

                for (int i = 1; i < arrParams.Count; i++)
                {
                    if ((bool)CompareEqualOP(sourceData, arrParams[i].Value, 0))
                    {
                        result = true;
                        break;
                    }
                }
            }

            return(result);
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
0
        /// <summary>
        /// 计算表达式字典
        /// </summary>
        /// <param name="strFuncName"></param>
        /// <param name="arrParams"></param>
        /// <param name="calcContext"></param>
        /// <returns></returns>
        private static object CalculateExpressionDictionary(string strFuncName, ParamObjectCollection arrParams, CalculateContext calcContext)
        {
            ExpressionDictionaryCollection dictionaries = (ExpressionDictionaryCollection)ObjectContextCache.Instance.GetOrAddNewValue(
                "ExpressionDictionaries",
                (cache, key) =>
            {
                ExpressionDictionaryCollection expDicts = new ExpressionDictionaryCollection();

                expDicts.InitFromConfiguration(ExpressionDictionarySettings.GetConfig());

                cache.Add("ExpressionDictionaries", expDicts);

                return(expDicts);
            });

            ExpressionDictionary dictionary = dictionaries[strFuncName];

            object oValue = null;

            if (dictionary != null)
            {
                ExpressionDictionaryCalculatorContext context = new ExpressionDictionaryCalculatorContext(dictionary, calcContext.CallerContxt);

                string key = string.Empty;

                if (arrParams.Count > 0 && arrParams[0].Value != null)
                {
                    key = arrParams[0].Value.ToString();
                }

                oValue = dictionary.Calculator.Calculate(strFuncName, key, context);
            }

            return(oValue);
        }
Пример #10
0
        /// <summary>
        /// 计算所有参数都已经准备好了的函数
        /// </summary>
        /// <param name="strFuncName"></param>
        /// <param name="arrParams"></param>
        /// <param name="calcContext"></param>
        /// <returns></returns>
        private static object CalculateFunctionWithParameters(string strFuncName, ParamObjectCollection arrParams, CalculateContext calcContext)
        {
            object oValue = null;

            try
            {
                switch (strFuncName.ToLower())
                {
                case "now":
                    oValue = DateTime.Now;
                    break;

                case "today":
                    oValue = DateTime.Today;
                    break;

                case "dateinterval.day":
                    oValue = "d";
                    break;

                case "dateinterval.hour":
                    oValue = "h";
                    break;

                case "dateinterval.minute":
                    oValue = "n";
                    break;

                case "dateinterval.second":
                    oValue = "s";
                    break;

                case "dateinterval.millisecond":
                    oValue = "ms";
                    break;

                case "datediff":
                    oValue = DoDateDiff(arrParams);
                    break;

                case "mindate":
                    oValue = DateTime.MinValue;
                    break;

                case "maxdate":
                    oValue = DateTime.MaxValue;
                    break;
                    //default:
                    //    {
                    //        if (calcContext.CalculateUserFunction != null)
                    //            oValue = calcContext.CalculateUserFunction(strFuncName, arrParams, calcContext.CallerContxt);

                    //        break;
                    //    }
                }

                return(oValue);
            }
            catch (ParsingException)
            {
                throw;
            }
            catch (System.Exception ex)
            {
                throw new SystemSupportException(string.Format(ExpressionParserRes.FunctionError, strFuncName, ex.Message));
            }
        }
Пример #11
0
        /// <summary>
        /// 计算所有参数都已经准备好了的函数
        /// </summary>
        /// <param name="strFuncName"></param>
        /// <param name="arrParams"></param>
        /// <param name="calcContext"></param>
        /// <returns></returns>
        private static object CalculateFunctionWithParameters(string strFuncName, ParamObjectCollection arrParams, CalculateContext calcContext)
        {
            object oValue = null;

            try
            {
                switch (strFuncName.ToLower())
                {
                    case "now":
                        oValue = DateTime.Now;
                        break;
                    case "today":
                        oValue = DateTime.Today;
                        break;
                    case "dateinterval.day":
                        oValue = "d";
                        break;
                    case "dateinterval.hour":
                        oValue = "h";
                        break;
                    case "dateinterval.minute":
                        oValue = "n";
                        break;
                    case "dateinterval.second":
                        oValue = "s";
                        break;
                    case "dateinterval.millisecond":
                        oValue = "ms";
                        break;
                    case "datediff":
                        oValue = DoDateDiff(arrParams);
                        break;
                    case "mindate":
                        oValue = DateTime.MinValue;
                        break;
                    case "maxdate":
                        oValue = DateTime.MaxValue;
                        break;
                    //default:
                    //    {
                    //        if (calcContext.CalculateUserFunction != null)
                    //            oValue = calcContext.CalculateUserFunction(strFuncName, arrParams, calcContext.CallerContxt);

                    //        break;
                    //    }
                }

                return oValue;
            }
            catch (ParsingException)
            {
                throw;
            }
            catch (System.Exception ex)
            {
                throw new SystemSupportException(string.Format(ExpressionParserRes.FunctionError, strFuncName, ex.Message));
            }
        }
Пример #12
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);
        }
Пример #13
0
        private static object DoInFunction(ParamObjectCollection arrParams, CalculateContext calcContext)
        {
            bool result = false;

            if (arrParams.Count > 0)
            {
                object sourceData = arrParams[0].Value;

                for (int i = 1; i < arrParams.Count; i++)
                {
                    if ((bool)CompareEqualOP(sourceData, arrParams[i].Value, 0))
                    {
                        result = true;
                        break;
                    }
                }
            }

            return result;
        }
Пример #14
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;
        }
Пример #15
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;
        }
Пример #16
0
        /// <summary>
        /// 计算表达式字典
        /// </summary>
        /// <param name="strFuncName"></param>
        /// <param name="arrParams"></param>
        /// <param name="calcContext"></param>
        /// <returns></returns>
        private static object CalculateExpressionDictionary(string strFuncName, ParamObjectCollection arrParams, CalculateContext calcContext)
        {
            ExpressionDictionaryCollection dictionaries = (ExpressionDictionaryCollection)ObjectContextCache.Instance.GetOrAddNewValue(
                "ExpressionDictionaries",
                (cache, key) =>
                {
                    ExpressionDictionaryCollection expDicts = new ExpressionDictionaryCollection();

                    expDicts.InitFromConfiguration(ExpressionDictionarySettings.GetConfig());

                    cache.Add("ExpressionDictionaries", expDicts);

                    return expDicts;
                });

            ExpressionDictionary dictionary = dictionaries[strFuncName];

            object oValue = null;

            if (dictionary != null)
            {
                ExpressionDictionaryCalculatorContext context = new ExpressionDictionaryCalculatorContext(dictionary, calcContext.CallerContxt);

                string key = string.Empty;

                if (arrParams.Count > 0 && arrParams[0].Value != null)
                    key = arrParams[0].Value.ToString();

                oValue = dictionary.Calculator.Calculate(strFuncName, key, context);
            }

            return oValue;
        }
Пример #17
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;
        }
Пример #18
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);
        }
Пример #19
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);
        }
Пример #20
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;
        }