%{ (* parservhc.mly *) (* syntaxe concrète *) #open "aintv";; #open "print";; #open "verif";; %} %token DPV PV PE PI LET IN PARG PARD EGALE %token SI ALORS SINON FINSI NON ET OU %token INFERIEUR SUPERIEUR INFEGALE SUPEGALE %token DIFFERENT VRAI FAUX PLUS MOINS %token FOIS DIVISE VIRGULE %token INT %token IDENT %start Program %type Program %type Suite_decl_fonc %type Foncs %type Fonc %type Debut_Fonc %type Variables %type Expr %type Expr_Arithm %type T %type Cst_Bool %type Terme %type Facteur %type Suite_Expr %type Liste_Var %type Parf %type Liste_Expr %% /* Règles de grammaire et actions sémantiques */ Program: Suite_decl_fonc Expr DPV {if !a_definir<>[] then raise (F_Inconnue (fst (hd !a_definir))) else definies:=[];($1,$2)} ; Suite_decl_fonc: LET Foncs IN {$2} | {[]} ; Foncs: Fonc PV {[$1]} | Fonc {[$1]} | Fonc PV Foncs {($1::$3)} ; Fonc: Debut_Fonc Expr {let (a,b)=$1 in (a,(b,$2))} ; Debut_Fonc: IDENT PARG Variables PARD EGALE {if mem_assoc $1 !definies then raise F_Doublon else (try let n=assoc $1 !a_definir in if n<>(list_length $3) then raise (Nb_incorrect $1) else a_definir:=except ($1,n) !a_definir with Not_found -> ()); definies:=($1,list_length $3)::!definies;($1,$3)} ; Variables: Liste_Var {lp:=$1;$1} | {[]} ; Liste_Var: Parf VIRGULE Liste_Var {if mem $1 $3 then raise Doublon;($1::$3)} | Parf {[$1]} ; Parf: IDENT {FPNSTAT $1} | PE IDENT {FPVAL $2} | PI IDENT {FPNDYN $2} ; Expr: SI Expr ALORS Expr SINON Expr FINSI {IF ($2,($4,$6))} | T {$1} | NON T {NOT $2} | Expr ET T {AND ($1,$3)} | Expr OU T {NOT (AND (NOT $1,NOT $3))} ; T: Expr_Arithm EGALE Expr_Arithm {EQUAL ($1,$3)} | Expr_Arithm INFERIEUR Expr_Arithm {LESS ($1,$3)} | Expr_Arithm SUPERIEUR Expr_Arithm {LESS ($3,$1)} | Expr_Arithm INFEGALE Expr_Arithm {NOT (LESS ($3,$1))} | Expr_Arithm SUPEGALE Expr_Arithm {NOT (LESS ($1,$3))} | Expr_Arithm DIFFERENT Expr_Arithm {NOT (EQUAL ($1,$3))} | Expr_Arithm {$1} ; Cst_Bool: VRAI {CST "true"} | FAUX {CST "false"} ; Expr_Arithm: Expr_Arithm PLUS Terme {ADD ($1,$3)} | Expr_Arithm MOINS Terme {SUB ($1,$3)} | Terme {$1} ; Terme: Terme FOIS Facteur {MULT ($1,$3)} | Terme DIVISE Facteur {DIV ($1,$3)} | Facteur {$1} ; Facteur: IDENT PARG Suite_Expr PARD {(try if (assoc $1 !a_definir)<>(list_length $3) then raise (Nb_incorrect $1) with Not_found -> (try if (assoc $1 !definies)<>(list_length $3) then raise (Nb_incorrect $1) with Not_found -> a_definir:=($1,list_length $3)::!a_definir)); CALL ($1,$3)} | PARG Expr PARD {$2} | IDENT {let mon_mem x = exists (function FPVAL y -> x=y | FPNSTAT y -> x=y | FPNDYN y -> x=y) in if not (mon_mem $1 !lp) then raise (Inconnue $1); VAR $1} | INT {CST (string_of_int $1)} | MOINS Facteur {SUB (CST "0",$2)} | Cst_Bool {$1} ; Suite_Expr: Liste_Expr {$1} | {[]} ; Liste_Expr: Expr VIRGULE Liste_Expr {($1::$3)} | Expr {[$1]} ;