/// <summary>
 /// create a nod.
 /// </summary>
 /// <param name="name"> name.</param>
 /// <returns> node .</returns>
 private ExpressionTreeNode CreateNode(string name)
 {
     if ((name[0] >= 48 && name[0] <= 57) || (name.Length > 1 && name[0] == '-'))
     {
         /* First character is a number: Constant Node */
         if (int.TryParse(name, out int value))
         {
             return(new ConstantNode(value));
         }
         else
         {
             return(null);
         }
     }
     else if (name.Length == 1 && this.IsOperator(name[0]))
     {
         /* Operator Node */
         return(OperatorNodeFactory.CreateNewNode(name[0]));
     }
     else
     {
         /* Variable Node */
         return(new VariableNode(name));
     }
 }
Exemple #2
0
 // post: helps returns a node in the expression tree based on the given expression
 // int index - the index of the lowest precedence operator in the expression
 // string expression - the given english expression that may consist of letters, numbers, and operators
 private static BaseNode GetNodeHelper(int index, string expression)
 {
     if (index != -1)
     {
         BinaryOperatorNode node = OperatorNodeFactory.CreateOperatorNode(expression[index]);
         node.Right = GetNode(expression.Substring(index + 1));
         node.Left  = GetNode(expression.Substring(0, index));
         return(node);
     }
     else if (index == -2)
     {
         throw new System.ArgumentException("Too many or too few parentheses", "Invalid expression");
     }
     return(BuildVariableNode(expression));
 }
        /// <summary>
        /// Takes a valid string expression and returns a postfix ordered list of expression tree nodes.
        /// Uses Dijkstra's Shunting Yard algorithm.
        /// </summary>
        /// <param name="expression">Valid expression string.</param>
        /// <returns>Postfix ordered expression tree node list.</returns>
        private List <ExpressionTreeNode> GetPostfixList(string expression)
        {
            Stack <char> stack = new Stack <char>();
            List <ExpressionTreeNode> postfixList = new List <ExpressionTreeNode>();
            OperatorNodeFactory       opFact      = new OperatorNodeFactory();

            char[] expressionArray = expression.ToArray <char>();

            // loops over each char in expression string
            for (int i = 0; i < expressionArray.Length; i++)
            {
                char currChar = expressionArray[i];

                // if the current char is a left parenthesis, push to stack
                if (currChar.Equals('('))
                {
                    stack.Push(currChar);
                }

                // if the current char is a right parenthesis
                else if (currChar.Equals(')'))
                {
                    // while the top of the stack is not a left parenthesis, pop and add to list
                    while (!stack.Peek().Equals('('))
                    {
                        OperatorNode newOpNode = opFact.CreateOperatorNode(stack.Pop());
                        postfixList.Add(newOpNode);
                    }

                    stack.Pop(); // pop the left parenthesis from the top of the stack
                }

                // If the current char is a valid operator
                else if (opFact.IsValidOperator(currChar))
                {
                    // if the stack is empty or the next char is a left parenthesis
                    if (stack.Count <= 0 || stack.Peek().Equals('('))
                    {
                        stack.Push(currChar);
                    }

                    // otherwise the next char on the stack is an operator
                    else
                    {
                        OperatorNode currOpNode = opFact.CreateOperatorNode(currChar);
                        OperatorNode nextOpNode = opFact.CreateOperatorNode(stack.Peek());

                        // if curr operator has > precedence than the next operator, or equal precedence and right associativity
                        if (currOpNode.Precedence > nextOpNode.Precedence ||
                            (currOpNode.Precedence == nextOpNode.Precedence && currOpNode.Associativity == OperatorNode.Associative.Right))
                        {
                            stack.Push(currChar); // push the current operator on the stack
                        }

                        // if curr operator has < precedence than the next operator, or equal precedence and left associativity
                        else
                        {
                            // add the next operator to the list
                            stack.Pop();
                            postfixList.Add(nextOpNode);
                            i--;
                        }
                    }
                }

                // if the current char is a digit (0-9)
                else if (char.IsDigit(currChar))
                {
                    string constantString = currChar.ToString();
                    for (int j = i + 1; j < expressionArray.Length; j++)
                    {
                        currChar = expressionArray[j];

                        // if the next char is a digit, append to constant string
                        if (char.IsDigit(currChar))
                        {
                            constantString += currChar.ToString();
                            i++;
                        }

                        // otherwise the next char is not part of this number
                        else
                        {
                            break;
                        }
                    }

                    postfixList.Add(new ConstantNode(double.Parse(constantString))); // add the complete number to the list
                }

                // if the current char is a variable
                else
                {
                    string variable = currChar.ToString();
                    for (int j = i + 1; j < expressionArray.Length; j++)
                    {
                        currChar = expressionArray[j];

                        // if the next char is not an operator
                        if (!opFact.IsValidOperator(currChar))
                        {
                            variable += expressionArray[j].ToString();
                            i++;
                        }

                        // otherwise the next char is not part of this variable
                        else
                        {
                            break;
                        }
                    }

                    // add the complete variable to the list
                    postfixList.Add(new VariableNode(variable, ref this.variables));

                    // Add the name to variabelNames list if it is not already in it.
                    if (!this.variableNames.Contains(variable))
                    {
                        this.variableNames.Add(variable);
                    }
                }
            }

            // pop and add the rest of the stack to the list
            while (stack.Count > 0)
            {
                OperatorNode newOpNode = opFact.CreateOperatorNode(stack.Pop());
                postfixList.Add(newOpNode);
            }

            return(postfixList);
        }