/// <summary> /// Evaluate: /// This function is used to evaluate the expression tree. This logic is given to /// us in our Etree.c lecture notes. It takes in an ExpressionTreeBaseNode param. /// then tries to cast it as a ConstantNode, VariableNode, or OperatorNode. Based /// on what the node type is (see ExpressionTreeNodeFactory) it will return a value /// to be evaluated. (all root nodes should be operators) /// </summary> /// <param name="node"></param> /// <returns></returns> private double Evaluate(ExpressionTreeBaseNode node) { ConstantNode constantNode = node as ConstantNode; if (constantNode != null) { return(constantNode.Value); } // as a variable VariableNode variableNode = node as VariableNode; if (variableNode != null) { return(variableDictionary[variableNode.Name]); } // it is an operator node if we came here OperatorNode operatorNode = node as OperatorNode; if (operatorNode != null) { // but which one? switch (operatorNode.Operator) { case '+': return(Evaluate(operatorNode.Left) + Evaluate(operatorNode.Right)); case '-': return(Evaluate(operatorNode.Left) - Evaluate(operatorNode.Right)); case '*': return(Evaluate(operatorNode.Left) * Evaluate(operatorNode.Right)); case '/': try { return(Evaluate(operatorNode.Left) / Evaluate(operatorNode.Right)); } catch (DivideByZeroException e) { Console.Write(e.Message); Console.ReadLine(); } break; case '^': return(Math.Pow(Evaluate(operatorNode.Left), Evaluate(operatorNode.Right))); default: // if it is not any of the operators that we support, throw an exception: throw new NotSupportedException( "Operator " + operatorNode.Operator.ToString() + " not supported."); } } throw new NotSupportedException(); }
private ExpressionTreeBaseNode CreateExpressionTree(string expression) { Stack <ExpressionTreeBaseNode> operandStack = new Stack <ExpressionTreeBaseNode>(); int precidence = -1; /**********************************************************************/ // we will parse the expression string into the expression tree here! // /**********************************************************************/ int expressionIndex = 0; for (; expressionIndex < expression.Length; expressionIndex++) { char currentChar = expression[expressionIndex]; //not an operator if (!CheckOperatorPrecidence(currentChar, ref precidence)) { switch (currentChar) { //Constant (double) case ':': string constantValue = ""; expressionIndex++; //traverse expression to grab the entire constant (double), and store in constantValue while (expressionIndex < expression.Length && expression[expressionIndex] != ':') { constantValue += expression[expressionIndex]; expressionIndex++; } //create new ConstantNode and pass in the corresponding Value prop. ExpressionTreeBaseNode constantNode = nodeFactory.GetNode("C", constantValue); //convert type to constant node to print the value /* * ConstantNode node = (ConstantNode)constantNode; * Console.WriteLine("constantNode.Value = " + node.Value); */ operandStack.Push(constantNode); //push to operand stack break; //Variable (string) case '{': string variableName = ""; expressionIndex++; //traverse expression to grab the entire constant (double), and store in constantValue while (expressionIndex < expression.Length && expression[expressionIndex] != '}') { variableName += expression[expressionIndex]; expressionIndex++; } //create new VariableNode and pass in the corresponding Name prop. ExpressionTreeBaseNode variableNode = nodeFactory.GetNode("V", variableName); //convert type to constant node to set the default value VariableNode tempNode = (VariableNode)variableNode; SetVariable(tempNode.Name, 0.0); operandStack.Push(variableNode); //push to operand stack break; } } //currentChar is an operator else { //create new OperatorNode and pass in the corresponding operator prop. ExpressionTreeBaseNode operatorNode = nodeFactory.GetNode("O", currentChar.ToString()); //convert type to constant node to print the value OperatorNode tempNode = (OperatorNode)operatorNode; //pop two operands off of the stack ExpressionTreeBaseNode rightNode = operandStack.Pop(); ExpressionTreeBaseNode leftNode = operandStack.Pop(); //set operatornode left and right nodes. tempNode.Left = leftNode; tempNode.Right = rightNode; operandStack.Push(tempNode); //push operator node onto stack } } ExpressionTreeBaseNode expressionTreeRoot = operandStack.Peek(); //expression tree root is top of stack operandStack.Pop(); //pop top of stack (root) return(expressionTreeRoot); }
} // variable ref dictionairy //constructor public ExpressionTree(string expression) { postfixExpression = ConvertInfixToPostfix(expression); root = CreateExpressionTree(postfixExpression); }