%{
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
using namespace std;
#include "Polinom.hpp"

void yyerror(string message){
	cerr << message << endl;
	exit(EXIT_FAILURE);
}
extern int yylex();
map<string, Polinom*> polinomcici;

%}

%union{
	float vrednost;
	string* ime_prom;
	vector<float>* vektorcic;
	Polinom* poli;
}

%left '+' '-'
%left '*'
%left '\'' 

%token<vrednost> NUM
%token<ime_prom> ID
%type<poli> polinom
%type<vektorcic> NizBrojeva

%%
program: program linija '\n' {}
| linija '\n' {}
;

linija: polinom { cout<<*$1<<endl; }
| polinom '=' '=' polinom { if (*$1 == *$4)
				cout<<"True"<<endl;
			    else
				cout<<"False"<<endl;}
| polinom '!' '=' polinom {if (*$1 == *$4)
				cout<<"False"<<endl;
			    else
				cout<<"True"<<endl;}
| polinom '[' NUM ']' { cout<<(*$1)[$3]<<endl;}
| ID ':' '=' polinom { polinomcici[*$1] = $4;}
;


polinom: '<' NizBrojeva '>' { $$ = new Polinom(*$2);}
| ID { map<string,Polinom*>::const_iterator it = polinomcici.find(*$1);
 if (it == polinomcici.end()){
	yyerror("Promenljiva nije u tablici");
	exit(EXIT_FAILURE);
  }
  $$ = polinomcici[*$1];
  delete $1;
} 
|polinom '+' polinom { $$ = *$1 + *$3;}
| polinom '-' polinom {$$ = *$1 - *$3;}
| polinom '*' polinom {$$ = (*$1) * (*$3);}
| polinom '\'' { $$ = $1->izvod();}
| '$' polinom '|' NUM { $$ = $2->integral($4);} 

| '(' polinom ')' { $$ = $2;}
;

NizBrojeva: NizBrojeva ',' NUM { $$ = $1;
			       $$ -> push_back($3);
				}
| NUM { $$ = new vector<float>();
	$$ -> push_back($1);
      }
;


%%

int main(){
	yyparse();
	return 0;
}
