//build the tree (bottom up) using the shuntingYard stacks
        private bool buildTree()
        {
            //pop operators from stack -> build tree
            //OpNode temp;
            //   if (root.operationType == '_')
            //   {

            root       = operators.Pop();
            root.right = operands.Pop();
            root.left  = operands.Pop();             //after building tree,
            operands.Push(new ValNode(root.Eval())); //evaluate, and push value to output
            return(true);
            //return true;
            //   }
            //else
            //{
            //    temp = root;                //hold sub-tree
            //    //operands.Pop();             //pop the result -- right sub-tree == result
            //    root = operators.Pop();     //grab an operator
            //    root.right = temp;          //restore sub-tree, making right-heavy tree
            //    root.left = operands.Pop(); //if we don't push the result (leave it in tree) this works

            //    return true;
            //}
            //int valCount = eTokens.Length;  //keep #items handy
            //int leafVal = 0;  //out variable -- required for parsing
        }
Beispiel #2
0
        // Created this method to prevent bloat in code
        private Node formTree(Stack <Node> operands, Stack <OpNode> operators)
        {
            // While there are no OpNode on the operatorsStack, form appropriate branches and place in operands stack
            while (operators.Count > 0)
            {
                OpNode newParent = operators.Pop();
                newParent.RightChild = operands.Pop();
                newParent.LeftChild  = operands.Pop();

                root = newParent;
                operandStack.Push(newParent);
            }

            return(root);
        }
Beispiel #3
0
        private double Eval(Node node)
        {
            //Evaluate based on the kind of node

            ConstNode constnode = node as ConstNode;

            if (constnode != null)
            {
                return(constnode.OpValue);
            }

            VarNode varnode = node as VarNode;

            if (varnode != null)
            {
                try
                { return(variableDict[varnode.Name]); }
                catch
                {
                    Console.WriteLine("Variable " + varnode.Name + " has not been defined. Continuing evaluation with variable equal to 0.");
                }
            }

            OpNode opnode = node as OpNode;

            if (opnode != null)
            {
                switch (opnode.Op)
                {
                case '+':
                    return(Eval(opnode.Left) + Eval(opnode.Right));

                case '-':
                    return(Eval(opnode.Left) - Eval(opnode.Right));

                case '*':
                    return(Eval(opnode.Left) * Eval(opnode.Right));

                case '/':
                    return(Eval(opnode.Left) / Eval(opnode.Right));
                }
            }

            return(0);
        }
Beispiel #4
0
        // Factory for ExpNodes to create an expression tree.
        protected ExpNode ConstructTreeFromTokens(List <string> expressionInPostfixNotation)
        {
            Stack <ExpNode> stack = new Stack <ExpNode>();

            foreach (string tok in expressionInPostfixNotation)
            {
                if (operators.TryGetValue(tok, out OperatorToken op))                                   //if the token is an operator
                {
                    ExpNode newrightNode = stack.Pop();                                                 //grabs the right and left nodes from the stack
                    ExpNode newLeftNode  = stack.Pop();
                    ExpNode newOpNode    = new OpNode(ref newLeftNode, ref newrightNode, op.Symbol[0]); // Creates an OpNode with the nodes we just popped off the stack.
                    stack.Push(newOpNode);                                                              // Adds the new operator node to the stack.
                }
                else // if the token is an operand
                {
                    stack.Push(MakeDataNode(tok)); //push the operand node on to the stack
                }
            } //when there are no more tokens. There should only be one node on the stack.
            return(stack.Pop()); // returns the root node of the tree.
        }
Beispiel #5
0
        private double Eval(Node node)
        {
            //Evaluate based on the kind of node

            ConstNode constnode = node as ConstNode;

            if (constnode != null)
            {
                return(constnode.OpValue);
            }

            VarNode varnode = node as VarNode;

            if (varnode != null)
            {
                // used to be a try/catch, but now we set every new variable to 0 when the tree is made, so there will always be a value to obtain.
                return(variableDict[varnode.Name]);
            }

            OpNode opnode = node as OpNode;

            if (opnode != null)
            {
                switch (opnode.Op)
                {
                case '+':
                    return(Eval(opnode.Left) + Eval(opnode.Right));

                case '-':
                    return(Eval(opnode.Left) - Eval(opnode.Right));

                case '*':
                    return(Eval(opnode.Left) * Eval(opnode.Right));

                case '/':
                    return(Eval(opnode.Left) / Eval(opnode.Right));
                }
            }

            return(0);
        }
        }                                                          //allow tree to tell its current expression

        //Expression Tree Constructor
        //--builds ExpTree according to given expression, with default expression if never supplied one
        public ExpTree(Cell c, Cell[][] spc, string expression = "4+18/(9-3)")
        {
            root = new OpNode('_');                                //'_' == special marker for base tree-building case
            currentExpression = expression;                        //hold the expression -- allows re-parsing -- not needed once I build the tree for real?
            variables         = new Dictionary <string, double>(); //create new dictionary for variableName:value mapping
            operands          = new Stack <Node>();                //shuntingYard Operand Stack
            operators         = new Stack <OpNode>();              //shuntingYard Operator Stack
            //output = new Stack<Node>();                   //shuntingYard Output Stack
            precedence = new Dictionary <string, int>()            //shuntingYard Precedence Mapping
            {
                { "(", 0 }, { ")", 3 }, { "*", 2 }, { "/", 2 }, { "+", 1 }, { "-", 1 }
            };
            evalResult       = -42.0;                                       //make initial value an uncommon result
            expressionTokens = parseExp(ref c, ref spc, currentExpression); //use self-made parser, couldn't get my RegEx right..
            if (expressionTokens[0] == "" || isOperator(expressionTokens[0]))
            {
                c.Text    = "#REF!";
                c.bgColor = "Red";
                c.clearRefDict(); //clear refs so it can re-evaluate
            }
            //shuntYard(expressionTokens);                      //convert to RPN & build tree with Shunting Yard Algorithm
        }
