/*****************************************************
  Author  : Yan Huang
  Date    : 02.18.07
  Synopsis: evaluate a postfix expression with integers
**************************************************************/

#include <stack>
#include <iostream>
using namespace std;


/************************************************ 
    Get the next token, symbol is the character
    representation, which is returned, the token is 
    represented by its enumerated value, which
    is returned in the function name 
***************************************************/

enum Precedence {lparen,rparen,plus,minus,divide,times,mod,eos,operand};

Precedence get_token()
{
  char symbol;

  symbol = cin.get();
  
  /* get rid of the space */
  if (symbol == ' '){
      symbol = cin.get();
  } 

  switch (symbol)  {
     case '(' : return lparen;
     case ')' : return rparen;
     case '+': return plus;
     case '-' : return minus;
     case '/' :  return divide;
     case '*' : return times;
     case '%' : return mod;
     case '\n' : return eos;
     default  : cin.unget(); return operand; 
     /* no error checking, default is operand */
     }
}

/************************************************************
    Evaluate a postfix expression, expr, maintained as a 
    global variable, '\n' is the the end of the expression.
    Get_token is used to return the token type and 
    the character symbol. Operands are assumed to be integer
*****************************************************************/

int main(void)
{

  Precedence token;
  char symbol;  
  int op1, op2, op;
  
  stack<int> expression; 
  cout << " Please enter a correct postfix expression : ";

  token = get_token();
  while (token != eos)  {
      if (token == operand){
           cin >> op; /* no error check */
           expression.push(op);   /* stack insert */
        }
        else { 
              /* remove two operands, perform operation, and 
                return result to the stack */
             op2 = expression.top();  /* stack delete */
             expression.pop();
             op1 = expression.top();  
             expression.pop();
             switch(token) {
                  case plus : expression.push(op1+op2); break;
                  case minus: expression.push(op1-op2); break;     
                  case times: expression.push(op1*op2); break;     
                  case divide: expression.push(op1/op2); break;     
                  case mod: expression.push(op1%op2);
             }
    }
    token = get_token();
 }
 cout << " The result is : " << expression.top() << endl; /* print result */
}




