%{
    #include <iostream>
    using namespace std;
    #include "three_address.h"
    extern int Line;
    #define yyerror(s) cout << "Error line " << Line << ": " s << endl
    token yylex();
%}

%token Assign
%token <st> Identifier
%token <in> Integer_literal
%token <to> Operator
%type <cl> three_address_code_list
%type <co> instruction
%type <op> operand dest

%union {
    char * st;
    int in;
    token to;
    operand op;
    code co;
    code_list cl;
}

%%
program:
    three_address_code_list
    { if ($1) $1->generate(); }
;

three_address_code_list:
        /* EPSILON */
        { $$ = NULL; }
    |    instruction three_address_code_list
        { $$ = new code_pair($1, $2); }
;

instruction:
        dest Assign operand
        { $$ = new two_address_code($1, $3); }
    |    dest Assign operand Operator operand
        { $$ = new three_address_code($1, $3, $4, $5); }
    |    Identifier operand
        { $$ = new input_output_code($2, $1); }
;

dest:
        Identifier
        { $$ = new identifier_operand($1); }
;

operand:
        Identifier
        { $$ = new identifier_operand($1); }
    |    Integer_literal
        { $$ = new constant_operand($1); }
;

%%

#include "lex.yy.c"

main() {
    yyparse();
}

