
%header{
#line 2  "header.gr0"
    #include "../scanner/scanner.h"
    #include <cstdlib>
    #include <iostream>
    #include <sstream>
    #include <fbb/a2x.h>

    using FBB::A2x;
    using std::cerr;
    using std::cout;
    using std::endl;
%}









%name Parser

%union {
#line 4  "tokens.gr0"
    int i;
    double d;
};

%token  DONE
        INT
        DOUBLE

%type   <i> intExpr
%type   <d> doubleExpr

%left   '+'
%left   '*'
%right  UnaryMinus

%define LEX_BODY {return d_scanner.yylex();}

%define ERROR_BODY { std::cerr << "error encountered\n"; }

// %define CONSTRUCTOR_INIT : d_rpn(new std::ostringstream())

%define MEMBERS                                         \
    virtual ~Parser()   {}                              \
    private:                                            \
        std::ostringstream d_rpn;                       \
        Scanner d_scanner;

%define DEBUG 1



%%
    lines:
        lines
        line
    |
        line
    ;

    line:
        intExpr
        '\n'
        {
#line 12  "startrule.gr0"
            cerr << "RPN: " << d_rpn.str() << endl;
            cerr << "int: " << $1 << endl;
            d_rpn.str(string());
        }
    |
        doubleExpr
        '\n'
        {
#line 20  "startrule.gr0"
            cerr << "RPN: " << d_rpn.str() << endl;
            cerr << "double: " << $1 << endl;
            d_rpn.str(string());
        }
    |
        '\n'
        {
#line 27  "startrule.gr0"
            cout << "Good bye\n";
            YYACCEPT;
        }
    |
        error
        '\n'
        {
#line 34  "startrule.gr0"
            d_rpn.clear();
            d_rpn.str(string());
        }
    ;

    intExpr:
        intExpr '*' intExpr
        {
#line 42  "startrule.gr0"
            d_rpn << " * ";
            $$ = $1 * $3;
        }
    |
        intExpr '+' intExpr
        {
#line 48  "startrule.gr0"
            d_rpn << " + ";
            $$ = $1 + $3;
        }
    |
        '(' intExpr ')'
        {
#line 54  "startrule.gr0"
            $$ = $2;
        }
    |
        '-' intExpr         %prec UnaryMinus
        {
#line 59  "startrule.gr0"
            d_rpn << " n ";
            $$ = -$2;
        }
    |
        INT
        {
#line 65  "startrule.gr0"
            $$ = A2x(d_scanner.YYText());
            d_rpn << " " << $$ << " ";
        }
    ;

    doubleExpr:
        doubleExpr '*' doubleExpr
        {
#line 73  "startrule.gr0"
            d_rpn << " * ";
            $$ = $1 * $3;
        }
    |
        doubleExpr '+' doubleExpr
        {
#line 79  "startrule.gr0"
            d_rpn << " + ";
            $$ = $1 + $3;
        }
    |
        doubleExpr '*' intExpr
        {
#line 85  "startrule.gr0"
            d_rpn << " * ";
            $$ = $1 * $3;
        }
    |
        doubleExpr '+' intExpr
        {
#line 91  "startrule.gr0"
            d_rpn << " + ";
            $$ = $1 + $3;
        }
    |
        intExpr '*' doubleExpr
        {
#line 97  "startrule.gr0"
            d_rpn << " * ";
            $$ = $1 * $3;
        }
    |
        intExpr '+' doubleExpr
        {
#line 103  "startrule.gr0"
            d_rpn << " + ";
            $$ = $1 + $3;
        }
    |
        '(' doubleExpr ')'
        {
#line 109  "startrule.gr0"
            $$ = $2;
        }
    |
        '-' doubleExpr         %prec UnaryMinus
        {
#line 114  "startrule.gr0"
            d_rpn << " n ";
            $$ = -$2;
        }
    |
        DOUBLE
        {
#line 120  "startrule.gr0"
            $$ = A2x(d_scanner.YYText());
            d_rpn << " " << $$ << " ";
        }
    ;
