/* E ::= T{+T} T ::= F{*F} F ::= (E)|i */ #include #include #include #include #include #define eprintf(...) fprintf(stderr, __VA_ARGS__) typedef enum TokenType { INTEGER = 1, PLUS = 2, MULT = 4, LBRACE = 8, RBRACE = 16, LF = 32, EF = 64, } TokenType; typedef struct _Token { TokenType type; int value; } Token; void fatal(const char* message); Token scan(); int e(); int t(); int f(); const int LINE_MAX = 1024; Token current; int main(int argc, char* argv[]) { current = scan(); int result = e(); printf("Success, result: %d\n", result); return 0; } Token scan() { static char prev_s = 0; Token token = {0, 0}; char s; if (prev_s) { s = prev_s; prev_s = 0; } else { s = getchar(); } while (isblank(s)) s = getchar(); while (s >= '0' && s <= '9') { token.type = INTEGER; token.value = token.value * 10 + ((int) (s - '0')); s = getchar(); } if (token.type == INTEGER) { prev_s = s; return token; } switch (s) { case '+': token.type = PLUS; break; case '*': token.type = MULT; break; case '(': token.type = LBRACE; break; case ')': token.type = RBRACE; break; case '\n': case '\r': case '\f': token.type = LF; break; case EOF: token.type = EF; break; default: eprintf("'%c' (%d)\n", s, s); fatal("Unexpected symbol"); break; } return token; } int e() { int result = t(); while (current.type == PLUS) { current = scan(); result += t(); } return result; } int t() { int result = f(); while (current.type == MULT) { current = scan(); result *= f(); } return result; } int f() { int result = 0; if (current.type == LBRACE) { current = scan(); result = e(); if (current.type != RBRACE) { fatal("Expected closing parentheses"); } } else if (current.type == INTEGER) { result = current.value; } else if (current.type == LF) { fatal("Unexpected line feed"); } else if (current.type == EF) { fatal("Unexpected EOF"); } else { fatal("Unexpected token"); } current = scan(); return result; } void fatal(const char* message) { eprintf("Error: %s\n", message); exit(1); }