parseur d'expressions régulières ; crible d'Ératosthène
Retour à la page générale de La lettre de Caml.
let string_of_char = make_string 1 ;; type lexeme = Car of char | Étoile | Parenthèse_gauche | Parenthèse_droite | Barre ;; let rec lexeur flot = match flot with [< '`\\` ; 'x >] -> [< '(Car x) ; lexeur flot >] | [< '`|` >] -> [< 'Barre ; lexeur flot >] | [< '`*` >] -> [< 'Étoile ; lexeur flot >] | [< '`(` >] -> [< 'Parenthèse_gauche ; lexeur flot >] | [< '`)` >] -> [< 'Parenthèse_droite ; lexeur flot >] | [< 'x >] -> [< '(Car x) ; lexeur flot >] | [< >] -> [< >] ;; include "lexeur_expression_régulière" ;; type expression_régulière = Chaîne of string | Caractère of char | Séquence of expression_régulière * expression_régulière | Étoilée of expression_régulière | Alternative of expression_régulière * expression_régulière ;; let rec parse_E flot = match flot with [< parse_F f ; parse_E1 e1 >] -> match e1 with [< 'expr >] -> Alternative(f,expr) | [< >] -> f and parse_E1 flot = match flot with [< 'Barre ; parse_E e >] -> [< 'e >] | [< >] -> [< >] and parse_F flot = match flot with [< parse_G g ; parse_F1 f1 >] -> match f1 with [< 'expr >] -> Séquence(g,expr) | [< >] -> g and parse_F1 flot = match flot with [< parse_F f >] -> [< 'f >] | [< >] -> [< >] and parse_G flot = match flot with [< parse_H h ; parse_G1 g1 >] -> match g1 with [< 'bidon >] -> Étoilée(h) | [< >] -> h and parse_G1 flot = match flot with [< 'Étoile >] -> [< 'Caractère(`?`) >] | [< >] -> [< >] and parse_H flot = match flot with [< '(Car c) >] -> Caractère(c) | [< 'Parenthèse_gauche ; parse_E expr ; 'Parenthèse_droite >] -> expr ;; let rec agrège = function Séquence(e1,e2) -> ( match (agrège e1),(agrège e2) with (Chaîne s1),(Chaîne s2) -> Chaîne (s1 ^ s2) | (Chaîne s1),(Séquence ((Chaîne s2),e)) -> agrège (Séquence (Chaîne (s1^s2),e)) | (Séquence (e,(Chaîne s1))),(Chaîne s2) -> agrège (Séquence (e,Chaîne(s1^s2))) | e'1,e'2 -> Séquence(e'1,e'2) ) | Étoilée(e1) -> Étoilée(agrège e1) | Alternative(e1,e2) -> Alternative((agrège e1),(agrège e2)) | Caractère(c) -> Chaîne (string_of_char c) | e -> e ;; let parseur s = agrège (parse_E (lexeur (stream_of_string s))) ;;
(* version avec les flots *) let rec à_partir_de n = [< 'n ; (à_partir_de (n+1)) >] ;; let rec filtre_stream f flot = match flot with | [< 'x >] -> if f(x) then [< 'x ; (filtre_stream f flot) >] else [< (filtre_stream f flot) >] | [< >] -> [< >] ;; let ne_divise_pas a b = (b mod a) <> 0 ;; let rec crible flot = match flot with | [< 'n >] -> [< 'n ; (crible (filtre_stream (ne_divise_pas n) flot)) >] | [< >] -> [< >] ;; let nombres_premiers = crible (à_partir_de 2) ;; let rec list_and_stream n flot = if n = 0 then [] , flot else match flot with [< 'x >] -> let l,f = list_and_stream (n-1) flot in (x :: l) , f ;; let list_of_stream n flot = fst (list_and_stream n flot) ;; (* version sans les flots *) type 'a suite_infinie = Nil | Cellule of (unit -> 'a * 'a suite_infinie) ;; exception Suite_Vide ;; let cons x l = let f () = (x,l) in Cellule f ;; let tête = function Nil -> raise Suite_Vide | Cellule f -> match f() with x,_ -> x ;; let queue = function Nil -> raise Suite_Vide | Cellule f -> match f() with _,q -> q ;; let est_vide = function Nil -> true | _ -> false ;; let rec force n l = match n,l with 0,l -> [],l | n,Nil -> raise Suite_Vide | n,Cellule f -> match f() with x,q -> let liste,reste = force (n-1) q in x :: liste,reste ;; let rec à_partir_de n = let f () = n,(à_partir_de (n+1)) in Cellule f ;; let premiers n l = match force n l with liste,_ -> liste ;; let reste n l = match force n l with _,r -> r ;; let rec filtre prédicat = function Nil -> Nil | Cellule f -> match f() with x,q -> if (prédicat x) then let g () = x,(filtre prédicat q) in Cellule g else filtre prédicat q ;; let non_multiple a b = (b mod a) <> 0 ;; let élimine x l = filtre (non_multiple x) l ;; let rec crible = function Nil -> raise Suite_Vide | Cellule f -> match f() with x,q -> let g() = x,(crible (élimine x q)) in Cellule g ;; let nombres_premiers = crible (à_partir_de 2) ;;
Retour à la page générale de La lettre de Caml.