/* example of recursive descent parsing */

/* evaluates arithmetic expressions defined by this
 EBNF grammar:

<main> ::= ( <expr> '\n' )* q
<expr> ::= <term> ( + <term> | - <term> )*
<term> ::= <factor> ( * <factor> | / <factor> )*
<factor> ::= n | ( <expr> )

*/

#include <iostream>
#include <stdlib.h>
#include <ctype.h>

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;}
       
