#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
char *input = NULL, operator= 0;
int pos = 0;
int oprands[80], top_opr = 0;
void dp() {
printf("[");
for (int i = 0; i < top_opr; ++i) {
printf(i == top_opr - 1 ? "%d" : "%d, ", oprands[i]);
}
printf("] [%s]\n", input + pos);
}
bool ws() {
if (!input || !input[pos]) return false;
while (input[pos] && isspace(input[pos])) pos++;
if (!input[pos]) return false;
return true;
}
bool factor() {
if (!ws()) return false;
char *end = NULL;
int i = strtol(input + pos, &end, 10);
if (errno == ERANGE) {
printf("error: expected factor, got %c\n", input[pos]);
return false;
}
oprands[top_opr++] = i;
pos = end - input;
return true;
}
bool match(char *s) {
if (!ws()) return false;
char *p;
if ((p = strchr(s, input[pos]))) {
operator= *p;
pos++;
return true;
}
return false;
}
bool mul() {
if (!factor()) return false;
while (match("*/")) {
char op = operator;
if (!factor()) {
printf("error: expected factor, got eof\n");
return false;
}
int b = oprands[--top_opr];
int a = oprands[--top_opr];
if (op == '*') oprands[top_opr++] = a * b;
if (op == '/') oprands[top_opr++] = a / b;
printf(". %d %c %d = %d\n", a, op, b, oprands[top_opr - 1]);
}
return true;
}
bool add() {
if (!mul()) return false;
while (match("+-")) {
char op = operator;
if (!mul()) {
printf("error: expected factor, got eof\n");
return false;
}
int b = oprands[--top_opr];
int a = oprands[--top_opr];
if (op == '+') oprands[top_opr++] = a + b;
if (op == '-') oprands[top_opr++] = a - b;
printf(". %d %c %d = %d\n", a, op, b, oprands[top_opr - 1]);
}
return true;
}
bool expr() { return add(); }
int main() {
input = "3 + 4 * 5 / 7 - 1";
pos = 0;
printf("? %s\n", input);
expr();
printf("= %d\n", oprands[--top_opr]);
}