Пример #1
0
        //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);
            }
        }
Пример #2
0
        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
        }