#include #include #include #include #include typedef int Value; struct Operand { Value val; struct Operand* next; }; typedef struct Operand Operand; struct Stack { struct Operand* top; }; typedef struct Stack Stack; struct Scanner { char ch; bool eof; enum {eofSY, newlineSY, operandSY, operatorSY} sy; Value operand; // if symbol==OperandSY char operator; // if symbol==OperatorSY }; typedef struct Scanner Scanner; // set s->ch to the next character in the input, // in case of eof, s->eof is set to true void next_ch(Scanner* s) { if (s->eof) return; int ch = getchar(); if (ch == EOF) { s->eof = true; } else { s->ch = ch; } } // read next input symbol void get_sy(Scanner* s) { while (!s->eof && s->ch != '\n' && isspace(s->ch)) { next_ch(s); } if (s->eof) { s->sy = eofSY; } else if (isdigit(s->ch)) { Value val = s->ch - '0'; next_ch(s); while (isdigit(s->ch)) { val = val * 10 + s->ch - '0'; next_ch(s); } s->sy = operandSY; s->operand = val; } else { switch (s->ch) { case '+': case '-': case '*': case '/': s->sy = operatorSY; s->operator = s->ch; next_ch(s); break; case '\n': s->sy = newlineSY; s->ch = ' '; // instead of next_ch(s) to postpone reading break; default: fprintf(stderr, "Unknown operator: '%c'\n", s->ch); exit(1); } } } void init_scanner(Scanner* s) { s->eof = false; next_ch(s); get_sy(s); } void push(Stack* stack, Value val) { Operand* op = (Operand*) malloc(sizeof(Operand)); op->val = val; op->next = stack->top; stack->top = op; } Value pop(Stack* stack) { if (stack->top) { Operand* op = stack->top; stack->top = op->next; Value val = op->val; free(op); return val; } else { fprintf(stderr, "Stack underflow\n"); exit(1); } } int main() { Scanner s; Stack stack; init_scanner(&s); while (s.sy != eofSY) { switch (s.sy) { case operandSY: push(&stack, s.operand); break; case operatorSY: { Value rightop = pop(&stack); Value leftop = pop(&stack); Value result; switch (s.operator) { case '+': result = leftop + rightop; break; case '-': result = leftop - rightop; break; case '*': result = leftop * rightop; break; case '/': result = leftop / rightop; break; } push(&stack, result); } break; case newlineSY: { Value result = pop(&stack); printf("%d\n", result); break; } default: assert(0); } get_sy(&s); } }