コード例 #1
0
 private Expression ParseEquationNoFunctions(string equation)
 {
     while (equation.IndexOf('(') != -1)                                                    //While there are still grouping symbols
     {
         var subEquation = GetSubExpression(equation.Substring(equation.IndexOf('(') + 1)); //Skip '('
         subExpressions.Add(ParseEquationNoFunctions(subEquation));
         equation = equation.Replace("(" + subEquation + ")", "{" + (subExpressions.Count - 1).ToString() + "}");
     }
     CreateExpressions(ref equation, '^');
     CreateExpressions(ref equation, '*', '/');
     CreateExpressions(ref equation, '-', '+');
     using (TypeTextReader reader = new TypeTextReader(new StringReader(equation.Substring(1))))
     {
         var expressionID = (int)reader.ReadInt64();
         return(subExpressions[expressionID]);
     }
 }
コード例 #2
0
        /// <summary>
        /// Parses a function as a string into an expression tree.
        /// </summary>
        /// <param name="function">The string to parse.</param>
        /// <returns>The expression tree representing the function.</returns>
        public Expression <Func <double, double> > ParseFunctionAsExpressionTree(string function)
        {
            function = Regex.Replace(function, @"({|\[)", "(");//Replace all non-paren grouping symbols with parens
            function = Regex.Replace(function, @"(}|\])", ")");
            function = Regex.Replace(function, @"\s", "");
            subExpressions.Clear();
            subExpressions.Add(x);
            subExpressions.Add(Expression.Constant(Math.E));
            subExpressions.Add(Expression.Constant(Math.PI));
            function = function.Replace(nameof(x), "{0}");
            function = function.Replace("e", "{1}");
            function = function.Replace("pi", "{2}");
            function = Regex.Replace(function, @"(?<number>[0-9]+){", @"${number}*{"); // Handles expressions such as 5x and changes it to 5 * x
            if (function[0] == '-')
            {
                if (function[1] != '{') // If we are not negating a subexpression
                {
                    using (TypeTextReader reader = new TypeTextReader(new StringReader(function.Substring(1))))
                    {
                        var val    = reader.ReadDouble();
                        var exprID = subExpressions.Count;
                        subExpressions.Add(Expression.Constant(-val));
                        var length = function.Length - reader.BaseReader.ReadToEnd().Length;
                        function = function.Replace(function.Substring(0, length), "{" + exprID + "}");
                    }
                }
                else
                {
                    using (TypeTextReader reader = new TypeTextReader(new StringReader(function.Substring(1))))
                    {
                        var subExprId = (int)reader.ReadInt64();
                        var exprID    = subExpressions.Count;
                        subExpressions.Add(Expression.Negate(subExpressions[subExprId]));
                        var length = function.Length - reader.BaseReader.ReadToEnd().Length;
                        function = function.Replace(function.Substring(0, length), "{" + exprID + "}");
                    }
                }
            }
            var lambda = Expression.Lambda <Func <double, double> >(ParseEquation(function), x);

            return(lambda);
        }
コード例 #3
0
        private void CreateExpressions(ref string equation, params char[] operations)
        {
            var index = 0;

            while ((index = equation.IndexOfAny(operations)) != -1)// While one of the operations can still be performed
            {
                var        previous = equation[index - 1];
                Expression left, right;
                int        startPlaceholder, endPlaceholder;
                if (previous == '}')
                {
                    var openingIndex = equation.Substring(0, index).LastIndexOf('{');
                    var exprID       = Int32.Parse(equation.Substring(openingIndex + 1, (index - 1) - (openingIndex + 1)));
                    left             = subExpressions[exprID];
                    startPlaceholder = openingIndex;
                }
                else
                {
                    var substr      = new string(equation.Substring(0, index).Reverse().ToArray());
                    var leftVal     = Double.NaN;
                    var leftBuilder = new StringBuilder();
                    using (StringReader reader = new StringReader(substr))
                    {
                        var val = 0;
                        while ((val = reader.Read()) != -1)
                        {
                            var ch = (char)val;
                            if (Char.IsDigit(ch))
                            {
                                leftBuilder.Append(ch);
                            }
                            else
                            {
                                break;
                            }
                        }
                        leftVal = Double.Parse(new string(leftBuilder.ToString().Reverse().ToArray()));
                    }
                    left             = Expression.Constant(leftVal);
                    startPlaceholder = equation.Substring(0, index).LastIndexOf(leftVal.ToString());
                }
                var next = equation[index + 1];
                if (next == '{')
                {
                    var closingIndex = equation.Substring(index).IndexOf('}');
                    int exprID;
                    using (TypeTextReader reader = new TypeTextReader(new StringReader(equation.Substring(index + 2))))
                    {
                        exprID = (int)reader.ReadInt64();
                    }
                    right          = subExpressions[exprID];
                    endPlaceholder = closingIndex + index + 1;
                }
                else
                {
                    using (TypeTextReader reader = new TypeTextReader(new StringReader(equation.Substring(index + 1))))
                    {
                        var exp = reader.ReadDouble();
                        right          = Expression.Constant(exp);
                        endPlaceholder = equation.Length - reader.BaseReader.ReadToEnd().Length;
                    }
                }
                var op = equation[index];
                equation = equation.Replace(equation.Substring(startPlaceholder, endPlaceholder - startPlaceholder), "{" + subExpressions.Count.ToString() + "}");
                subExpressions.Add(Expression.MakeBinary(ExpTypeFromChar(op), left, right));
            }
        }