/// <summary> /// Makes expression tree from string /// </summary> /// <param name="ex"></param> /// <returns></returns> private Node MakeTree(string ex) { SolverUtilities.RemoveExternalBracets(ref ex); Node res = new Node(); if (SolverUtilities.CheckNumber(ex)) { res.Operation = ex; res.Type = ExpressionType.Number; res.Left = null; res.Right = null; } if (SolverUtilities.CheckVariable(ex)) { res.Operation = ex; res.Type = ExpressionType.Variable; res.Left = null; res.Right = null; } if (SolverUtilities.CheckFunction(ex)) { int openBracet, closeBracet; openBracet = ex.IndexOf("("); closeBracet = ex.LastIndexOf(")"); res.Operation = ex.Substring(0, openBracet); string FunctionParam = ex.Substring(openBracet+1, closeBracet-openBracet-1); // If function takes one argument then make one child node. // If it takes two argumetns then make two children nodes; if (SolverUtilities.NumberOfFunctionArguments(FunctionParam) == 1) { res.Type = ExpressionType.OneArgumentFunction; res.Left = MakeTree(FunctionParam); res.Right = null; } else { int comma = FunctionParam.IndexOf(","); res.Type = ExpressionType.TwoArgumentFunction; res.Left = MakeTree(FunctionParam.Substring(0, comma)); res.Right = MakeTree(FunctionParam.Substring(comma+1, FunctionParam.Length-comma-1)); } } // We should pay attention to operations' priorities int signIndex = SolverUtilities.FindOperationSign(ex, new string[] {"-", "+"}); if (signIndex == -1) signIndex = SolverUtilities.FindOperationSign(ex, new string[] {"/", "*"}); if (signIndex == -1) signIndex = SolverUtilities.FindOperationSign(ex, new string[] { "^" }); if (signIndex != -1) { res.Operation = ex[signIndex].ToString(); res.Type = ExpressionType.Expression; res.Left = MakeTree(ex.Substring(0, signIndex)); res.Right = MakeTree(ex.Substring(signIndex+1, ex.Length-signIndex-1)); } return res; }
/// <summary> /// Figures out a value of given expression tree node /// </summary> /// <param name="tree"></param> public void ExecuteTree(Node tree) { if (tree == null) return; ExecuteTree(tree.Left); ExecuteTree(tree.Right); switch (tree.Type) { case ExpressionType.Number: tree.Value = double.Parse(tree.Operation); break; case ExpressionType.Variable: if (!m_Variables.ContainsKey(tree.Operation)) return; tree.Value = m_Variables[tree.Operation]; break; case ExpressionType.Expression: tree.Value = SolverUtilities.ExecuteExpression(tree.Operation, tree.Left.Value, tree.Right.Value); break; case ExpressionType.OneArgumentFunction: tree.Value = SolverUtilities.ExecuteFunction(tree.Operation, tree.Left.Value); break; case ExpressionType.TwoArgumentFunction: tree.Value = SolverUtilities.ExecuteFunction(tree.Operation, tree.Left.Value, tree.Right.Value); break; } }
/// <summary> /// Parsing string expression into expression tree /// </summary> public void Prepare() { // Check bracet balance if (!SolverUtilities.CheckBracets(m_Expression)) return; // Removing all spaces and make all characters low m_Expression = m_Expression.ToLower().Replace(" ", string.Empty); // Building an expression tree ExpressionTree = MakeTree(m_Expression); m_IsCompiled = true; }