/* example of recursive descent parsing */ /* evaluates arithmetic expressions defined by this EBNF grammar:
::= ( '\n' )* q ::= ( + | - )* ::= ( * | / )* ::= n | ( ) */ #include #include #include using namespace std; int lval; int lookahead; int scan() { char c; static char next_c; static int holding=0; if (holding) {holding = 0; c = next_c;} else c = cin.get(); while (c == ' ') c = cin.get(); /* skip blanks */ if (isdigit(c)) {lval = 0; while (isdigit(c)) {lval = 10*lval + c - '0'; c = cin.get();} next_c = c; holding = 1; c = 'n';} return c;} bool match(int token) { return token == lookahead;} void advance() {lookahead = scan();} void error() {cout << "oops" << endl; exit(0);} int expr(); int term(); int factor(); main() {advance(); while (!match('q')) {cout << expr() << endl; if (match('\n')) advance(); else error();}} int expr() {int eval; char op; eval = term(); while (match('+') | match ('-')) {op = lookahead; advance(); switch (op) {case '+': eval += term(); break; case '-': eval -= term(); break;}} return eval;} int term() {int tval; char op; tval = factor(); while (match('*') | match('/')) {op = lookahead; advance(); switch (op) {case '*': tval *= factor(); break; case '/': tval /= factor(); break;}} return tval;} int factor() {int fval; if (match('n')) {fval = lval; advance();} else if (match('(')) {advance(); fval = expr(); if (match(')')) advance(); else error();} else error(); return fval;}