#define DEBUG #include #include #include "stack.h" #define NUMBER 0 #define STACKSIZE 4 // The maximum number of items can be stored to the stack. #define BUFSIZE 8 static char s[BUFSIZE]; // Temporary buffer to store data return by getToken() double operandStack[STACKSIZE]; // An array to store the data in the stack. int stackPointer; // The index of the top of the stack. ////////////////////////////////////////////////////////////////////////// // Implementation of getToken() ////////////////////////////////////////////////////////////////////////// static char buf[4]; static int bufp; // Clear the read buffer. static void clearBuffer() { bufp = 0; } // Get a character from the buffer. static int getch() { return (bufp > 0) ? *(buf + --bufp) : getchar(); } // Push back a character to the buffer. static void ungetch(int c) { *(buf + bufp++) = c; } // Get a token from the input. If the input is a number, the return // value of this function is NUMBER, and 's' contains the numeric string. // If the input is not a number, the return value is the ASCII value // of the character. static int getToken(char* s) { int i, c; while((*s = c = getch()) == ' ' || c == '\t'); *(s + 1) = 0; if(!isdigit(c) && c != '.') return c; // not a number i = 0; if(isdigit(c)) // Collect integer part { while(isdigit(*(s + ++i) = c = getch())) { // Check if the next character will cause buffer overflow. // If so, stop reading. // Ideally, the code should also skip the rest of the line. if(i >= BUFSIZE - 2) { *(s + BUFSIZE - 1) = '\0'; printf("ERROR: Buffer Overflow.\n"); return NUMBER; } } } if(c == '.') // Collect fraction part { while(isdigit(*(s + ++i) = c = getch())) { // Check if the next character will cause buffer overflow. // If so, stop reading. if(i >= BUFSIZE - 2) { *(s + BUFSIZE - 1) = '\0'; printf("ERROR: Buffer Overflow.\n"); return NUMBER; } } } *(s + i) = 0; if(c != EOF) ungetch(c); return NUMBER; } /////////////////////////////////////////////////////////////////////////// int main() { int type; double op1, op2; // Initialize the stack. stack_clear(operandStack, &stackPointer, STACKSIZE); printf("Enter an expression in postfix order. E.g. 1 234 5 * 6 / + 7 - 89 -\n"); // continuously read characters from the keyboard until CTRL+D is pressed. while((type = getToken(s)) != EOF) { if(type == NUMBER) // The input is a number -> Push onto the stack. { printf("Read a number \'%s\'\n", s); stack_push(operandStack, &stackPointer, STACKSIZE, atof(s)); } else if(type == '\n') // The input is a new line -> Reset { printf("Result = %.8g\n", stack_pop(operandStack, &stackPointer)); stack_clear(operandStack, &stackPointer, STACKSIZE); } else if(type == '+' || type == '-' || type == '*' || type == '/') // Operator { op2 = stack_pop(operandStack, &stackPointer); op1 = stack_pop(operandStack, &stackPointer); if(type == '+') stack_push(operandStack, &stackPointer, STACKSIZE, op1 + op2); else if(type == '-') stack_push(operandStack, &stackPointer, STACKSIZE, op1 - op2); else if(type == '*') stack_push(operandStack, &stackPointer, STACKSIZE, op1 * op2); else if(type == '/') stack_push(operandStack, &stackPointer, STACKSIZE, op1 / op2); } else // Invalid expression { printf("\tInvalid Expression \'%s\'\n", s); clearBuffer(); stack_clear(operandStack, &stackPointer, STACKSIZE); } // Print out the stack only if DEBUG is defined. #ifdef DEBUG stack_print(operandStack, &stackPointer); #endif } return 0; }