| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- using System;
- using System.Collections;
- using System.Text.RegularExpressions;
- using IwbZero.ExprFunctions;
- using IwbZero.IwbBase;
- using IwbZero.ToolCommon.StringModel;
- namespace IwbZero.Expr
- {
- public class EvalExpr
- {
- // Fields
- private static IdCollection _functions;
- private static IdCollection _operators;
- private static Regex _RegexDate = new Regex("[0-9]{1,2}/[0-9]{1,2}/[0-9]{2,4}( [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}[ ]*(AM|PM)?)?", RegexOptions.IgnoreCase);
- private static Regex _RegexDateAdd = new Regex("[0-9]+(d|m|y)", RegexOptions.IgnoreCase);
- private static Regex _RegexDecimal = new Regex(@"-?[0-9]*\.[0-9]*", RegexOptions.IgnoreCase);
- private static Regex _RegexInt = new Regex("-?[0-9]+", RegexOptions.IgnoreCase);
- private static Regex _RegexVariable = new Regex("[_@a-zA-Z][_@a-zA-Z0-9.$]*", RegexOptions.IgnoreCase);
- // Methods
- public static string Evaluate(ExprObject exprObj)
- {
- string str = "";
- if (exprObj.ChildCount == 0)
- {
- return exprObj.Expr;
- }
- EvaluateAllChildren(exprObj);
- ExprObject expr = null;
- for (int i = 0; i < exprObj.ChildCount; i++)
- {
- ExprObject child = exprObj.GetChild(i);
- if (child.IsOperator)
- {
- var @operator = child.GetOperator();
- ExprObject expr3 = exprObj.GetChild(i + 1);
- if (expr3 != null)
- {
- expr = @operator.Calculate(expr, expr3);
- i++;
- }
- }
- else if (expr == null)
- {
- expr = child;
- }
- }
- if (expr != null) str = expr.Expr;
- return str;
- }
- public static string Evaluate(string exprStr)
- {
- string str = exprStr;
- try
- {
- ExprObject exprObj = new ExprObject(exprStr, ExprElements.Expression);
- if (Parse(exprObj, true))
- {
- str = Evaluate(exprObj);
- }
- }
- catch (Exception)
- {
- // ignored
- }
- return str;
- }
- public static string Evaluate(string exprStr, Hashtable variableValueDic)
- {
- var exprStr2 = TransVariable(exprStr, variableValueDic);
- var str = Evaluate(exprStr2);
- return str;
- }
- #region Methods
- public static ExprElements GetElementType(string expression)
- {
- ExprElements variable = ExprElements.Value;
- expression = expression.Trim();
- Match match = _RegexVariable.Match(expression);
- if (((match.Index == 0)) && (match.Length == expression.Length))
- {
- variable = ExprElements.Variable;
- }
- return variable;
- }
- public static ExprTypes GetExprTypes(string expression)
- {
- ExprTypes date = ExprTypes.String;
- expression = expression.Trim();
- if ((expression.UAndT() == "TRUE") || (expression.UAndT() == "FALSE"))
- {
- return ExprTypes.Bool;
- }
- Match match = _RegexVariable.Match(expression);
- if (((match.Index == 0)) && (match.Length == expression.Length))
- {
- return ExprTypes.Variable;
- }
- match = _RegexDecimal.Match(expression);
- if (((match.Index == 0)) && (match.Length == expression.Length))
- {
- return ExprTypes.Decimal;
- }
- match = _RegexInt.Match(expression);
- if (((match.Index == 0)) && (match.Length == expression.Length))
- {
- return ExprTypes.Integer;
- }
- match = _RegexDateAdd.Match(expression);
- if (((match.Index == 0)) && (match.Length == expression.Length))
- {
- return ExprTypes.DateAdd;
- }
- match = _RegexDate.Match(expression);
- if (((match.Index == 0)) && (match.Length == expression.Length))
- {
- date = ExprTypes.Date;
- }
- return date;
- }
- public static ExprTypes GetExprTypes(ExprObject exprObj)
- {
- ExprTypes @bool = ExprTypes.String;
- if (exprObj.ElementType != ExprElements.String)
- {
- string str = exprObj.Expr.Trim();
- if ((str.UAndT() == "TRUE") || (str.UAndT() == "FALSE"))
- {
- @bool = ExprTypes.Bool;
- str = "";
- }
- if (str == "")
- {
- return @bool;
- }
- Match match = _RegexDecimal.Match(str);
- if (((match.Index == 0)) && (match.Length == str.Length))
- {
- return ExprTypes.Decimal;
- }
- match = _RegexInt.Match(str);
- if (((match.Index == 0)) && (match.Length == str.Length))
- {
- return ExprTypes.Integer;
- }
- match = _RegexDateAdd.Match(str);
- if (((match.Index == 0)) && (match.Length == str.Length))
- {
- return ExprTypes.DateAdd;
- }
- match = _RegexDate.Match(str);
- if (((match.Index == 0)) && (match.Length == str.Length))
- {
- @bool = ExprTypes.Date;
- }
- }
- return @bool;
- }
- public static DateTime GetLastDayOfMonth(DateTime datetime)
- {
- int year = datetime.Year;
- int month = datetime.Month + 1;
- if (month > 12)
- {
- year++;
- month = 1;
- }
- int day = 1;
- return (new DateTime(year, month, day) - new TimeSpan(1, 0, 0, 0));
- }
- public static DateTime AddDays(DateTime datetime, string toAdd)
- {
- DateTime time = datetime;
- toAdd = toAdd.UAndT();
- int days = toAdd.ValI();
- if (toAdd.IndexOf("D", StringComparison.Ordinal) >= 0)
- {
- return (time + new TimeSpan(days, 0, 0, 0));
- }
- int year;
- int month = datetime.Month;
- int day = datetime.Day;
- if (toAdd.IndexOf("M", StringComparison.Ordinal) >= 0)
- {
- int num5 = ((datetime.Year * 12) + datetime.Month) + days;
- year = num5 / 12;
- month = num5 - (year * 12);
- }
- else
- {
- year = datetime.Year + days;
- }
- DateTime lastDayOfMonth = GetLastDayOfMonth(new DateTime(year, month, 1));
- if (lastDayOfMonth.Day < day)
- {
- day = lastDayOfMonth.Day;
- }
- return new DateTime(year, month, day, datetime.Hour, datetime.Minute, datetime.Second, datetime.Millisecond);
- }
- public static string TransVariable(string exprStr, Hashtable variableValueDic)
- {
- string str = exprStr;
- var variables = GetVariablesInString(exprStr);
- if (variables != null)
- {
- foreach (string v in variables)
- {
- var value = GetVariableValue(v, variableValueDic);
- if (value != null)
- {
- str = str.Replace(v, value);
- }
- }
- }
- return str;
- }
- public static string TransGlobalVariable(string exprStr, Hashtable variableValueDic)
- {
- string str = exprStr;
- var variables = GetVariablesInString(exprStr);
- if (variables != null)
- {
- foreach (string v in variables)
- {
- var value = GetVariableValue(v, variableValueDic);
- str = str.Replace(v, value);
- }
- }
- return str;
- }
- private static void EvaluateAllChildren(ExprObject exprObj)
- {
- if (exprObj != null)
- {
- for (int i = 0; i < exprObj.ChildCount; i++)
- {
- ExprObject child = exprObj.GetChild(i);
- EvaluateAllChildren(child);
- if (child != null)
- {
- string str = null;
- switch (child.ElementType)
- {
- case ExprElements.Function:
- str = EvaluateFunction(child);
- break;
- case ExprElements.Variable:
- //str = TransSessionVariables(child.Expr);
- break;
- case ExprElements.Expression:
- str = Evaluate(child);
- break;
- }
- if (str != null)
- {
- child.Expr = str;
- child.ElementType = ExprElements.Value;
- }
- }
- }
- }
- }
- public static string EvaluateFunction(ExprObject exprObj)
- {
- string str = "";
- string functionId = exprObj.Expr.UAndT();
- if (_functions == null)
- {
- _functions = new IdCollection();
- }
- IwbFunction function = (IwbFunction)_functions[functionId];
- if (function == null)
- {
- function = IwbFunction.LoadById(functionId);
- if (function != null)
- {
- _functions.Add(function);
- }
- }
- if (function != null)
- {
- str = function.InvokeFunction(exprObj);
- }
- return str;
- }
- private static bool IsStartingParent(char pcChar)
- {
- return (pcChar == '(');
- }
- private static bool IsStartingQuote(char pcChar)
- {
- if (pcChar != '"')
- {
- return (pcChar == '\'');
- }
- return true;
- }
- private static int GetStaticString(string pcString, char pcQuote)
- {
- int length = pcString.Length;
- for (int i = 0; i < length; i++)
- {
- char ch = pcString[i];
- if (ch == pcQuote)
- {
- return i;
- }
- if ((ch == '\\') && (i < (length - 1)))
- {
- switch (pcString[i + 1])
- {
- case '"':
- case '\'':
- i++;
- break;
- }
- }
- }
- return -1;
- }
- private static int GetClosingParenthesis(string pcString)
- {
- int num = -1;
- int length = pcString.Length;
- int num3 = 0;
- for (int i = 0; i < length; i++)
- {
- char pcQuote = pcString[i];
- if (((pcQuote == '"') || (pcQuote == '\'')) && (i < (length - 1)))
- {
- int staticString = GetStaticString(pcString.Substring(i + 1), pcQuote);
- if (staticString >= 0)
- {
- i += staticString + 1;
- }
- }
- if (pcQuote == '(')
- {
- num3++;
- }
- else if (pcQuote == ')')
- {
- if (num3 == 0)
- {
- num = i;
- }
- else
- {
- num3--;
- }
- }
- }
- return num;
- }
- #endregion
- #region 变量赋值
- public static ArrayList GetVariablesInString(string pcString)
- {
- var arr1 = GetStringVariables(pcString)??new ArrayList();
- var arr2 = GetStringVariables(pcString, IwbVariableType.Global)??new ArrayList();
- arr1.AddRange(arr2);
- return arr1;
- }
- public static ArrayList GetStringVariables(string pcString, string variableHeader = IwbVariableType.Local)
- {
- int index;
- ArrayList poArrayList = new ArrayList();
- for (int i = pcString.IndexOf(variableHeader, StringComparison.Ordinal); i >= 0; i = pcString.IndexOf(variableHeader, index, StringComparison.Ordinal))
- {
- string pcName = variableHeader;
- for (index = i + variableHeader.Length; index < pcString.Length; index++)
- {
- char ch = pcString[index];
- if ((((ch < 'a') || (ch > 'z')) && ((ch < 'A') || (ch > 'Z'))) && (((ch < '0') || (ch > '9')) && (ch != '_')))
- {
- break;
- }
- pcName = pcName + ch;
- }
- poArrayList.InsertIdentifier(pcName);
- }
- return poArrayList;
- }
- public static string GetVariableValue(string pcVariable, Hashtable variableValueDic)
- {
- var key = pcVariable.UAndT();
- foreach (DictionaryEntry dic in variableValueDic)
- {
- if (dic.Key.UAndT() == key)
- {
- return ((IwbRtVariable)dic.Value).GetStringValue();
- }
- }
- return null;
- }
- #endregion 变量赋值
- #region 表达式转换为ExprObject
- public static bool Parse(ExprObject exprObj, bool plThrowException)
- {
- bool flag = true;
- try
- {
- Parse(exprObj);
- }
- catch (Exception)
- {
- if (plThrowException)
- {
- throw;
- }
- flag = false;
- }
- return flag;
- }
- private static void Parse(ExprObject exprObj, string pcExpression = null)
- {
- pcExpression = (pcExpression ?? exprObj.Expr)?.Trim() ?? "";
- switch (GetExprTypes(pcExpression))
- {
- case ExprTypes.Integer:
- case ExprTypes.Decimal:
- case ExprTypes.Date:
- case ExprTypes.Bool:
- exprObj.AddChild(new ExprObject(pcExpression, ExprElements.Value));
- return;
- case ExprTypes.Variable:
- exprObj.AddChild(new ExprObject(pcExpression, ExprElements.Variable));
- return;
- }
- ExprObject exprObject = null;
- string str = "";
- while (pcExpression != "")
- {
- var poNode = GetNextElement(ref pcExpression);
- if (poNode != null)
- {
- if (((poNode.ElementType != ExprElements.String) && (poNode.Expr == "-")) && ((exprObject == null) || exprObject.IsOperator))
- {
- str = "-";
- }
- else
- {
- poNode.Expr = str + poNode.Expr;
- exprObj.AddChild(poNode);
- str = "";
- }
- exprObject = poNode;
- }
- }
- CollapseSyntaxTree(exprObj);
- }
- private static ExprObject GetNextElement(ref string pcString)
- {
- ExprObject exprObj = null;
- string pcExpr = "";
- bool flag = false;
- int length = pcString.Length;
- for (int i = 0; i < length; i++)
- {
- char pcChar = pcString[i];
- string str2 = "";
- if (i < (length - 1))
- {
- str2 = pcString.Substring(i + 1);
- }
- int closingParenthesis;
- if (IsStartingParent(pcChar))
- {
- closingParenthesis = GetClosingParenthesis(str2);
- if (closingParenthesis < 0)
- {
- throw new Exception("No ending parenthesis.");
- }
- if (pcExpr != "")
- {
- string pcExpression = pcString.Substring(i + 1, closingParenthesis);
- exprObj = new ExprObject(pcExpr, ExprElements.Function);
- if (pcExpression != "")
- {
- Parse(exprObj, pcExpression);
- CollapseFunctionCall(exprObj);
- }
- }
- else
- {
- exprObj = new ExprObject(pcString.Substring(i + 1, closingParenthesis), ExprElements.Expression);
- Parse(exprObj, exprObj.Expr);
- }
- i = (i + closingParenthesis) + 2;
- flag = true;
- }
- else if (IsStartingQuote(pcChar))
- {
- if (pcExpr != "")
- {
- throw new Exception("Operand required.");
- }
- closingParenthesis = GetStaticString(str2, pcChar);
- if (closingParenthesis < 0)
- {
- throw new Exception("No ending quote.");
- }
- exprObj = new ExprObject(pcString.Substring(i + 1, closingParenthesis), ExprElements.String);
- i = (i + closingParenthesis) + 2;
- flag = true;
- }
- else
- {
- ExprOperator @operator = GetOperator(pcString.Substring(i));
- bool flag2 = true;
- if (i == (length - 1))
- {
- pcString = "";
- }
- if (((@operator != null) && (pcExpr != "")) && (GetExprTypes(pcExpr) == ExprTypes.String))
- {
- @operator = null;
- }
- if (@operator != null)
- {
- if (pcExpr == "")
- {
- exprObj = new ExprObject(@operator.Id, ExprElements.Operator);
- i += @operator.Symbol.Length;
- }
- flag = true;
- flag2 = false;
- }
- else if ((pcExpr == "") && (pcChar == ' '))
- {
- flag2 = false;
- }
- if (flag2)
- {
- pcExpr = pcExpr + pcChar.ToString();
- }
- if ((pcExpr != "") && ((@operator != null) || (i == (length - 1))))
- {
- ExprElements elementType = GetElementType(pcExpr);
- exprObj = new ExprObject(pcExpr, elementType);
- flag = true;
- }
- }
- if (flag)
- {
- if (i < pcString.Length)
- {
- pcString = pcString.Substring(i);
- return exprObj;
- }
- pcString = "";
- return exprObj;
- }
- }
- return null;
- }
- private static ExprOperator GetOperator(string pcString)
- {
- foreach (ExprOperator operator2 in Operators)
- {
- if (operator2.IsSymbolMatched(pcString))
- {
- return operator2;
- }
- }
- return null;
- }
- /// <summary>
- /// 构建表达式树
- /// </summary>
- /// <param name="poExprObject"></param>
- private static void CollapseSyntaxTree(ExprObject poExprObject)
- {
- int level = -1;
- int piStart = -1;
- int piLevel = 100;
- for (int i = 0; i < poExprObject.ChildCount; i++)
- {
- ExprOperator @operator = poExprObject.GetChild(i).GetOperator();
- if (i == (poExprObject.ChildCount - 1))
- {
- @operator = new ExprOperator("", "", piLevel, 0);
- i++;
- }
- if (@operator != null)
- {
- if (piLevel > @operator.Level)
- {
- piLevel = @operator.Level;
- }
- if (@operator.Level > level)
- {
- piStart = i - @operator.LeftOperands;
- }
- else if (@operator.Level < level)
- {
- CollapseSyntaxTree(poExprObject, piStart, i - 1);
- CollapseSyntaxTree(poExprObject);
- }
- level = @operator.Level;
- }
- }
- }
- /// <summary>
- /// 构建表达式树
- /// </summary>
- /// <param name="poExprObject"></param>
- /// <param name="piStart"></param>
- /// <param name="piEnd"></param>
- private static void CollapseSyntaxTree(ExprObject poExprObject, int piStart, int piEnd)
- {
- if (piEnd > piStart)
- {
- ExprObject poNode = new ExprObject("", ExprElements.Expression);
- for (int i = piStart; i <= piEnd; i++)
- {
- ExprObject child = poExprObject.GetChild(piStart);
- poExprObject.RemoveChildAt(piStart);
- poNode.AddChild(child);
- poNode.Expr = poNode.Expr + " " + child.Expr;
- }
- poExprObject.InsertChildAt(poNode, piStart);
- }
- }
- private static void CollapseFunctionCall(ExprObject poExprObject)
- {
- if (poExprObject.ChildCount > 1)
- {
- bool flag = false;
- foreach (ExprObject expr in poExprObject.ChildNodes)
- {
- if (expr.IsOperator && (expr.Expr.Trim() == ","))
- {
- flag = true;
- break;
- }
- }
- if (!flag)
- {
- ExprObject poNode = new ExprObject(poExprObject.Expr, ExprElements.Expression);
- foreach (ExprObject expr3 in poExprObject.ChildNodes)
- {
- poNode.AddChild(expr3);
- }
- poExprObject.ChildNodes.Clear();
- poExprObject.AddChild(poNode);
- }
- }
- }
- public static IdCollection Operators =>
- _operators ?? (_operators = new IdCollection
- {
- new ExprOperator("+", "+", 4, 1),
- new ExprOperator("-", "-", 4, 1),
- new ExprOperator(",", ",", 0, 0),
- new ExprOperator("and", " and ", 1, 1),
- new ExprOperator("&&", " && ", 1, 1),
- new ExprOperator("or", " or ", 1, 1),
- new ExprOperator("||", " || ", 1, 1),
- new ExprOperator("not", "not ", 2, 0),
- new ExprOperator("!", "! ", 2, 0),
- new ExprOperator("!=", "!=", 3, 1),
- new ExprOperator("=", "=", 3, 1),
- new ExprOperator(">=", ">=", 3, 1),
- new ExprOperator(">", ">", 3, 1),
- new ExprOperator("<=", "<=", 3, 1),
- new ExprOperator("<", "<", 3, 1),
- new ExprOperator("like", " like ", 3, 1),
- new ExprOperator("*", "*", 5, 1),
- new ExprOperator("/", "/", 5, 1),
- new ExprOperator("%", "%", 5, 1)
- });
- #endregion 表达式转换为ExprObject
- }
- }
|