Beispiel #1
0
    /// <summary>
    /// Takes an equation in infix format and parses it into postfix format. Each operator or number
    /// is stored in a Command. The parsed, postfix format equation is then stored in a list of commands.
    /// </summary>
    /// <param name="infix">
    /// The user's equation in infix format
    /// </param>
    /// <param name="factory">
    /// The factory used to create commands
    /// </param>
    /// <returns>
    /// Returns a list of commands for the user's equation in postfix format
    /// </returns>
    public List<Command> infixToPostfix(string infix, CommandFactory factory)
    {
        Command command;
        List<Command> postfix = new List<Command>(); // Equation in postfix format
        Stack<Command> tempStack = new Stack<Command>(); // Temporary stack of operators
        int length = infix.Length;

        for (int i = 0; i < length; i++)
        {
            char c = infix[i];

            // Infix to Postfix algorithm
            if (Char.IsNumber(c))
            {
                createNumber(c, factory, ref postfix, ref i, length, infix, false);
            }
            else if (c == '(')
            {
                command = factory.createLeftParenthesesCommand();
                tempStack.Push(command);
            }
            else if (c == '^')
            {
                command = factory.createExponentCommand();

                if ((tempStack.Count > 0) && (operatorCheck(Convert.ToChar(tempStack.Peek().getValue()), c, tempStack.Count)))
                {
                    postfix.Add(tempStack.Pop());
                }// end if

                tempStack.Push(command);
            }
            else if (c == '*')
            {
                command = factory.createMultiplyCommand();

                if ((tempStack.Count > 0) && (operatorCheck(Convert.ToChar(tempStack.Peek().getValue()), c, tempStack.Count)))
                {
                    postfix.Add(tempStack.Pop());
                }// end if

                tempStack.Push(command);
            }
            else if (c == '/')
            {
                command = factory.createDivideCommand();

                if ((tempStack.Count > 0) && (operatorCheck(Convert.ToChar(tempStack.Peek().getValue()), c, tempStack.Count)))
                {
                    postfix.Add(tempStack.Pop());
                }// end if

                tempStack.Push(command);
            }
            else if (c == '%')
            {
                command = factory.createModulusCommand();

                if ((tempStack.Count > 0) && (operatorCheck(Convert.ToChar(tempStack.Peek().getValue()), c, tempStack.Count)))
                {
                    postfix.Add(tempStack.Pop());
                }// end if

                tempStack.Push(command);
            }
            else if (c == '+')
            {
                command = factory.createAddCommand();

                if ((tempStack.Count > 0) && (operatorCheck(Convert.ToChar(tempStack.Peek().getValue()), c, tempStack.Count)))
                {
                    postfix.Add(tempStack.Pop());
                }// end if

                tempStack.Push(command);
            }
            else if (c == '-')
            {
                string operators = "+-*/%";

                if ((i != 0) && (operators.IndexOf(infix[i-1]) != -1) && (Char.IsNumber(infix[i + 1])))
                {// if the index is not 0, index - 1 is an operator, and index + 1 is a number, then create a negative number
                    i++;
                    createNumber(infix[i], factory, ref postfix, ref i, length, infix, true);
                }
                else
                {

                    // If infix[0] is '-', then append a 0 before appending the operator
                    if (i == 0)
                    {
                        command = factory.createNumberCommand(0);
                        postfix.Add(command);
                    }// end if

                    // If c == '-' and infix[i+1] == '-', then that is # - - #, which is # + #.
                    // Otherwise, it is a normal subtract command.
                    if (infix[i + 1] == '-')
                    {// # - - # = # + #
                        command = factory.createAddCommand();
                        i++;
                    }
                    else
                    {
                        command = factory.createSubtractCommand();
                    }// end if

                    if ((tempStack.Count > 0) && (operatorCheck(Convert.ToChar(tempStack.Peek().getValue()), c, tempStack.Count)))
                    {
                        postfix.Add(tempStack.Pop());
                    }// end if

                    tempStack.Push(command);
                }
            }
            else if (c == ')')
            {
                command = factory.createRightParenthesesCommand();

                while ((tempStack.Count > 0) && (Convert.ToChar(tempStack.Peek().getValue()) != '('))
                {
                    postfix.Add(tempStack.Pop());
                }// end while

                // Pops off the left parentheses
                if (tempStack.Count > 0)
                {
                    tempStack.Pop();
                }// end if
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Invalid Character: " + c);
            }// end if
        }// end foreach

        // Adds the last operation to the postfix list.
        while (tempStack.Count > 0)
        {
            postfix.Add(tempStack.Pop());
        }// end while

        return postfix;
    }