%{
  open Ast
%}

%token <int> CST
%token <string> IDENT
%token SET, LET, IN, PRINT
%token EOF 
%token LP RP
%token PLUS MINUS TIMES DIV
%token EQ

/* Définitions des priorités et associativités des tokens */

%nonassoc IN
%left MINUS PLUS 
%left TIMES DIV
%nonassoc uminus

/* Point d'entrée de la grammaire */
%start prog

/* Type des valeurs retournées par l'analyseur syntaxique */
%type < Ast.prg > prog

%%

prog:
| instrs EOF {List.rev $1}
;

instrs:
| instr        { [$1] }
| instrs instr { $2::$1 }
;
 
instr:
| SET IDENT EQ expr { Set($2,$4)}
| PRINT expr        { Print($2) }
;
 
expr:
| CST                       { Cst($1) }
| IDENT                     { Var($1) }
| expr PLUS expr            { Op(Sum,$1,$3) }
| expr MINUS expr           { Op(Diff,$1,$3) }
| expr TIMES expr           { Op(Prod,$1,$3) }
| expr DIV expr             { Op(Quot,$1,$3) }
| MINUS expr %prec uminus   { Op(Diff,Cst(0),$2) } 
| LET IDENT EQ expr IN expr { Letin($2,$4,$6) }
| LP expr RP                { $2 }
;