public Object EvaluateEnumMethod( EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { if (target == null || target.Count < 2) { return(target); } var evaluateParams = new EvaluateParams(eventsLambda, isNewData, context); var set = new LinkedHashMap <IComparable, Object>(); var resultEvent = new ObjectArrayEventBean(new Object[1], _resultEventType); var values = target; foreach (Object next in values) { resultEvent.Properties[0] = next; eventsLambda[StreamNumLambda] = resultEvent; var comparable = (IComparable)InnerExpression.Evaluate(evaluateParams); if (!set.ContainsKey(comparable)) { set.Put(comparable, next); } } return(set.Values); }
public override BooleanExpression ToNNF() { if (InnerExpression is Negation neg) { return(neg.InnerExpression.ToNNF()); } else if (InnerExpression is NAryOperator nary) { List <BooleanExpression> newOperands = nary.GetOperands().Select(op => new Negation(op).ToNNF()).ToList(); if (nary is Disjunction) { return(new Conjunction(newOperands)); } else // nary is Conjunction { return(new Disjunction(newOperands)); } } else if (InnerExpression.Equals(FALSE)) { return(TRUE); } else if (InnerExpression.Equals(TRUE)) { return(FALSE); } else { return(new Negation(this.InnerExpression.Simplify())); } }
public override Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { if (target.IsEmpty()) { return(target); } var result = new LinkedList <Object>(); var evalEvent = new ObjectArrayEventBean(new Object[1], Type); foreach (Object next in target) { evalEvent.Properties[0] = next; eventsLambda[StreamNumLambda] = evalEvent; var pass = (bool?)InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (!pass.GetValueOrDefault(false)) { continue; } result.AddLast(next); } return(result); }
public Object EvaluateEnumMethod( EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { var beans = (ICollection <EventBean>)target; if (beans.IsEmpty() || beans.Count == 1) { return(beans); } var evaluateParams = new EvaluateParams(eventsLambda, isNewData, context); var distinct = new LinkedHashMap <IComparable, EventBean>(); foreach (var next in beans) { eventsLambda[StreamNumLambda] = next; var comparable = (IComparable)InnerExpression.Evaluate(evaluateParams); if (!distinct.ContainsKey(comparable)) { distinct.Put(comparable, next); } } return(distinct.Values); }
public Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { var result = new LinkedHashMap <object, ICollection <object> >(); var resultEvent = new ObjectArrayEventBean(new Object[1], _resultEventType); var values = target; foreach (Object next in values) { resultEvent.Properties[0] = next; eventsLambda[StreamNumLambda] = resultEvent; var key = InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); resultEvent.Properties[0] = next; var entry = _secondExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); var value = result.Get(key); if (value == null) { value = new List <object>(); result.Put(key, value); } value.Add(entry); } return(result); }
public override Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { if (target.IsEmpty()) { return(target); } var result = new LinkedList <Object>(); var indexEvent = new ObjectArrayEventBean(new Object[1], IndexEventType); int count = -1; foreach (EventBean next in target) { count++; indexEvent.Properties[0] = count; eventsLambda[StreamNumLambda] = next; eventsLambda[StreamNumLambda + 1] = indexEvent; var pass = (bool?)InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (!pass.HasValue || !pass.Value) { continue; } result.AddLast(next); } return(result); }
public Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { if (target.IsEmpty()) { return(target); } var resultEvent = new ObjectArrayEventBean(new Object[1], _resultEventType); var values = (ICollection <Object>)target; var queue = new LinkedList <object>(); foreach (Object next in values) { resultEvent.Properties[0] = next; eventsLambda[StreamNumLambda] = resultEvent; var item = InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (item != null) { queue.AddLast(item); } } return(queue); }
public object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { double sum = 0d; int count = 0; var beans = target; foreach (EventBean next in target) { eventsLambda[StreamNumLambda] = next; var num = InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (num == null) { continue; } count++; sum += num.AsDouble(); } if (count == 0) { return(null); } return(sum / count); }
public Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { var items = new LinkedHashMap <Object, int?>(); var values = target; var resultEvent = new ObjectArrayEventBean(new Object[1], _resultEventType); foreach (Object next in values) { resultEvent.Properties[0] = next; eventsLambda[StreamNumLambda] = resultEvent; var item = InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); int?existing; if (!items.TryGetValue(item, out existing)) { existing = 1; } else { existing++; } items.Put(item, existing); } return(EnumEvalMostLeastFrequentEvent.GetResult(items, _isMostFrequent)); }
public override ComputationResult Evaluate(IDataSource[] dataSources) { var inner = InnerExpression.Evaluate(dataSources); if (inner.IsValue) { return(new ComputationResult(-inner.LiteralValue)); } else if (inner.IsVectorResult) { var ret = inner.Accumulator ? inner.VectorData : inner.VectorData.CreateSimilarArray <float>(); VectorHelper.Negate(ret.GetFlatData(), inner.VectorData.GetFlatData()); return(new ComputationResult(ret, true, inner.Direction)); } else { var ret = inner.Accumulator ? inner.OdData : inner.OdData.CreateSimilarArray <float>(); var flatRet = ret.GetFlatData(); var flatInner = inner.OdData.GetFlatData(); for (int i = 0; i < flatRet.Length; i++) { VectorHelper.Negate(flatRet[i], flatInner[i]); } return(new ComputationResult(ret, true)); } }
public override void InitBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { innerValue = InnerExpression.EvaluateCodegen(typeof(bool?), methodNode, scope, codegenClassScope); EnumTakeWhileHelper.InitBlockSizeOneScalar(numParameters, block, innerValue, InnerExpression.EvaluationType); block.DeclareVar( typeof(object[]), "all", StaticMethod(typeof(EnumTakeWhileHelper), "TakeWhileLastScalarToArray", EnumForgeCodegenNames.REF_ENUMCOLL)); var forEach = block.ForLoop( typeof(int), "i", Op(ArrayLength(Ref("all")), "-", Constant(1)), Relational(Ref("i"), GE, Constant(0)), DecrementRef("i")) .AssignArrayElement("props", Constant(0), ArrayAtIndex(Ref("all"), Ref("i"))); if (numParameters >= 2) { forEach.IncrementRef("count") .AssignArrayElement("props", Constant(1), Ref("count")); } CodegenLegoBooleanExpression.CodegenBreakIfNotNullAndNotPass(forEach, InnerExpression.EvaluationType, innerValue); forEach.Expression(ExprDotMethod(Ref("result"), "AddFirst", ArrayAtIndex(Ref("all"), Ref("i")))); }
public Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { double sum = 0d; int count = 0; var resultEvent = new ObjectArrayEventBean(new Object[1], _resultEventType); ICollection <object> values = target; foreach (object next in values) { resultEvent.Properties[0] = next; eventsLambda[StreamNumLambda] = resultEvent; object num = InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (num == null) { continue; } count++; sum += num.AsDouble(); } if (count == 0) { return(null); } return(sum / count); }
protected override string GetStringForm() { if (InnerExpression != null) { return(string.Format("({0})", InnerExpression.ToString())); } return(null); }
protected override void AttachCore() { InnerExpression.Attach(); foreach (var binding in MemberBindings) { binding.Attach(); } }
internal override bool Is_DNF_Helper(bool seenNegation, bool seenDisjunction, bool seenConjunction) { if (seenNegation) { return(false); } return(InnerExpression.Is_DNF_Helper(true, seenDisjunction, seenConjunction)); }
public override Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { if (target.IsEmpty()) { return(target); } var evalEvent = new ObjectArrayEventBean(new Object[1], EvalEventType); var indexEvent = new ObjectArrayEventBean(new Object[1], IndexEventType); if (target.Count == 1) { Object item = target.First(); evalEvent.Properties[0] = item; eventsLambda[StreamNumLambda] = evalEvent; indexEvent.Properties[0] = 0; eventsLambda[StreamNumLambda + 1] = indexEvent; var pass = (bool?)InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (!pass.GetValueOrDefault(false)) { return(Collections.GetEmptyList <object>()); } return(Collections.SingletonList(item)); } var size = target.Count; var all = new Object[size]; var count = 0; foreach (Object item in target) { all[count++] = item; } var result = new LinkedList <Object>(); int index = 0; for (int i = all.Length - 1; i >= 0; i--) { evalEvent.Properties[0] = all[i]; eventsLambda[StreamNumLambda] = evalEvent; indexEvent.Properties[0] = index++; eventsLambda[StreamNumLambda + 1] = indexEvent; var pass = (bool?)InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); if (!pass.GetValueOrDefault(false)) { break; } result.AddFirst(all[i]); } return(result); }
public override void InitBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { innerValue = InnerExpression.EvaluateCodegen(typeof(bool?), methodNode, scope, codegenClassScope); EnumTakeWhileHelper.InitBlockSizeOneEventPlus(numParameters, block, innerValue, StreamNumLambda, InnerExpression.EvaluationType); }
internal override bool OptimizeAst(ref Expression ex, ref string error) { if (!InnerExpression.OptimizeAst(ref ex, ref error)) { return(false); } ex = InnerExpression; return(true); }
public void Accept(Visitor.VisitorBase visitor) { if (visitor.VisitEnter(this)) { visitor.Visit(this); InnerExpression.Accept(visitor); } visitor.VisitLeave(this); }
public override void ForEachBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { block.DeclareVar <object>("key", InnerExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .DeclareVar <object>("value", SecondExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .Expression(ExprDotMethod(Ref("map"), "Put", Ref("key"), Ref("value"))); }
public override void ForEachBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { block.DeclareVar <object>("item", InnerExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .IfCondition(NotEqualsNull(Ref("item"))) .Expression(ExprDotMethod(Ref("result"), "Add", Ref("item"))); }
public override void ForEachBlock(CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { block.DeclareVar <object>("key", InnerExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .DeclareVar <ICollection <object> >("value", Cast(typeof(ICollection <object>), ExprDotMethod(Ref("result"), "Get", Ref("key")))) .IfRefNull("value") .AssignRef("value", NewInstance(typeof(List <object>))) .Expression(ExprDotMethod(Ref("result"), "Put", Ref("key"), Ref("value"))) .BlockEnd() .Expression(ExprDotMethod(Ref("value"), "Add", ExprDotUnderlying(Ref("next")))); }
public override void ForEachBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { block .DeclareVar <object>("item", InnerExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .AssignArrayElement(Ref("result"), Ref("count"), FlexCast(_arrayComponentType, Ref("item"))); }
public override void ForEachBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { CodegenExpression eval = InnerExpression.EvaluateCodegen(_innerType, methodNode, scope, codegenClassScope); EnumDistinctOfHelper.ForEachBlock(block, eval, _innerType); }
public override CodegenExpression Codegen( EnumForgeCodegenParams premade, CodegenMethodScope codegenMethodScope, CodegenClassScope codegenClassScope) { var resultTypeMember = codegenClassScope.AddDefaultFieldUnshared( true, typeof(ObjectArrayEventType), Cast(typeof(ObjectArrayEventType), EventTypeUtility.ResolveTypeCodegen(_resultEventType, EPStatementInitServicesConstants.REF))); var scope = new ExprForgeCodegenSymbol(false, null); var methodNode = codegenMethodScope .MakeChildWithScope(typeof(IDictionary <object, object>), typeof(EnumToMapScalar), scope, codegenClassScope) .AddParam(EnumForgeCodegenNames.PARAMS); var hasIndex = _numParameters >= 2; var hasSize = _numParameters >= 3; var block = methodNode.Block .IfCondition(ExprDotMethod(EnumForgeCodegenNames.REF_ENUMCOLL, "IsEmpty")) .BlockReturn(EnumValue(typeof(EmptyDictionary <object, object>), "Instance")); block.DeclareVar <IDictionary <object, object> >("map", NewInstance(typeof(NullableDictionary <object, object>))) .DeclareVar( typeof(ObjectArrayEventBean), "resultEvent", NewInstance(typeof(ObjectArrayEventBean), NewArrayByLength(typeof(object), Constant(_numParameters)), resultTypeMember)) .AssignArrayElement(EnumForgeCodegenNames.REF_EPS, Constant(StreamNumLambda), Ref("resultEvent")) .DeclareVar <object[]>("props", ExprDotName(Ref("resultEvent"), "Properties")); if (hasIndex) { block.DeclareVar <int>("count", Constant(-1)); } if (hasSize) { block.AssignArrayElement(Ref("props"), Constant(2), ExprDotName(REF_ENUMCOLL, "Count")); } var forEach = block .ForEach(typeof(object), "next", EnumForgeCodegenNames.REF_ENUMCOLL) .AssignArrayElement("props", Constant(0), Ref("next")); if (hasIndex) { forEach.IncrementRef("count").AssignArrayElement("props", Constant(1), Ref("count")); } forEach .DeclareVar <object>("key", InnerExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .DeclareVar <object>("value", _secondExpression.EvaluateCodegen(typeof(object), methodNode, scope, codegenClassScope)) .Expression(ExprDotMethod(Ref("map"), "Put", Ref("key"), Ref("value"))); block.MethodReturn(Ref("map")); return(LocalMethod(methodNode, premade.Eps, premade.Enumcoll, premade.IsNewData, premade.ExprCtx)); }
public override void ForEachBlock(CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { var innerType = InnerExpression.EvaluationType; block.DeclareVar(innerType, "value", InnerExpression.EvaluateCodegen(innerType, methodNode, scope, codegenClassScope)); if (!innerType.IsPrimitive) { block.IfRefNull("value").BlockContinue(); } sumMethodFactory.CodegenEnterNumberTypedNonNull(block, Ref("value")); }
internal override bool Is_NNF_Helper(bool seenNegation) { if (seenNegation) { // no double negation allowed in nnf return(false); } else { return(InnerExpression.Is_NNF_Helper(true)); } }
public override void ForEachBlock( CodegenBlock block, CodegenMethod methodNode, ExprForgeCodegenSymbol scope, CodegenClassScope codegenClassScope) { CodegenLegoBooleanExpression.CodegenContinueIfNotNullAndNotPass( block, InnerExpression.EvaluationType, InnerExpression.EvaluateCodegen(typeof(bool?), methodNode, scope, codegenClassScope)); block.BlockReturn(Ref("next")); }
public Object EvaluateEnumMethod(EventBean[] eventsLambda, ICollection <object> target, bool isNewData, ExprEvaluatorContext context) { var method = _sumMethodFactory.SumAggregator; foreach (EventBean next in target) { eventsLambda[StreamNumLambda] = next; var value = InnerExpression.Evaluate(new EvaluateParams(eventsLambda, isNewData, context)); method.Enter(value); } return(method.Value); }
public override BooleanExpression Simplify() { var newInnerExpression = InnerExpression.Simplify(); if (newInnerExpression.Equals(FALSE)) { return(TRUE); } if (newInnerExpression.Equals(TRUE)) { return(FALSE); } return(new Negation(InnerExpression.Simplify())); }
/// <summary> /// 获取改参数的真实值 /// </summary> public object GetValue() { //Util.Debug(false, "Get Param Value:[" + this.ParamDefine + "] Is Fun:" + IsFunction.ToString()); if (this.ParamDefine == null) return null; if (IsExpression == true) { InnerExpression exp = new InnerExpression(this.ParamDefine, GetResourceDependency()); return exp.GetValue(); } else if (IsFunction == true) { int idx = this.ParamDefine.IndexOf('('); string funName = (idx == 0) ? null : this.ParamDefine.Substring(0, idx); //Util.Debug(false, this.ParamDefine.Substring(idx + 1).TrimEnd(')')); InnerFunction fun = new InnerFunction(funName, this.ParamDefine.Substring(idx+1).TrimEnd(')'), this.GetResourceDependency()); return fun.Execute(); } else { #region 字符型 if (this.ParamDefine.StartsWith("\"") && this.ParamDefine.EndsWith("\"")) { return this.ParamDefine.Trim('"'); } else if (this.ParamDefine.StartsWith("'") && this.ParamDefine.EndsWith("'")) { return this.ParamDefine.Trim('\''); } #endregion if (this.ParamDefine.StartsWith("%") && this.ParamDefine.EndsWith("%")) { #region 已定义资源数据 string define = string.Concat("{#", this.ParamDefine, "#}"); if (this.Res != null && Res.IsDefined(define)) { return Res.GetDefinition(define); } else { return ""; } #endregion } else if (this.ParamDefine.StartsWith("$") && this.ParamDefine.EndsWith("$")) { #region 系统标签 SystemTag sysTag = new SystemTag(string.Concat("{#", this.ParamDefine, "#}")); sysTag.SetResourceDependency(GetResourceDependency()); return sysTag.ToString(); #endregion } else { #region 布尔及数字型 if (string.Compare(this.ParamDefine, "true", true) == 0) { return true; } else if (string.Compare(this.ParamDefine, "false", true) == 0) { return false; } else { if (Regex.IsMatch(this.ParamDefine, @"^[\d,]+$", RegexOptions.Compiled)) { try { double dec = double.Parse(this.ParamDefine); return dec; } catch (Exception) { return 0; } } else { return this.ParamDefine; } } #endregion } } }
/// <summary> /// 转换描述文本为表达式数组 /// </summary> /// <remarks> /// a: {#$ TrimHTML(%Title%) $#} /// b: {#$ Repeat(5,%Title%) $#} /// c: {#$ Length(TrimHTML(%Title%)) $#} /// d: {#$ Length(TrimHTML(%Title%)) > 3 ? "太长" : "OK" $#} /// e: {#$ Replace(TrimHTML(%Title%), "电子"," ") $#} /// f: {#$ ReplaceX(TrimHTML(%Title%), "\w","") $#} /// </remarks> public static List<InnerExpression> GetInnerExpressions(string ExpPaper, IResourceDependency Res) { //OleDbHelper.AppendToFile("~/debug.txt", "\n\n 解析:" + ExpPaper); List<InnerExpression> expList = new List<InnerExpression>(); int lenT = ExpPaper.Length; int cursor = 0, iflag = 0; char chr = ExpPaper[cursor]; string strTemp = "", strExpression = ""; ReservedWords words = null; while (cursor < lenT) { #region 字符扫描 chr = ExpPaper[cursor]; if (!ReservedWords.IsReservedChar(chr)) { ++cursor; continue; } else { if (cursor > iflag) { strTemp = ExpPaper.Substring(iflag, cursor - iflag).Trim(); } iflag = cursor; words = new ReservedWords(chr); if (words.IsBraceChar()) { #region 配对字符解析 ReservedWords.MoveToCharBrace(chr, ReservedWords.GetBraceChar(chr), ref cursor, ref ExpPaper); if (chr == '(') { //Function strExpression = ExpPaper.Substring(iflag + 1, cursor - iflag - 1); //OleDbHelper.AppendToFile("~/debug.txt", "\n 函数体:" + strExpression); if (strTemp.Length == 0) strTemp = null; expList.Add(new InnerExpression(strTemp, strExpression, Res)); } else if (chr == '?') { strExpression = ExpPaper.Substring(iflag + 1, cursor - iflag - 1).Trim(); #region 跳出双引号里面的 : 操作符号 if (strExpression.IndexOf('"') != -1 && strExpression[0] != '"') { ReservedWords.MoveToCharBrace('"', '"', ref cursor, ref ExpPaper); ReservedWords.MoveToCharBrace(ExpPaper[cursor], ':', ref cursor, ref ExpPaper); strExpression = ExpPaper.Substring(iflag + 1, cursor - iflag - 1).Trim(); } #endregion #region 跳出单引号里面的 : 操作符号 if (strExpression.IndexOf('\'') != -1 && strExpression[0] != '\'') { ReservedWords.MoveToCharBrace('\'', '\'', ref cursor, ref ExpPaper); ReservedWords.MoveToCharBrace(ExpPaper[cursor], ':', ref cursor, ref ExpPaper); strExpression = ExpPaper.Substring(iflag + 1, cursor - iflag - 1).Trim(); } #endregion if (strTemp.Length > 0) { expList.Add(new InnerExpression(strTemp)); } expList.Add(new InnerExpression("?")); expList.Add(new InnerExpression(strExpression)); expList.Add(new InnerExpression(":")); //Util.Debug(false, ExpPaper.Substring(cursor)); } else if (chr == '[') { // {#$["首页","新闻","动态","联系"][2]$#} = "动态" #region 数组情况 if (cursor < lenT - 1) { char aIdx = ExpPaper[cursor + 1]; while (aIdx == '[') { cursor++; ReservedWords.MoveToCharBrace(aIdx, ReservedWords.GetBraceChar(aIdx), ref cursor, ref ExpPaper); if (cursor < (lenT - 1)) { aIdx = ExpPaper[cursor + 1]; } else { break; } } strExpression = ExpPaper.Substring(iflag, cursor - iflag + 1); expList.Add(new InnerExpression(strExpression, ',', Res)); } else { #region 获取数组下标操作TODO strExpression = ExpPaper.Substring(iflag, cursor - iflag + 1); expList.Add(new InnerExpression(strExpression, Res)); #endregion } #endregion } else if (chr == '$') { #region 内置系统标签 strExpression = ExpPaper.Substring(iflag, cursor - iflag + 1); SystemTag sysTag = new SystemTag(string.Concat("{#", strExpression, "#}")); sysTag.SetResourceDependency(Res); //OleDbHelper.AppendToFile("~/debug.log", System.Environment.NewLine + string.Concat("{#", strExpression, "#}", "\n", sysTag.ToString())); expList.Add(new InnerExpression(sysTag.ToString())); #endregion } else if (chr == '"' || chr == '\'') { strExpression = ExpPaper.Substring(iflag, cursor - iflag + 1); //Util.Debug(false, "Find String:" + strExpression); expList.Add(new InnerExpression(strExpression)); } #endregion iflag = cursor + 1; } else if (words.IsOperator()) { strExpression = strTemp; if (strExpression.Length > 0) { InnerExpression exp = new InnerExpression(strExpression); expList.Add(exp); } #region 处理操作符号 ParseOperator: char chrNext = ExpPaper[cursor + 1]; if ((chr == '+' || chr == '-') && char.IsNumber(chrNext)) { #region 正负号处理 ++cursor; if (cursor < lenT) { ReservedWords.MoveToCharInRange(ref cursor, ref ExpPaper, ' ', '*', '/', '%', '+', '-', '>', '<', '=', '!', '&', '^', '|'); expList.Add(new InnerExpression(ExpPaper.Substring(iflag, cursor - iflag))); #region 如遇操作符 if (cursor < lenT && ExpPaper[cursor] != ' ') { iflag = cursor; chr = ExpPaper[cursor]; //Util.Debug(false, "new char: = [" + chr.ToString() + "]"); goto ParseOperator; } #endregion } #endregion } else { // *= += -= ++ -- <> if (ReservedWords.IsCharInRange(chrNext, '=', '+', '-', '>')) { expList.Add(new InnerExpression(chr.ToString() + chrNext.ToString())); ++cursor; } else { expList.Add(new InnerExpression(chr.ToString())); } } #endregion iflag = cursor + 1; } else { if (strTemp.Length > 0) { expList.Add(new InnerExpression(strTemp)); } //Util.Debug(false, "11 - [" + strTemp.Trim() + "]" + "chr=[" + chr.ToString() + "]"); } } ++cursor; #endregion } if (iflag < cursor) { expList.Add(new InnerExpression(ExpPaper.Substring(iflag, cursor - iflag).Trim())); } //#region 解析结果查看 //foreach (InnerExpression ext in expList) //{ // //Util.Debug(false, string.Concat("Exp定义:", ext.TagDefinition)); // OleDbHelper.AppendToFile("~/debug.log", System.Environment.NewLine + string.Concat("Exp定义:", ext.TagDefinition)); //} //#endregion return expList; }
/// <summary> /// 计算一个表达式的值 /// </summary> /// <param name="exp">The exp.</param> /// <param name="op">The op.</param> /// <returns></returns> public static object ComputeOne(InnerExpression exp, InnerOperate op) { //"!", "~", "++", "--", "true", "false" object oRet = exp.GetValue(); if (op.OperatorDefine == "!") { return !(Convert.ToBoolean(oRet)); } else if (op.OperatorDefine == "~") { return ~Convert.ToChar(oRet); } else if (op.OperatorDefine == "++" || op.OperatorDefine == "--") { if (!Regex.IsMatch(oRet.ToString(), @"^(\+|\-)?[\d\.]+$", RegexOptions.Compiled)) { throw new InvalidOperationException("数据不支持自增/减运算!"); } else { double odb = double.Parse(oRet.ToString()); return (op.OperatorDefine == "++") ? odb++ : odb--; } } return oRet; }
/// <summary> /// 计算两个表达式的值 /// </summary> public static object ComputeTwo(InnerExpression lExp, InnerOperate op, InnerExpression rExp) { object oRet = ""; object lValue = lExp.GetValue(); object rValue = rExp.GetValue(); //OleDbHelper.AppendToFile("~/debug.txt", "\n" + "Left:" + lValue.GetType().ToString() // + " Right:" + rValue.GetType().ToString()); //Util.Debug(false, lValue.GetType(), rValue.GetType()); //return ""; if (lValue.GetType() != rValue.GetType()) { try { rValue = Convert.ChangeType(rValue, lValue.GetType()); } catch (Exception) { throw new InvalidOperationException(string.Format("{0}与{1}不支持运算,且类型不兼容!", lValue, rValue)); } } string opDef = op.OperatorDefine; #region 处理比较操作 if (ReservedWords.IsStringInRange(opDef, ">", "<", ">=", "<=", "!=", "==", "<>")) { if (!(lValue is IComparable) || !(rValue is IComparable)) { throw new InvalidOperationException(string.Format("{0}与{1}不支持比较!", lValue, rValue)); } IComparable ica = lValue as IComparable; IComparable icb = rValue as IComparable; switch (opDef) { case ">": oRet = (ica.CompareTo(icb) > 0); break; case "<": oRet = (ica.CompareTo(icb) < 0); break; case ">=": oRet = (ica.CompareTo(icb) >= 0); break; case "<=": oRet = (ica.CompareTo(icb) <= 0); break; case "!=": oRet = (ica.CompareTo(icb) != 0); break; case "<>": oRet = (ica.CompareTo(icb) != 0); break; case "==": oRet = (ica.CompareTo(icb) == 0); break; default: break; } } #endregion #region 双目基本运算 if (ReservedWords.IsStringInRange(opDef, "*", "/", "%", "+", "-")) { if (lValue.GetType() == typeof(string)) { #region 字符型 if (op.OperatorDefine == "+") { oRet = String.Concat(lValue.ToString(), rValue.ToString()); } else { oRet = lValue.ToString().Replace(rValue.ToString(), ""); } #endregion } else { #region 数字型 double dba = Convert.ToDouble(lValue); double dbb = Convert.ToDouble(rValue); switch (opDef) { case "*": oRet = (dba * dbb); break; case "/": oRet = (dba / dbb); break; case "%": oRet = (dba % dbb); break; case "+": oRet = (dba + dbb); break; case "-": oRet = (dba - dbb); break; default: break; } #endregion } } #endregion //return string.Format("{0}{1}{2}", lExp.GetValue(), op.OperatorDefine , rExp.GetValue()); return oRet; }
/// <summary> /// 计算表达式 /// </summary> public static object ExecExpressions(List<InnerExpression> exps) { if (exps.Count == 0) return ""; while (exps.Count > 1) { List<int> priIdxes = GetMaxPriorityExpIndexes(exps); int total = exps.Count; int offSet = 0, cIdx = 0; InnerExpression tempExp = null; InnerOperate op = null; if (priIdxes.Count == 0) { #region 没有操作符号的数学运算 while (exps.Count >= 2) { tempExp = new InnerExpression(); if (Regex.IsMatch(exps[1].TagDefinition, InnerExpression.ArrayIndexFetchPattern, RegexOptions.Compiled)) { #region 数组下标直接获取 "ab"[0] = "a" string strExpValue = exps[0].GetValue().ToString(); int arrIdx = Convert.ToInt32(exps[1].TagDefinition.Trim('[', ']')); tempExp.TagDefinition = (arrIdx < strExpValue.Length) ? strExpValue[arrIdx].ToString() : strExpValue; tempExp.IsString = true; #endregion } else { tempExp.TagDefinition = InnerExpression.ComputeTwo(exps[0], new InnerOperate("+"), exps[1]).ToString(); tempExp.IsString = exps[0].IsString; } tempExp.IsEntity = true; exps[0] = tempExp; exps.RemoveAt(1); } #endregion } else { #region 处理同级运算 foreach (int idx in priIdxes) { cIdx = idx + offSet; //Util.Debug(false, cIdx); op = new InnerOperate(exps[cIdx].GetValue().ToString()); if (op.IsUnary()) { #region 一元 自增/减操作 直接运算 // ++i if ((idx + 1) < total) { tempExp = new InnerExpression(); tempExp.TagDefinition = InnerExpression.ComputeOne(exps[cIdx + 1], op).ToString(); tempExp.IsEntity = true; exps[cIdx + 1] = tempExp; exps.RemoveAt(cIdx); offSet -= 1; } else { //i++ if (idx > 0) { tempExp = new InnerExpression(); tempExp.TagDefinition = InnerExpression.ComputeOne(exps[cIdx - 1], op).ToString(); tempExp.IsEntity = true; exps[cIdx - 1] = tempExp; exps.RemoveAt(cIdx); offSet -= 1; } } #endregion } else if (op.IsTernary()) { //最低优先级 ? a : b #region 三目条件运算符 if (idx + 3 < total) { tempExp = new InnerExpression(); tempExp.TagDefinition = (Convert.ToBoolean(exps[cIdx - 1].GetValue()) ? exps[cIdx + 1].GetValue() : exps[cIdx + 3].GetValue()).ToString(); tempExp.IsEntity = true; exps[cIdx - 1] = tempExp; exps.RemoveAt(cIdx); exps.RemoveAt(cIdx); exps.RemoveAt(cIdx); exps.RemoveAt(cIdx); offSet -= 4; } #endregion } else { #region 双目运算 if (exps.Count >= 3) { tempExp = new InnerExpression(); tempExp.TagDefinition = InnerExpression.ComputeTwo(exps[cIdx - 1], op, exps[cIdx + 1]).ToString(); tempExp.IsString = exps[cIdx - 1].IsString; tempExp.IsEntity = true; exps[cIdx - 1] = tempExp; exps.RemoveAt(cIdx); exps.RemoveAt(cIdx); offSet -= 2; } else { //无效运算操作 exps.RemoveAt(cIdx); offSet -= 1; } #endregion } } #endregion } //Util.Debug(false, "当前还剩余:" + exps.Count.ToString()); //foreach (InnerExpression tex in exps) //{ // Util.Debug(false, tex.GetValue()); //} } return exps[0].GetValue(); }