/* SI 413 Fall 2021
 * This is a bison file that will use the hand-coded scanner to
 * make a parser and interpreter for the simple calculator language.
 */
%define parse.error detailed
%define parse.lac full
%locations

%{
#include <iostream>
#include <cstdlib>
using namespace std;

// Prototype for our scanner function, aka getNextToken()
int yylex();

void yyerror(const char *s);

bool finished = false;
%}

//-- GRAMMAR SYMBOL DECLARATIONS
%union {
  int val;
  char sym;
};
%token<val> NUM
%token<sym> OPA OPM
%token LP RP STOP
%type<val> exp term factor

//-- GRAMMAR RULES
%%
res: exp STOP         { cout << $1 << endl; YYACCEPT; }
|                     { cout << endl; finished = true; YYACCEPT; }

exp: exp OPA term     { $$ = ($2 == '+' ? $1 + $3 : $1 - $3); }
|    term             { $$ = $1; }

term: term OPM factor { $$ = ($2 == '*' ? $1 * $3 : $1 / $3); }
|     factor          { $$ = $1; }

factor: NUM           { $$ = $1; }
|       LP exp RP     { $$ = $2; }

%%

int main() {
  do {
    cout << "> " << flush;
  } while (yyparse() == 0 && !finished);
  return 0;
}

void yyerror(const char *s) {
  cerr << s << endl;
}