/// <summary> /// 随机创建表达式树 /// </summary> public Tuple <Expression, List <ParameterExpression> > Create() { //参数名 Queue <string> parameterName = new Queue <string>(new string[] { "a1", "a2", "b1", "b2", "c1", "c2", "d1", "d2", "e1", "e2", "f1", "f2", "g1", "g2", "h1", "h2", "i1", "i2", "j1", "j2", "k1", "k2", "l1", "l2", "m1", "m2", "n1", "n2", "o1", "o2", "p1", "p2" }); Random random = new Random(); int layer = GetTreeLayerCount(random); //每层使用的队列 Queue <Expression>[] queue = new Queue <Expression> [layer]; for (int i = 0; i < layer; i++) { queue[i] = new Queue <Expression>(); } List <ParameterExpression> parameterList = new List <ParameterExpression>(); for (int l = layer; l >= 1; l--) //自低向上每一层 { int layerCount = (int)Math.Pow(2, l - 1); //本层的节点数 for (int i = 0; i < layerCount; i++) //每个节点 { int number = GetExpressionPartNumber(random); IExpressionPart part = parts.Where(t => t.Number == number).FirstOrDefault();//随机生成一个部件 Expression[] parameter; Expression expression; if (layer == l)//最底下一层,直接操作常量的二元运算符 { string s = parameterName.Dequeue(); var p1 = Expression.Parameter(typeof(int), s); parameterList.Add(p1); s = parameterName.Dequeue(); var p2 = Expression.Parameter(typeof(int), s); parameterList.Add(p2); parameter = new Expression[] { p1, p2 }; expression = (Activator.CreateInstance(part.GetType()) as IExpressionPart).Process(parameter); } else//操作下面一层的二元运算符的结果的表达式 { parameter = new Expression[] { queue[layer - l - 1].Dequeue(), queue[layer - l - 1].Dequeue() };//从下一层取出两个表达式 expression = (Activator.CreateInstance(part.GetType()) as IExpressionPart).Process(parameter); } queue[layer - l].Enqueue(expression); } } return(Tuple.Create(queue[layer - 1].Dequeue(), parameterList)); }
internal virtual Expression Parse(EvaluationContext context, ref string code) { if (code == null) { throw new ArgumentNullException(nameof(code)); } IList <ProcessedItem> expressionTree = new List <ProcessedItem>(); IExpressionPart current = GetObject <TParserEntry>(); code = code.TrimStart(context.Whitespaces); string source = code; while (!string.IsNullOrEmpty(code)) { bool found = false; foreach (Type partType in current.ExpectedParts) { IExpressionPart newPart = GetObject(partType); string part = newPart.Get(context, ref code); if (!string.IsNullOrEmpty(part)) { expressionTree.Add(ProcessedItem.Create(partType, part)); current = newPart; found = true; break; } } if (!found) { string dependentObjects = string.Join(", ", current.ExpectedParts.Select(o => o.Name) #if NET35 .ToArray() #endif ); throw new EvaluationException($"Invalid expression, unable to parse.\nCurrent part: {current.GetType().Name}\nFollowing parts: {dependentObjects}\n{code}") { SourceExpression = source, Position = source.Length - code.Length + 1 }; } code = code.TrimStart(context.Whitespaces); } Expression compiled = Compile(context, expressionTree); return(compiled); }