Sunday 7 July 2013

Convert Infix expression to Post/Pre fix.


/*
      * Compiler always represent expression in postfix Notation.
      * Shunting yard algorithm is used for this conversion.
      * It can be used to convert to Prefix also.
      * Reverse Input string.
      * Use shunting yard algorith.
      * Reverse the output string
*/
      #include <iostream>
      #include <stack>
      using namespace std;
     
      string output = "";
      stack<int> operatorStack;
     
      // Attach integer value with each operand.
      // Same precedence operator share same int. value.
      // ( paren has least value.
      int getPrecedence(char ch)
      {
            switch(ch)
            {
                  case '*' : return 2;
                  case '+' : return 1;
                  case '/' : return 2;
                  case '-' : return 1;
                  case '(' : return 0;
            }
      }
     
      // Get precedence of current as well as stack top element.
      // If current precedence is greater or equal then return true
      // else return false
      bool greaterPrecedenceThanStackTop(char ch)
      {
             int topPrecedence = getPrecedence(operatorStack.top());
             int charPrecedence = getPrecedence(ch);
             if(charPrecedence >= topPrecedence)
                 return true;
             return false;
      }
     
      bool isOperand(char ch)
      {
             switch(ch)
             {
                   case '+' : return true;
                   case '-' : return true;
                   case '*' : return true;
                   case '/' : return true;
                   default  : return false;
             }
      }
     
      bool isParen(char ch)
      {
             if(ch == '(' || ch == ')')
                 return true;
             return false;
      }
     
      // If opening paren push it to operator stack.
      // Else Pop operators from operator stack to output string.
      // until operning paren is popped.
      void scannedParen(char ch)
      {
             if(ch == '(')
             {
                   cout<<"\n\tPUSH ( TO OPERATOR STACK";
                   operatorStack.push(ch);
             }
             else
             {
                   while(!operatorStack.empty() && operatorStack.top() != '(')
                   {
                        cout<<"\n\tPOP AND ADD TO OUTPUT "<<char(operatorStack.top());
                        output += operatorStack.top();
                        operatorStack.pop();
                   }
                   if(!operatorStack.empty())
                   {
                        cout<<"\n\tPOP (";
                        operatorStack.pop();
                   }
             }
      }
     
      // If stack is empty push operator.
      // If operator has same or higher precedence than stack[top] push operator.
      // Else pop operators until stack is empty or stack[top] has equal or less precedence
      // Than current operator.
      void scannedOperator(char ch)
      {
             if(operatorStack.empty())
             {
                   cout<<"\n\tPUSH TO OPERATOR STACK";                
                   operatorStack.push(ch);
                   return;
             }
             if(greaterPrecedenceThanStackTop(ch))
             {
                   cout<<"\n\tPUSH TO OPERATOR STACK";
                   operatorStack.push(ch);
             }
             else
             {
                   while(!greaterPrecedenceThanStackTop(ch) && !operatorStack.empty())
                   {
                        cout<<"\n\tPOP "<<char(operatorStack.top());
                        output += operatorStack.top();
                        operatorStack.pop();
                   }
                   cout<<"\n\tPUSH "<<ch;
                   operatorStack.push(ch);
             }
      }
     
      //Copy all operators from operatroStack to output string.
      void flushStack()
      {
             while(!operatorStack.empty())
             {
                 char c = operatorStack.top();
                 cout<<"\n\tCOPY "<<c<<" TO OUTPUT";
                 operatorStack.pop();
                 if(c == '(')
                     continue;
                 output += c;
             }
      }
     
      //Separate operators, parenthesis and Operands.
      //Call appropriate function accordingly.
      void scanInput(string input)
      {
             string operand = "";
             for(int i=0 ; i< input.length(); i++)
             {
                    char ch = input[i];
                    cout<<"\n\nCURRENT CHAR = "<<ch;
                    if(isParen(ch))
                    {
                         output += operand;
                         operand = "";
                         scannedParen(ch);
                    }
                    else if(isOperand(ch))
                    {
                        output += operand;
                        operand = "";
                        scannedOperator(ch);
                    }
                    else
                    {
                        cout<<"\n\tCOPY TO OUTPUT STRING";
                        operand += ch;
                    }
             }
             cout<<"\n\nEND OF INPUT : FLUSH STACK";
             output += operand;
             flushStack();
      }
     
      int main()
      {
            string input = "a+(b+c*(e/f)+d)*g";
            cout<<"INFIX NOTATION : "<<input;
            scanInput(input);
            cout<<"\n\nPOSTFIX NOTATION : "<<output<<endl;
            system("pause");
      }

/*
OUTPUT
-------
INFIX NOTATION : a+(b+c*(e/f)+d)*g

CURRENT CHAR = a
        COPY TO OUTPUT STRING

CURRENT CHAR = +
        PUSH TO OPERATOR STACK

CURRENT CHAR = (
        PUSH ( TO OPERATOR STACK

CURRENT CHAR = b
        COPY TO OUTPUT STRING

CURRENT CHAR = +
        PUSH TO OPERATOR STACK

CURRENT CHAR = c
        COPY TO OUTPUT STRING

CURRENT CHAR = *
        PUSH TO OPERATOR STACK

CURRENT CHAR = (
        PUSH ( TO OPERATOR STACK

CURRENT CHAR = e
        COPY TO OUTPUT STRING

CURRENT CHAR = /
        PUSH TO OPERATOR STACK

CURRENT CHAR = f
        COPY TO OUTPUT STRING

CURRENT CHAR = )
        POP AND ADD TO OUTPUT /
        POP (

CURRENT CHAR = +
        POP *
        PUSH +

CURRENT CHAR = d
        COPY TO OUTPUT STRING

CURRENT CHAR = )
        POP AND ADD TO OUTPUT +
        POP AND ADD TO OUTPUT +
        POP (

CURRENT CHAR = *
        PUSH TO OPERATOR STACK

CURRENT CHAR = g
        COPY TO OUTPUT STRING

END OF INPUT : FLUSH STACK
        COPY * TO OUTPUT
        COPY + TO OUTPUT

POSTFIX NOTATION : abcef/*d++g*+
*/

No comments:

Post a Comment