```/********************************************************
* Here is a simple int calculator based on bison, with
* a hand-coded scanner.  It is based explicity on the
* finite automaton pictured in simple.ps.
********************************************************/
%{
#include <iostream>
#include <string>
#include <cstdlib> //-- I need this for atoi
using namespace std;

//-- Lexer prototype required by bison, aka getNextToken()
int yylex();
int yyerror(const char *p) { cerr << "Error!" << endl; }
%}

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

//-- GRAMMAR RULES
%%
res: exp STOP { cout << \$1 << endl; }

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

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

sfactor: OPA factor   { \$\$ = (\$1 == '+' ? \$2 : -\$2); }
| factor              { \$\$ = \$1; }

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

%%
//-- FUNCTION DEFINITIONS
int main()
{
while(1) yyparse();
return 0;
}

// This is the scanner
int yylex()
{
bool found = false;
int state = 0;
string val = "";
while(!found)
{
char c = cin.get();
switch(state)
{
case 0:
switch(c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
val += c; state = 1; break;
case '+': case '-': val += c; state = 2; break;
case '*': case '/': val += c; state = 3; break;
case ';': val += c; state = 4; break;
case '(': val += c; state = 5; break;
case ')': val += c; state = 6; break;
case ' ': case '\t': case '\n': break;
case EOF: exit(0); break;
default: found = true; }
break;
case 1:
switch(c) {
case '0':case '1':case '2':case '3':case '4':
case '5':case '6':case '7':case '8': case '9':
val += c; state = 1; break;
default:
cin.putback(c);
found = true; }
break;
case 2: case 3: case 4: case 5: case 6:
cin.putback(c);
found = true;
break;
}
}

switch(state) {
case 0: return 0; // EOF
case 1: yylval.val = atoi(val.c_str()); return NUM;
case 2: yylval.sym = val[0];            return OPA;
case 3: yylval.sym = val[0];            return OPM;
case 4:                                 return STOP;
case 5:                                 return LP;
case 6:                                 return RP; }
}

```