Beispiel #7
0
 // recursive function to set a variable node.
 protected void SetVarNode(ref VarNode input, OpNode node)
 {
     if (VariableNodeCompare(input, node.left)) //if the left node is a Variable node and has the same variable name
     {
         (node.left as VarNode).Value = input.Value;
     }
     else if (VariableNodeCompare(input, node.right)) //if the right node is a Variable node and has the same variable name
     {
         (node.right as VarNode).Value = input.Value;
     }
     else
     {
         if (node.right as OpNode != null)                //if the right side node is an operator node
         {
             SetVarNode(ref input, node.right as OpNode); //check right subtree
         }
         if (node.left as OpNode != null)                 //if the right side node is an operator node
         {
             SetVarNode(ref input, node.left as OpNode);  //check right subtree
         }
     }
 }
        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
        }
Beispiel #9
0
        private string userInput;                                                           // Used for menu interface

        public ExpTree(string expression)
        {
            int  operandBegin = 0;      // Index of where the first character of the operand exists
            bool exit         = false;  // Used for logic with paranthesis and how they are placed onto appropriate stack
            bool paranthesis  = false;  // If true, we know that the last paranthesis was placed onto stack and we do not need to create another operand for current operator

            // Iterate through length of given expression
            for (int i = 0; i < expression.Length; i++)
            {
                char currentChar = expression[i];
                // If looking at an operator
                if (currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/')
                {
                    // Create an appropriate OpNode
                    OpNode newOp = new OpNode(currentChar.ToString());

                    // Last thing we looked at was not ')'
                    if (paranthesis == false)
                    {
                        //  Create an operand node with last operand and place onto stack
                        Node newNode = determineNode(expression, operandBegin, i);
                        operandStack.Push(newNode);
                    }
                    // We know that there is no 'new' operand to be placed on stack, sub-tree contained in () is already placed onto operand stack
                    else
                    {
                        // Reset the paranthesis flag
                        paranthesis = false;
                    }
                    // Next operand should begin immediately after the operator, note this would be different if urnary operators were included
                    operandBegin = i + 1;

                    // Determine what to do with current and previous operators
                    if (operatorStack.Count > 0)
                    {
                        // Need to peak at top of operand stack, if higher precedence need to push current operand down
                        if (operatorStack.Peek().Precedence < newOp.Precedence)
                        {
                            operatorStack.Push(newOp);
                        }
                        // If lower precedence, need to pop and form node
                        else
                        {
                            OpNode newParent = operatorStack.Pop();
                            newParent.RightChild = operandStack.Pop();
                            newParent.LeftChild  = operandStack.Pop();
                            operandStack.Push(newParent);

                            operatorStack.Push(newOp);
                        }
                    }

                    else
                    {
                        // If the operator stack is empty, it is essentially a sentinal like the hint paper was describing
                        operatorStack.Push(newOp);
                    }
                }
                else if (currentChar == '(')
                {
                    // Need to form new tree
                    ExpTree newTree = new ExpTree(expression.Substring(i + 1));

                    //TEST
                    i           = expression.IndexOf(')', i + 1);
                    paranthesis = true;

                    operandStack.Push(newTree.root);
                }
                else if (currentChar == ')')
                {
                    // End new tree, pop back out
                    Node newNode = determineNode(expression, operandBegin, i);
                    operandStack.Push(newNode);
                    root = formTree(operandStack, operatorStack);
                    exit = true;
                    break;
                }
            }

            // Since we are only using binary oprators, the operand stack must be even when expression is completely evaluated
            if (operandStack.Count > 0 & (operandStack.Count % 2 != 0) & exit == false)
            {
                Node newNode = determineNode(expression, operandBegin, expression.Length);
                operandStack.Push(newNode);
            }
            // Provide an entry point for outside world to access
            root = formTree(operandStack, operatorStack);
        }