Exemple #1
0
        private static double Calculate(ExpressionOperand root, Dictionary <string, double> varValues)
        {
            if (root.IsConstant)
            {
                return(root.ConstantValue);
            }
            if (root.IsVariable)
            {
                double result;
                if (!varValues.TryGetValue(root.VariableName, out result))
                {
                    throw new Exception(string.Format("Переменная \"{0}\" не определена", root.VariableName));
                }
                return(result);
            }
            var valLeft  = root.OperandLeft == null ? 0 : Calculate(root.OperandLeft, varValues);
            var valRight = root.OperandRight == null ? 0 : Calculate(root.OperandRight, varValues);

            return(CalculateOperator(root.Operator, valLeft, valRight));
        }
Exemple #2
0
 private static void GetVariableNames(ExpressionOperand root, List <string> vars)
 {
     if (root == null)
     {
         return;
     }
     if (root.IsVariable)
     {
         vars.Add(root.VariableName);
     }
     else
     {
         if (root.OperandLeft != null)
         {
             GetVariableNames(root.OperandLeft, vars);
         }
         if (root.OperandRight != null)
         {
             GetVariableNames(root.OperandRight, vars);
         }
     }
 }
Exemple #3
0
        private static void BuildOperandTree(ref ExpressionOperand root, string formula, List <ExpressionOperatorEntry> operators)
        {
            if (string.IsNullOrEmpty(formula))
            {
                throw new ArgumentException("BuildOperandTree() - formula пуста", "formula");
            }
            // освободить формулу от обрамляющих скобок, если имеются
            while (true)
            {
                if (HasRedundantBraces(formula))
                {
                    formula = formula.Substring(1, formula.Length - 2);
                    foreach (var op in operators)
                    {
                        op.start -= 1;
                        op.end   -= 1;
                    }
                }
                else
                {
                    break;
                }
            }
            if (string.IsNullOrEmpty(formula))
            {
                throw new ArgumentException("BuildOperandTree() - formula пуста", "formula");
            }

            if (operators.Count == 0)
            {// либо константа, либо - переменная
                var constVal = formula.ToDoubleUniformSafe();
                if (constVal.HasValue)
                {
                    root = new ExpressionOperand {
                        IsConstant = true, ConstantValue = constVal.Value
                    };
                    return;
                }
                // будем считать переменной
                root = new ExpressionOperand {
                    IsVariable = true, VariableName = formula
                };
                return;
            }

            root = new ExpressionOperand();

            // найти самый низко-приоритетный оператор
            var minPrior  = operators.Min(op => op.priority);
            var firstOper = operators.Last(op => op.priority == minPrior);

            root.Operator = firstOper.oper;

            // получить левый и правый (если есть) операнды
            // есть левый операнд
            if (firstOper.start > 0)
            {
                var leftOpers = new List <ExpressionOperatorEntry>();
                foreach (var op in operators)
                {
                    if (op.start >= firstOper.start)
                    {
                        continue;
                    }
                    leftOpers.Add(new ExpressionOperatorEntry(op.oper, op.start, op.end)
                    {
                        priority = op.priority
                    });
                }
                var partLeft = formula.Substring(0, firstOper.start);
                ExpressionOperand leftRoot = null;
                BuildOperandTree(ref leftRoot, partLeft, leftOpers);
                root.OperandLeft = leftRoot;
            }
            // есть правый операнд
            if (firstOper.end < formula.Length)
            {
                var rightOpers = new List <ExpressionOperatorEntry>();
                foreach (var op in operators)
                {
                    if (op.start <= firstOper.start)
                    {
                        continue;
                    }
                    rightOpers.Add(new ExpressionOperatorEntry(op.oper, op.start - firstOper.end,
                                                               op.end - firstOper.end)
                    {
                        priority = op.priority
                    });
                }
                var partRight = formula.Substring(firstOper.end);
                ExpressionOperand rightRoot = null;
                BuildOperandTree(ref rightRoot, partRight, rightOpers);
                root.OperandRight = rightRoot;
            }
        }
        private static bool ParseSimpleFormulaBranch(ExpressionOperand root,
                                                     List<Cortege3<PerformerStatField, ExpressionOperator, double>> filters)
        {
            if (root.Operator == ExpressionOperator.And)
            {
                if (root.OperandLeft.IsConstant || root.OperandLeft.IsConstant) return false;
                if (root.OperandRight.IsConstant || root.OperandRight.IsConstant) return false;
                if (!ParseSimpleFormulaBranch(root.OperandLeft, filters)) return false;
                if (!ParseSimpleFormulaBranch(root.OperandRight, filters)) return false;
                return true;
            }
            if (root.Operator == ExpressionOperator.Greater ||
                root.Operator == ExpressionOperator.Lower ||
                root.Operator == ExpressionOperator.Equal)
            {
                if (!root.OperandLeft.IsVariable) return false;
                if (!root.OperandRight.IsConstant) return false;

                var field = fields.FirstOrDefault(f => f.ExpressionParamName != null &&
                    f.ExpressionParamName.Equals(root.OperandLeft.VariableName, StringComparison.OrdinalIgnoreCase));
                if (field == null) return false;

                filters.Add(new Cortege3<PerformerStatField, ExpressionOperator, double>(field, root.Operator, root.OperandRight.ConstantValue));
                return true;
            }

            return false;
        }
        private static void BuildOperandTree(ref ExpressionOperand root, string formula, List<ExpressionOperatorEntry> operators)
        {
            if (string.IsNullOrEmpty(formula))
                throw new ArgumentException("BuildOperandTree() - formula пуста", "formula");
            // освободить формулу от обрамляющих скобок, если имеются
            while (true)
            {
                if (HasRedundantBraces(formula))
                {
                    formula = formula.Substring(1, formula.Length - 2);
                    foreach (var op in operators)
                    {
                        op.start -= 1;
                        op.end -= 1;
                    }
                }
                else break;
            }
            if (string.IsNullOrEmpty(formula))
                throw new ArgumentException("BuildOperandTree() - formula пуста", "formula");

            if (operators.Count == 0)
            {// либо константа, либо - переменная
                var constVal = formula.ToDoubleUniformSafe();
                if (constVal.HasValue)
                {
                    root = new ExpressionOperand { IsConstant = true, ConstantValue = constVal.Value };
                    return;
                }
                // будем считать переменной
                root = new ExpressionOperand { IsVariable = true, VariableName = formula };
                return;
            }

            root = new ExpressionOperand();

            // найти самый низко-приоритетный оператор
            var minPrior = operators.Min(op => op.priority);
            var firstOper = operators.Last(op => op.priority == minPrior);
            root.Operator = firstOper.oper;

            // получить левый и правый (если есть) операнды
            // есть левый операнд
            if (firstOper.start > 0)
            {
                var leftOpers = new List<ExpressionOperatorEntry>();
                foreach (var op in operators)
                {
                    if (op.start >= firstOper.start) continue;
                    leftOpers.Add(new ExpressionOperatorEntry(op.oper, op.start, op.end) { priority = op.priority });
                }
                var partLeft = formula.Substring(0, firstOper.start);
                ExpressionOperand leftRoot = null;
                BuildOperandTree(ref leftRoot, partLeft, leftOpers);
                root.OperandLeft = leftRoot;
            }
            // есть правый операнд
            if (firstOper.end < formula.Length)
            {
                var rightOpers = new List<ExpressionOperatorEntry>();
                foreach (var op in operators)
                {
                    if (op.start <= firstOper.start) continue;
                    rightOpers.Add(new ExpressionOperatorEntry(op.oper, op.start - firstOper.end,
                        op.end - firstOper.end) { priority = op.priority });
                }
                var partRight = formula.Substring(firstOper.end);
                ExpressionOperand rightRoot = null;
                BuildOperandTree(ref rightRoot, partRight, rightOpers);
                root.OperandRight = rightRoot;
            }
        }
 private static double Calculate(ExpressionOperand root, Dictionary<string, double> varValues)
 {
     if (root.IsConstant) return root.ConstantValue;
     if (root.IsVariable)
     {
         double result;
         if (!varValues.TryGetValue(root.VariableName, out result))
             throw new Exception(string.Format("Переменная \"{0}\" не определена", root.VariableName));
         return result;
     }
     var valLeft = root.OperandLeft == null ? 0 : Calculate(root.OperandLeft, varValues);
     var valRight = root.OperandRight == null ? 0 : Calculate(root.OperandRight, varValues);
     return CalculateOperator(root.Operator, valLeft, valRight);
 }
 private static void GetVariableNames(ExpressionOperand root, List<string> vars)
 {
     if (root == null) return;
     if (root.IsVariable) vars.Add(root.VariableName);
     else
     {
         if (root.OperandLeft != null)
             GetVariableNames(root.OperandLeft, vars);
         if (root.OperandRight != null)
             GetVariableNames(root.OperandRight, vars);
     }
 }