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)); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
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); }
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); }
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); }
/// <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); }
/// <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)); } }
/// <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)); } }
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); }
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; }
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; }
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; }
/// <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; }
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; }
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); }
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); }
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; }