/// <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));
        }
Example #2
0
        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);
        }