//simple function that turns a string into a Data node. protected virtual ExpNode MakeDataNode(string operand) { double number; bool isDouble = double.TryParse(operand, out number); //only stores the operand in number if it is actually a double if (isDouble) { ValNode numNode = new ValNode(number); //makes a Numerical node with the operand's value return(numNode); } else { VarNode varNode = new VarNode(operand); //makes a variable node with the operands variable name. return(varNode); } }
public ExpTree(string expression) { Stack <string> equationStack = new Stack <string>(); Stack <string> treeStack = new Stack <string>(); Stack <Node> buildTree = new Stack <Node>(); string tempString = ""; //format expression to work with parser expression = "(" + expression + ")"; char[] tokens = expression.ToCharArray(); //build stack from parsed expression - shunting yard algorithm for (int i = 0; i < tokens.Length; i++) { if (tokens[i] == '(') { equationStack.Push(tokens[i].ToString()); } else if (tokens[i] == ')') // doesn't push ")" to equation stack { while (equationStack.Peek() != "(") // pop until lhs bracket is found { treeStack.Push(equationStack.Pop()); // add right child and operator } equationStack.Pop(); // get rid of "(" } else if (operators.Contains(tokens[i].ToString())) // current token is an operator { while (equationStack.Peek() != "(" && (!operators.Contains(equationStack.Peek()) || (getPrecedence(tokens[i].ToString()) < getPrecedence(equationStack.Peek())) || /*check if stack top is operator of higher precedence*/ (getPrecedence(tokens[i].ToString()) == getPrecedence(equationStack.Peek())))) { treeStack.Push(equationStack.Pop()); } equationStack.Push(tokens[i].ToString()); } else // integer or variable { // get numbers with multiple digits (will always execute at least once) while (tokens[i] != '(' && tokens[i] != ')' && !operators.Contains(tokens[i].ToString())) { tempString += tokens[i]; i++; } if (tokens[i] == '(' || tokens[i] == ')' || operators.Contains(tokens[i].ToString())) { i--; //move back so token isn't skipped in next iteration } equationStack.Push(tempString); tempString = ""; } } equationStack.Clear(); //reverse stack to get postfix expression while (treeStack.Count != 0) { equationStack.Push(treeStack.Pop()); } //build tree while (equationStack.Count != 0) //equationStack now contains postfix expression { tempString = equationStack.Pop(); if (operators.Contains(tempString)) //make opNode { OpNode newNode = new OpNode(tempString); if (buildTree.Count >= 2) { newNode.right = buildTree.Pop(); newNode.left = buildTree.Pop(); buildTree.Push(newNode); } } else { if (tempString.All(Char.IsDigit)) //make valNode { ValNode newNode = new ValNode(tempString); buildTree.Push(newNode); } else //make varNode { char let = Char.ToUpper(tempString[0]); string row = tempString.Substring(1); tempString = let + row; if (!varDict.ContainsKey(tempString)) { varDict[tempString] = 0; //initialize all variables to 0 } VarNode newNode = new VarNode(tempString); buildTree.Push(newNode); varList.Add(tempString); //add to list of cell references } } } this.root = buildTree.Pop(); //final item in stack will be root node pointing to subtrees }