pro-fondement/Rendu0/parser.mly

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 }
;