%{ (* --- préambule: ici du code Caml --- *) open Expr (* rappel: dans expr.ml: type expr = Const of int | Add of expr*expr | Mull of expr*expr *) %} /* description des lexèmes, ceux-ci sont décrits (par vous) dans lexer.mll */ %token INT /* le lexème INT a un attribut entier */ %token VAR %token TRUE FALSE %token IF THEN ELSE %token FUN MAPSTO %token LET IN %token PVPV %token UNDERSCORE %token PRINT %token BAND BOR %token EQ GT LT GTE LTE %token PLUS TIMES MINUS %token LPAREN RPAREN %token EOL /* retour à la ligne */ %left PVPV %nonassoc LET IN %nonassoc FUN MAPSTO %nonassoc IF THEN ELSE %left BAND BOR %left EQ %nonassoc GT LT GTE LTE %nonassoc APP %left PLUS MINUS /* associativité gauche: a+b+c, c'est (a+b)+c */ %left TIMES /* associativité gauche: a*b*c, c'est (a*b)*c */ %nonassoc PRINT %nonassoc UMINUS /* un "faux token", correspondant au "-" unaire */ %nonassoc UNDERSCORE /* cf. son usage plus bas : il sert à "marquer" une règle pour lui donner la précédence maximale */ %start main /* "start" signale le point d'entrée: */ /* c'est ici main, qui est défini plus bas */ %type main /* on _doit_ donner le type associé au point d'entrée */ %% /* --- début des règles de grammaire --- */ /* à droite, les valeurs associées */ main: /* <- le point d'entrée (cf. + haut, "start") */ preambule EOL { $1 } /* on veut reconnaître une expression */ ; preambule: | LET VAR EQ expression PVPV preambule { LetIn($2,$4,$6) } | LET UNDERSCORE EQ expression PVPV preambule { LetIn("_",$4,$6) } | expression { $1 } ; expression: /* règles de grammaire pour les expressions */ | INT { Const $1 } | VAR { Var $1 } | TRUE { BConst true } | FALSE { BConst false } | LPAREN expression RPAREN { $2 } /* on récupère le deuxième élément */ | expression PLUS expression { Add($1,$3) } | expression TIMES expression { Mul($1,$3) } | expression MINUS expression { Min($1,$3) } | expression EQ expression { Eq($1,$3) } | expression GT expression { Gt($1,$3) } | expression LT expression { Lt($1,$3) } | expression GTE expression { Gte($1,$3) } | expression LTE expression { Lte($1,$3) } | expression BAND expression { Band($1,$3) } | expression BOR expression { Bor($1,$3) } | PRINT expression { PrInt($2) } | IF expression THEN expression ELSE expression { ITE($2,$4,$6)} | LET VAR EQ expression IN expression { LetIn($2,$4,$6) } | LET UNDERSCORE EQ expression IN expression { LetIn("_",$4,$6) } | FUN VAR MAPSTO expression { Fun($2,$4) } | MINUS expression %prec UMINUS { Min(Const 0, $2) } | applic sexpr %prec APP { App($1,$2) } ; applic: | applic sexpr { App($1,$2) } | VAR { Var $1 } | LPAREN expression RPAREN { $2 } ; sexpr: | INT { Const $1 } | VAR { Var $1 } | TRUE { BConst true } | FALSE { BConst false } | LPAREN expression RPAREN { $2 } ;