diff --git a/Sujet.pdf b/Sujet.pdf index af1239cb519f91d2689a7b3328df0688bcfffcf4..df4388a9daf5586b91e8c03d357f754cb55c51a6 100644 Binary files a/Sujet.pdf and b/Sujet.pdf differ diff --git a/src/cfg_dead_assign.ml b/src/cfg_dead_assign.ml index c94352c820fc90baf6146294ebc6dd7e5e6e30ce..abd0f0420c56af9dfa4408246744c514dce57d8c 100644 --- a/src/cfg_dead_assign.ml +++ b/src/cfg_dead_assign.ml @@ -3,21 +3,32 @@ open Cfg open Prog open Utils open Cfg_liveness - -(* Dead Assign Elimination *) -(* [dead_assign_elimination_fun f] performs DAE on function [f]. *) +(* Dead Assign Elimination -- Élimination des affectations mortes *) + +(* [dead_assign_elimination_fun f] élimine les affectations mortes dans la + function [f]. Cette fonction renvoie un couple [(f',c)] oú [f'] est la + nouvelle fonction, et [c] est un booléen qui indique si du progrès a été + fait. *) let dead_assign_elimination_fun ({ cfgfunargs; cfgfunbody; cfgentry } as f: cfg_fun) = + let changed = ref false in let cfgfunbody = Hashtbl.map (fun (n: int) (m: cfg_node) -> match m with (* TODO *) | _ -> m ) cfgfunbody in - { f with cfgfunbody } + ({ f with cfgfunbody }, !changed ) + +(* Applique l'élimination de code mort autant de fois que nécessaire. Testez + notamment sur le fichier de test [basic/useless_assigns.e]. *) +let rec iter_dead_assign_elimination_fun f = + let f, c = dead_assign_elimination_fun f in + (* TODO *) + f let dead_assign_elimination_gdef = function - Gfun f -> Gfun (dead_assign_elimination_fun f) + Gfun f -> Gfun (iter_dead_assign_elimination_fun f) let dead_assign_elimination p = assoc_map dead_assign_elimination_gdef p diff --git a/src/cfg_liveness.ml b/src/cfg_liveness.ml index 63f3a650956da0dacbf7323cd2d91e3a0b7ed74a..1fee07ab1b5a52f6a7156862265b25746f3041ce 100644 --- a/src/cfg_liveness.ml +++ b/src/cfg_liveness.ml @@ -3,48 +3,42 @@ open Cfg open Prog open Utils -(* Liveness analysis *) +(* Analyse de vivacité *) -(* [vars_in_expr e] returns the set of variables appearing in [e]. *) +(* [vars_in_expr e] renvoie l'ensemble des variables qui apparaissent dans [e]. *) let rec vars_in_expr (e: expr) = + (* TODO *) Set.empty -(* [live_cfg_node node live_after] gives the set of variables live before the - node [node], given the set [live_after] of variables live after this node. *) +(* [live_cfg_node node live_after] renvoie l'ensemble des variables vivantes + avant un nœud [node], étant donné l'ensemble [live_after] des variables + vivantes après ce nœud. *) let live_cfg_node (node: cfg_node) (live_after: string Set.t) = + (* TODO *) live_after -(* Computes the set of live variables after a node [n] in a CFG [cfg]. - [lives] is a mapping from CFG node identifier to the set of variables that - are live before this node. -*) +(* [live_after_node cfg n] renvoie l'ensemble des variables vivantes après le + nœud [n] dans un CFG [cfg]. [lives] est l'état courant de l'analyse, + c'est-à -dire une table dont les clés sont des identifiants de nœuds du CFG et + les valeurs sont les ensembles de variables vivantes avant chaque nœud. *) let live_after_node cfg n (lives: (int, string Set.t) Hashtbl.t) : string Set.t = + (* TODO *) Set.empty -(* [live_cfg_nodes cfg lives] makes one iteration of the fixpoint computation. +(* [live_cfg_nodes cfg lives] effectue une itération du calcul de point fixe. - This returns a boolean that is true if some progress has been made in this - iteration (the set of variables live at at least one node has changed), false - otherwise. *) + Cette fonction met à jour l'état de l'analyse [lives] et renvoie un booléen + qui indique si le calcul a progressé durant cette itération (i.e. s'il existe + au moins un nœud n pour lequel l'ensemble des variables vivantes avant ce + nœud a changé). *) let live_cfg_nodes cfg (lives : (int, string Set.t) Hashtbl.t) = + (* TODO *) false -(* [live_cfg_fun f] computes the set of live variables at each point by - iterating [live_cfg_nodes] as long as progress is made. *) -let live_cfg_fun ({ cfgfunargs; cfgfunbody; cfgentry }: cfg_fun) = - let lives : (int, string Set.t) Hashtbl.t = Hashtbl.create 17 in - let rec aux () = - if live_cfg_nodes cfgfunbody lives - then aux () - else () in - aux (); - lives - -let live_cfg_fun ({ cfgfunargs; cfgfunbody; cfgentry }: cfg_fun) = - fixpoint (fun cfg lives n -> - match Hashtbl.find_option cfg n with - | Some cn -> live_cfg_node cn (live_after_node cfg n lives) - | None -> failwith "Unknown node" - ) - (fun cfg n cn -> Set.empty) - cfgfunbody +(* [live_cfg_fun f] calcule l'ensemble des variables vivantes avant chaque nœud + du CFG en itérant [live_cfg_nodes] jusqu'à ce qu'un point fixe soit atteint. + *) +let live_cfg_fun (f: cfg_fun) : (int, string Set.t) Hashtbl.t = + let lives = Hashtbl.create 17 in + (* TODO *) + lives diff --git a/src/e_regexp.ml b/src/e_regexp.ml index 4b1568194f748ef336b25c5b23bc9254f4e23a5f..58f07775c88b155cafae363d2077e3cc481eab05 100644 --- a/src/e_regexp.ml +++ b/src/e_regexp.ml @@ -59,10 +59,10 @@ let alphabet = char_list_of_string (lowercase_letters ^ uppercase_letters ^ digi let letter_regexp = char_range (char_list_of_string (uppercase_letters ^ lowercase_letters)) let digit_regexp = char_range (char_list_of_string digits) let identifier_material = char_range (char_list_of_string (uppercase_letters ^ lowercase_letters ^ digits ^ "_")) +let keyword_regexp s = str_regexp (char_list_of_string s) (* La liste des expressions régulières permettant d'identifier les tokens du langage E *) let list_regexp = - let keyword_regexp s = str_regexp (char_list_of_string s) in [ (keyword_regexp "while", fun s -> Some (SYM_WHILE)); (keyword_regexp "int", fun s -> Some (SYM_INT)); diff --git a/src/test_lexer.ml b/src/test_lexer.ml index 8c6542040184dff2bf7073d4bdfaebe798cfe7fa..fa64acc93c566c2c6e2ff5af64b251d973dc4d8c 100644 --- a/src/test_lexer.ml +++ b/src/test_lexer.ml @@ -5,19 +5,13 @@ open Utils open Symbols let () = - let lowercase_letters = "abcdefghijklmnopqrstuvwxyz" in - let uppercase_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" in - let digits = "0123456789" in - let other_characters = "?!=<>_ ;,{}()[]-+*/%\n\t" in - let alphabet = char_list_of_string (lowercase_letters ^ uppercase_letters ^ digits ^ other_characters) in - let letter_regexp = char_range (char_list_of_string (uppercase_letters ^ lowercase_letters)) in - let digit_regexp = char_range (char_list_of_string digits) in - let keyword_regexp s = str_regexp (char_list_of_string s) in let regexp_list = [ (keyword_regexp "while", fun s -> Some (SYM_WHILE)); (keyword_regexp "if", fun s -> Some (SYM_IF)); ] in - + (* Décommentez la ligne suivante pour tester sur la vraie liste d'expressions + régulières. *) + (* let regexp_list = list_regexp in *) List.iteri (fun i (rg, _) -> Printf.printf "%d: %s\n" i (string_of_regexp rg)) regexp_list;