%{ (* parservhc.mly, Objective Caml version 3.08.1 *) (* syntaxe avec verification des conditions de contexte, methode de la table des symboles *) open Print open Aintv type typage = Type_int | Type_bool | Type_poly let meme_type = fun let fonctions = ref [] %} %token T_LET T_EQ T_IN T_AND T_LESS T_ADD T_SUB T_MUL T_DIV T_NOT T_IF T_THEN T_ELSE T_FI T_TRUE T_FALSE %token INT %token IDENT %token LPAR RPAR COMMA SEMICOLON DOUBLESEMICOLON %start program %type program %type program_0 %type expr %type expr_1 %type expr_2 %type expr_3 %type expr_4 %type expr_5 %type atome * typage %type liste_args %type affectations %type elem_aff %type liste_vars %% /* Rgles de grammaireet actions sŽmantiques */ program: | program_0 DOUBLESEMICOLON { $1 } ; program_0: | expr { [] , fst $1 } | T_LET affectations T_IN expr { $2 , fst $4 } ; expr: expr_1 { $1 } ; expr_1: expr_1 T_AND expr_2 { var_bool $1; var_bool $3; AND ($1, $3) } | expr_2 { $1 } ; expr_2: expr_2 T_LESS expr_3 { var_int $1; var_int $3; LESS ($1, $3) } | expr_2 T_EQ expr_3 { var_int $1; var_int $3; EQUAL($1, $3) } | expr_3 { $1 } ; expr_3: expr_3 T_ADD expr_4 { var_int $1; var_int $3; ADD ($1, $3) } | expr_3 T_SUB expr_4 { var_int $1; var_int $3; SUB ($1, $3) } | expr_4 { $1 } ; expr_4: expr_4 T_MUL expr_5 {var_int $1; var_int $3; MULT ($1, $3) } | expr_4 T_DIV expr_5 {var_int $1; var_int $3; DIV ($1, $3) } | expr_5 { $1 } ; expr_5: atome { $1 } ; atome: LPAR expr RPAR { $2 } | INT { CST $1 } | T_SUB INT { CST ("-" ^ $2) } | T_TRUE { CST "true" } | T_FALSE { CST "false" } | IDENT { VAR $1 } | IDENT LPAR RPAR { CALL ($1, []) } | IDENT LPAR liste_args RPAR { CALL ($1, $3) } | T_NOT LPAR expr RPAR { NOT $3 } | T_IF expr T_THEN expr T_ELSE expr T_FI {var_int $2; IF ($2, ($4, $6)) } ; liste_args: expr { [ $1 ] } | expr COMMA liste_args { $1 :: $3 } ; affectations: elem_aff { [ $1 ] } | elem_aff SEMICOLON { [ $1 ] } | elem_aff SEMICOLON affectations { let rec mem2 = function [] -> $1 :: $3 | (a, _) :: _ when a = fst $1 -> failwith ("Fonction " ^ a ^ " en double.") | _ :: q -> mem2 q in mem2 $3 } ; elem_aff: IDENT LPAR RPAR T_EQ expr { $1, ([], $5) } | IDENT LPAR liste_vars RPAR T_EQ expr { $1, ($3, $6) } ; liste_vars: IDENT { [FPVAL $1] } | IDENT COMMA liste_vars { if mem (FPVAL $1) $3 then failwith ("Variable " ^ $1 ^ " en double") else ((FPVAL $1) :: $3) } ; %%