97 lines
3.5 KiB
OCaml
97 lines
3.5 KiB
OCaml
%{
|
|
(* --- 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> INT /* le lexème INT a un attribut entier */
|
|
%token <string> 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 <Expr.expr> 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 }
|
|
;
|
|
|