noisybox.net

Project 3:  Postfix Expression Evaluator

This program will take a postfix expression on the command line and will spit back the result.  The program will handle addition, subtraction, division, and multiplication.  The maximum number of operators and operands (combined) that can be specified is 200.  All values given should be less than 90000000 (90 million).  If the program is run with a value larger than this, the output is undefined.  Integer and floating point values may be used.  If the result is an integer, the result will be displayed in integer format, otherwise a floating point representation will be shown with 5 significant digits.

Binary Win95/98/NT executable can be downloaded directly:  postfix.exe (approx 41k)

The program can be tested with the following expressions:

postfix 1 1 + 
(output 2)

postfix 2 2 2 2 2 * * * * 
(output 32)

postfix 12 13 + 100 200 + * 
(output 7500)

postfix 1 2 / 8 * 7 + 12 12 + + 
(output 35)

-------------------------- begin postfix.h ------------------------------------------ 
//postfix.h by Jason Plumb

// Defines 
#define STACK_SIZE 200 
#define OPER_ADD (float)90000000 
#define OPER_SUB (float)91000000 
#define OPER_MUL (float)92000000 
#define OPER_DIV (float)93000000 
#define STACK_EMPTY (float)94000000

// Function declarations 
void PrintProgramUsage();    // Displays a message telling how to use this program 
float PopStack();      // Pops an item from the stack 
bool PushStack(float iVal);    // Pushes an item onto the stack 
void ModifyStackAfterOperator();  // Modifies the stack after an operator has been added 
-------------------------- end postfix.h ------------------------------------------

-------------------------- begin postfix.cpp----------------------------------------- 
/*  Project 3 - by Jason Plumb 
    Concepts of Programming Languages 
 Spring, 1999

 This program will interpret a postfix expression given on the command line and will 
 output the result.

 Example program usage:

    postfix.exe 1 1 + 
 postfix.exe 12 13 + 100 200 + * 
 postfix.exe 2 2 2 2 2 2 2 * * * * * * 
*/

#include <stdio.h> 
#include <stdlib.h>   /* Needed for strtod */ 
#include <string.h> 
#include "postfix.h"

// Global variables here 
float Stack[STACK_SIZE]; 
int iStackIndex;

//Main function 
int main(int argc, char *argv[]){

 int i; 
 float CurVal; 
 char buffer[200], tmpbuff[200], *pTemp;

 iStackIndex = -1;     //Start with an empty stack

 if(argc<2){ 
  PrintProgramUsage(); 
  return 0; 
 }//if

 for(i=1;i<argc;i++){    //Loop for all arguments 
  switch(argv[i][0]){ 
  case '+': 
   PushStack(OPER_ADD); 
   ModifyStackAfterOperator(); 
   break; 
  case '-': 
   PushStack(OPER_SUB); 
   ModifyStackAfterOperator(); 
   break; 
  case '*': 
   PushStack(OPER_MUL); 
   ModifyStackAfterOperator(); 
   break; 
  case '/': 
   PushStack(OPER_DIV); 
   ModifyStackAfterOperator(); 
   break; 
  default: 
   CurVal = (float)strtod(argv[i], &pTemp); 
   if(!PushStack(CurVal)){ 
    printf("Error:  Stack overflow...exiting (-1)"); 
    return -1; 
   }//if 
   break; 
  }//switch 
 }//for

 if(iStackIndex!=0){ 
  printf("Error:  Probably invalid expression...exiting (-1)"); 
  return -1; 
 }//if

 //Do some simple formatting here to see if we should print decimal point or not 
 sprintf(buffer, "%0.10f", Stack[0]); 
 pTemp = strchr(buffer, '.');    //Get pointer to decimal point 
 memset(tmpbuff, NULL, 200); 
 tmpbuff[0] = '.'; 
 for(i=1;i<(int)strlen(pTemp);i++){ 
  tmpbuff[i]='0'; 
 }//for

 if(strstr(buffer, tmpbuff)==NULL) 
  printf("%0.5f", Stack[0]);    //If decimal pts needed 
 else 
  printf("%0.0f", Stack[0]);

 return 0;

}//main function

void PrintProgramUsage(){ 
 printf("\nProgram Usage:\n\n"); 
 printf(" proj3.exe <expression>\n"); 
}//PrintProgramUsage function

//This will pop an int off the stack 
float PopStack(){ 
 if(iStackIndex == -1) 
  return STACK_EMPTY;

 float rc = Stack[iStackIndex]; 
 iStackIndex--; 
 return rc; 
}//PopStack function

//This function will push the specified value onto the stack 
bool PushStack(float iVal){ 
 if(iStackIndex+1 > STACK_SIZE)   //If a the end of the array 
  return false;      //Return false if stack is full

 iStackIndex++; 
 Stack[iStackIndex] = iVal; 
 return true;

}//PushStack function

//This function will modify the stack after an operator has been pushed 
void ModifyStackAfterOperator(){ 
 float oper, val1, val2, newval;

 oper = PopStack(); 
 val1 = PopStack(); 
 val2 = PopStack();

 if( (oper==STACK_EMPTY) || (val1==STACK_EMPTY) || (val2==STACK_EMPTY)) 
  return;      //just bail out if empty stack reached (error)

 if(oper==OPER_ADD){ 
  newval = val1 + val2; 
 } 
 else if(oper==OPER_SUB){ 
  newval = val2 - val1; 
 } 
 else if(oper==OPER_MUL){ 
  newval = val2 * val1; 
 } 
 else if(oper==OPER_DIV){ 
  newval = val2 / val1; 
 } 
 else 
  return;       //Abort out if invalid operator on top of stack

 PushStack(newval);

}//ModifyStackAfterOperator function 
-------------------------- end postfix.cpp-----------------------------------------