From 123c8bc693063cfc880709c7dfa700a177a66adb Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Fri, 3 Sep 2021 17:37:03 +0200 Subject: Ended refactoring --- src/bin/transcriptor.ml | 3 +- src/lib/modifiers/mute.ml | 4 +- src/lib/modifiers/nasal.ml | 11 ++-- src/lib/modifiers/sig.ml | 2 +- src/lib/modifiers/vocalize.ml | 5 +- src/lib/parser.mly | 77 +++++++++++------------ src/lib/process.ml | 143 +++++++++++++++++++++--------------------- src/lib/prononciation.mly | 1 - src/lib/reader.ml | 4 +- src/lib/sounds/repr.ml | 2 + src/lib/sounds/repr.mli | 46 +------------- src/lib/sounds/sig.ml | 55 +++++++++++++++- src/lib/sounds/sounds.ml | 14 +++-- src/lib/sounds/sounds.mli | 4 +- 14 files changed, 189 insertions(+), 182 deletions(-) diff --git a/src/bin/transcriptor.ml b/src/bin/transcriptor.ml index d8cc6db..6d02e9d 100644 --- a/src/bin/transcriptor.ml +++ b/src/bin/transcriptor.ml @@ -1,8 +1,7 @@ module T = Translator module P = T.Parser -module Parser = P.Make(Sounds) -module I = Parser.MenhirInterpreter +module I = P.MenhirInterpreter let process (optional_line : string option) = match optional_line with diff --git a/src/lib/modifiers/mute.ml b/src/lib/modifiers/mute.ml index 3597876..331ed1a 100644 --- a/src/lib/modifiers/mute.ml +++ b/src/lib/modifiers/mute.ml @@ -1,12 +1,12 @@ open StdLabels +module T = Sounds (** Mute the last consonant if there is no voyel in the syllabus. This modifier is only applied in the first step, and not repeated anymore. *)let process : 'a Sig.modifier - = fun (type el) m init -> - let module T = (val m:Sounds.Sig.T with type t = el) in + = fun init -> let (((v1, v2), c) , ending) = init in let is_voyel = T.is_voyel v1 && T.is_voyel v2 in match is_voyel, c with diff --git a/src/lib/modifiers/nasal.ml b/src/lib/modifiers/nasal.ml index ec8ddb4..57a3235 100644 --- a/src/lib/modifiers/nasal.ml +++ b/src/lib/modifiers/nasal.ml @@ -1,9 +1,9 @@ +module T = Sounds (* Remove the ending consonant, and transform the voyel into the nasal form *) let transform - : (module Sounds.Sig.T with type t = 'a) -> 'a Sig.consonants option -> 'a Sig.t -> 'a Sig.t - = fun (type el) m c init -> - let module T = (val m:Sounds.Sig.T with type t = el) in + : Sounds.t Sig.consonants option -> Sounds.t Sig.t -> Sounds.t Sig.t + = fun c init -> let (((v1, v2), _) , _) = init in begin match T.nasal v1, T.nasal v2 with @@ -21,15 +21,14 @@ let transform merge from two distinct elements ? *) let process : 'a Sig.modifier - = fun (type el) m init -> - let module T = (val m:Sounds.Sig.T with type t = el) in + = fun init -> let (((v1, v2), c) , ending) = init in let ending = Option.bind ending (fun x -> x) in let opening = Option.map (fun v -> v.Sig.opening) c in let is_voyel = T.is_voyel v1 && T.is_voyel v2 in match ending, is_voyel, opening with | Some ending, _, _ when T.is_nasal ending -> - transform m c init + transform c init | None, false, Some (opening::tl) when T.is_nasal opening -> (* If there is no voyel here, transform the opening consonant as an ending consonant for the next syllabus *) diff --git a/src/lib/modifiers/sig.ml b/src/lib/modifiers/sig.ml index 4cf605f..bcc4af2 100644 --- a/src/lib/modifiers/sig.ml +++ b/src/lib/modifiers/sig.ml @@ -9,4 +9,4 @@ type 'a group = 'a voyel * 'a consonants option type 'a t = 'a group * 'a option option -type 'a modifier = (module Sounds.Sig.T with type t = 'a) -> 'a t -> 'a t +type 'a modifier = 'a t -> 'a t diff --git a/src/lib/modifiers/vocalize.ml b/src/lib/modifiers/vocalize.ml index b390757..1014642 100644 --- a/src/lib/modifiers/vocalize.ml +++ b/src/lib/modifiers/vocalize.ml @@ -1,9 +1,10 @@ +module T = Sounds + (** Transform the S into Z if the S is the opening consonant and there is no ending consonant before *) let process : 'a Sig.modifier - = fun (type el) m init -> - let module T = (val m:Sounds.Sig.T with type t = el) in + = fun init -> let (((v1, v2), c) , ending) = init in match c with diff --git a/src/lib/parser.mly b/src/lib/parser.mly index 251f359..a207329 100644 --- a/src/lib/parser.mly +++ b/src/lib/parser.mly @@ -7,52 +7,51 @@ See [1] for the theory behind the analysis *) -%parameter %{ - module P = Process.M(T) + module P = Process %} -%start main +%start main %% occlusiv: - | P { T.p } - | B { T.b } + | P { Sounds.p } + | B { Sounds.b } - | T { T.t } - | D { T.d } + | T { Sounds.t } + | D { Sounds.d } - | K { T.k } - | G { T.g } + | K { Sounds.k } + | G { Sounds.g } fricativ: - | S { T.s } - | SZ { T.sz } - | Z { T.z } + | S { Sounds.s } + | SZ { Sounds.sz } + | Z { Sounds.z } - | F { T.f } - | V { T.v } + | F { Sounds.f } + | V { Sounds.v } - | X { T.ch } - | J { T.j } + | X { Sounds.ch } + | J { Sounds.j } obstruent: | occlusiv { $1 } | fricativ { $1 } liquid: - | L { T.l } - | L L { T.l } - | R { T.r } + | L { Sounds.l } + | L L { Sounds.l } + | R { Sounds.r } nasal: - | N { T.n } - | M { T.m } + | N { Sounds.n } + | M { Sounds.m } consonant: | occlusiv { $1 } @@ -61,8 +60,8 @@ consonant: | nasal { $1 } semi_voyel: - | Y { T.semi_voyel_y } - | W { T.semi_voyel_w } + | Y { Sounds.semi_voyel_y } + | W { Sounds.semi_voyel_w } opening_consonant: | occlusiv { $1, None } @@ -78,25 +77,25 @@ opening_consonant: (* Each voyel as two associated sounds, depending there is a followng sound or not *) voyels: - | A { T.a , T.a } - | A I { T.voyel_ai , T.voyel_ai } - | E I { T.e `Opened , T.e `Opened } - | I { T.i , T.i } - | E { T.e `Opened , T.schwa () } - | E_ACUTE E? { T.e `Closed , T.e `Closed } - | E_AGRAVE { T.e `Opened , T.e `Opened } - | E U { T.eu , T.eu } - | O { T.o , T.o } - | U { T.voyel_y , T.voyel_y } - | OU { T.voyel_u , T.voyel_u } - | W A { T.diphtongue T.semi_voyel_w T.a, T.diphtongue T.semi_voyel_w T.a} - | W I { T.diphtongue T.semi_voyel_w T.i, T.diphtongue T.semi_voyel_w T.i} - | I E { T.diphtongue T.i (T.e `Opened), T.diphtongue T.i (T.e `Opened)} + | A { Sounds.a , Sounds.a } + | A I { Sounds.voyel_ai , Sounds.voyel_ai } + | E I { Sounds.e `Opened , Sounds.e `Opened } + | I { Sounds.i , Sounds.i } + | E { Sounds.e `Opened , Sounds.schwa () } + | E_ACUTE E? { Sounds.e `Closed , Sounds.e `Closed } + | E_AGRAVE { Sounds.e `Opened , Sounds.e `Opened } + | E U { Sounds.eu , Sounds.eu } + | O { Sounds.o , Sounds.o } + | U { Sounds.voyel_y , Sounds.voyel_y } + | OU { Sounds.voyel_u , Sounds.voyel_u } + | W A { Sounds.diphtongue Sounds.semi_voyel_w Sounds.a, Sounds.diphtongue Sounds.semi_voyel_w Sounds.a} + | W I { Sounds.diphtongue Sounds.semi_voyel_w Sounds.i, Sounds.diphtongue Sounds.semi_voyel_w Sounds.i} + | I E { Sounds.diphtongue Sounds.i (Sounds.e `Opened), Sounds.diphtongue Sounds.i (Sounds.e `Opened)} ending_consonant: - | B { Some (T.b ) } + | B { Some (Sounds.b ) } | T { None } - | K { Some (T.k)} + | K { Some (Sounds.k)} | liquid { Some $1 } | nasal { Some $1 } diff --git a/src/lib/process.ml b/src/lib/process.ml index 13a24a1..463701c 100644 --- a/src/lib/process.ml +++ b/src/lib/process.ml @@ -1,86 +1,83 @@ open StdLabels -module M(T:Sounds.Sig.T) = struct - - type voyel = T.t Modifiers.Sig.voyel - - type group = voyel * T.t Modifiers.Sig.consonants option - type modifier = T.t Modifiers.Sig.modifier - - (** Apply all the modifiers to the syllabic group in order to correct the - relation between the elements - - This is just a fold_left list, and the order matter : for example - nasalisation shall be applied after the S vocalisation - - *) - let apply_modifiers - : group * T.t option option -> modifier list -> group * T.t option option - = fun e m -> - List.fold_left m - ~init:e - ~f:(fun e f -> f (module T:Sounds.Sig.T with type t = T.t) e) - - let change_voyel - = fun init -> - let (((v1, v2), _) , ending) = init in - match ending with - | None -> v2 - | Some _ -> v1 - - let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> T.t list - = function - | [] -> acc - | hd::tl -> - let modifier = match tl with - | [] -> Modifiers.nasal::m - | _ -> (Modifiers.vocalize_s) :: (Modifiers.nasal) :: m in - let (voyel, consonants), ending_consonant = - apply_modifiers - (hd, ending_consonant) - modifier in - let voyel = change_voyel ((voyel, consonants), ending_consonant) in - - (* Add the last consonant and the voyel *) - let acc = match ending_consonant with - | None -> voyel::acc +type voyel = Sounds.t Modifiers.Sig.voyel + +type group = voyel * Sounds.t Modifiers.Sig.consonants option +type modifier = Sounds.t Modifiers.Sig.modifier + +(** Apply all the modifiers to the syllabic group in order to correct the + relation between the elements + + This is just a fold_left list, and the order matter : for example + nasalisation shall be applied after the S vocalisation + +*) +let apply_modifiers + : group * Sounds.t option option -> modifier list -> group * Sounds.t option option + = fun e m -> + List.fold_left m + ~init:e + ~f:(fun e f -> f e) + +let change_voyel + = fun init -> + let (((v1, v2), _) , ending) = init in + match ending with + | None -> v2 + | Some _ -> v1 + +let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> Sounds.t list + = function + | [] -> acc + | hd::tl -> + let modifier = match tl with + | [] -> Modifiers.nasal::m + | _ -> (Modifiers.vocalize_s) :: (Modifiers.nasal) :: m in + let (voyel, consonants), ending_consonant = + apply_modifiers + (hd, ending_consonant) + modifier in + let voyel = change_voyel ((voyel, consonants), ending_consonant) in + + (* Add the last consonant and the voyel *) + let acc = match ending_consonant with + | None -> voyel::acc + | Some s -> + let default = voyel :: acc in + match s with + | None -> default | Some s -> - let default = voyel :: acc in - match s with - | None -> default - | Some s -> - voyel :: s::acc in + voyel :: s::acc in - match consonants with - | None -> _rebuild ~m:[] acc None tl - | Some {ending; opening; following} -> + match consonants with + | None -> _rebuild ~m:[] acc None tl + | Some {ending; opening; following} -> - let acc = match following with - | None -> acc - | Some s -> s::acc in + let acc = match following with + | None -> acc + | Some s -> s::acc in - match opening with - | [] ->_rebuild ~m:[] acc ending tl - | opening -> _rebuild ~m:[] (opening @ acc) ending tl + match opening with + | [] ->_rebuild ~m:[] acc ending tl + | opening -> _rebuild ~m:[] (opening @ acc) ending tl - (** Rebuild the list in the normal order +(** Rebuild the list in the normal order - The voyels have to be choosen, depending either they are followed by a - consonant or not + The voyels have to be choosen, depending either they are followed by a + consonant or not - Some consonants may be changed depending of the following voyel + Some consonants may be changed depending of the following voyel - The list has to be reversed + The list has to be reversed - and so one + and so one - *) - let rebuild - : T.t Modifiers.Sig.consonants option -> group list -> T.t list - = fun ending elems -> - let elems' = match ending with - | None -> elems - | Some _ -> ((T.none, T.none), ending)::elems in - _rebuild ~m:[Modifiers.mute_consonant] [] None elems' +*) +let rebuild + : Sounds.t Modifiers.Sig.consonants option -> group list -> Sounds.t list + = fun ending elems -> + let elems' = match ending with + | None -> elems + | Some _ -> ((Sounds.none, Sounds.none), ending)::elems in + _rebuild ~m:[Modifiers.mute_consonant] [] None elems' -end diff --git a/src/lib/prononciation.mly b/src/lib/prononciation.mly index 31ed8ff..7162b09 100644 --- a/src/lib/prononciation.mly +++ b/src/lib/prononciation.mly @@ -101,7 +101,6 @@ letters | E L { letter_e $1 :: L :: [] } | E L L { E_AGRAVE :: L :: [] } | I L { I :: L :: [] } - | voyel I L L { $1 :: Y :: [] } | I L L { I :: Y :: [] } | L { L :: [] } | M { M :: [] } diff --git a/src/lib/reader.ml b/src/lib/reader.ml index 52339a2..45ea69e 100644 --- a/src/lib/reader.ml +++ b/src/lib/reader.ml @@ -1,7 +1,5 @@ open StdLabels -module P = Parser -module Parser = P.Make(Sounds) module I = Parser.MenhirInterpreter let sound_to_string @@ -9,7 +7,7 @@ let sound_to_string = fun t -> let buff = Buffer.create 16 in List.iter t - ~f:(fun f -> Buffer.add_string buff (Sounds.repr f)); + ~f:(fun f -> Buffer.add_string buff (Sounds.repr (module Sounds.Repr) f)); Buffer.contents buff let succeed (res : Sounds.t list) = diff --git a/src/lib/sounds/repr.ml b/src/lib/sounds/repr.ml index af13e68..72cf95d 100644 --- a/src/lib/sounds/repr.ml +++ b/src/lib/sounds/repr.ml @@ -1,5 +1,7 @@ type t = string +let none = "" + let a = "a" and a_nasal = "@" diff --git a/src/lib/sounds/repr.mli b/src/lib/sounds/repr.mli index 3e2a9c7..7e2e035 100644 --- a/src/lib/sounds/repr.mli +++ b/src/lib/sounds/repr.mli @@ -1,45 +1 @@ -type t = string - -val a : t -val a_nasal : t - -val e_opened : t -val e_closed : t -val schwa : t - -val eu : t - -val o : t -val o_nasal : t - -val i : t -val i_nasal : t - -val y : t -val y_nasal : t - -val u : t -val p : t -val b : t -val t : t -val d : t -val k : t -val g : t -val f : t -val v : t -val ch : t -val j : t -val s : t -val z : t -val m : t -val n : t -val l : t -val r : t - -val semi_voyel_w : t - -val semi_voyel_y : t - -val muted : t -> t - -val diphtongue : t -> t -> t +include Sig.REPR with type t = String.t diff --git a/src/lib/sounds/sig.ml b/src/lib/sounds/sig.ml index 372b888..6b496d2 100644 --- a/src/lib/sounds/sig.ml +++ b/src/lib/sounds/sig.ml @@ -1,4 +1,55 @@ +module type REPR = sig + type t + + val none: t + + val a : t + val a_nasal : t + + val e_opened : t + val e_closed : t + val schwa : t + + val eu : t + + val o : t + val o_nasal : t + + val i : t + val i_nasal : t + + val y : t + val y_nasal : t + + val u : t + val p : t + val b : t + val t : t + val d : t + val k : t + val g : t + val f : t + val v : t + val ch : t + val j : t + val s : t + val z : t + val m : t + val n : t + val l : t + val r : t + + val semi_voyel_w : t + + val semi_voyel_y : t + + val muted : t -> t + + val diphtongue : t -> t -> t +end + module type T = sig + type t val muted : t -> t @@ -66,6 +117,8 @@ module type T = sig val is_voyel : t -> bool val is_nasal : t -> bool - val repr : t -> string + val repr + : (module REPR with type t = 'a) -> t -> 'a end + diff --git a/src/lib/sounds/sounds.ml b/src/lib/sounds/sounds.ml index 92a644f..e5f5d29 100644 --- a/src/lib/sounds/sounds.ml +++ b/src/lib/sounds/sounds.ml @@ -1,4 +1,5 @@ module Sig = Sig +module Repr = Repr type kind = | None @@ -239,14 +240,15 @@ let muted f = code = Muted f } let rec repr - : t -> Repr.t - = fun letter -> + : type a. (module Sig.REPR with type t = a) -> t -> a + = fun m letter -> + let module Repr = (val m:Sig.REPR with type t = a) in match letter.code, letter.nasal with - | None, _ -> "" + | None, _ -> Repr.none | Voyel_A, false -> Repr.a | Voyel_A, true -> Repr.a_nasal - | Voyel_AI, false -> "E" + | Voyel_AI, false -> Repr.e_opened | Voyel_AI, true -> Repr.i_nasal | E_Closed, _ -> Repr.e_closed | E_Opened, true | Voyel_E, true -> Repr.a_nasal @@ -283,5 +285,5 @@ let rec repr | Consonant_N, _ -> Repr.n | Consonant_L, _ -> Repr.l | Consonant_R, _ -> Repr.r - | Diphtonge (l1, l2), _ -> Repr.diphtongue (repr l1) (repr l2) - | Muted t, _ -> Repr.muted (repr t) + | Diphtonge (l1, l2), _ -> Repr.diphtongue (repr m l1) (repr m l2) + | Muted t, _ -> Repr.muted (repr m t) diff --git a/src/lib/sounds/sounds.mli b/src/lib/sounds/sounds.mli index acb3335..8a07db3 100644 --- a/src/lib/sounds/sounds.mli +++ b/src/lib/sounds/sounds.mli @@ -1,4 +1,5 @@ module Sig = Sig +module Repr = Repr type t val muted : t -> t @@ -67,4 +68,5 @@ val semi_voyel_y: t val is_voyel : t -> bool val is_nasal : t -> bool -val repr : t -> string +val repr + : (module Sig.REPR with type t = 'a) -> t -> 'a -- cgit v1.2.3