From 6a34154b77ac80f89df816ba0062f382d915fb22 Mon Sep 17 00:00:00 2001
From: Sébastien Dailly <sebastien@chimrod.com>
Date: Sun, 5 Sep 2021 19:41:40 +0200
Subject: Updated tests

---
 src/application/application.ml | 49 ++++++++++++++++++++++++++++++++++++++++++
 src/application/dune           |  7 ++++++
 src/lib/lexer.mll              |  1 +
 src/lib/modifiers/e.ml         | 18 +++++++++++++---
 src/lib/modifiers/modifiers.ml |  1 +
 src/lib/modifiers/mute.ml      |  2 +-
 src/lib/modifiers/nasal.ml     |  2 +-
 src/lib/modifiers/sig.ml       | 10 ++++-----
 src/lib/parser.mly             | 35 ++++++++++++++++++++----------
 src/lib/process.ml             | 14 ++++++------
 src/lib/prononciation.mly      | 10 ++++++---
 src/lib/repr/default.ml        |  2 ++
 src/lib/sounds/sig.ml          |  1 +
 src/lib/sounds/sounds.ml       |  7 ++++++
 src/lib/sounds/sounds.mli      |  1 +
 src/lib/tokens.mly             |  4 ----
 src/test/test.ml               | 19 ++++++++++++----
 17 files changed, 143 insertions(+), 40 deletions(-)
 create mode 100755 src/application/application.ml
 create mode 100755 src/application/dune

(limited to 'src')

diff --git a/src/application/application.ml b/src/application/application.ml
new file mode 100755
index 0000000..01724ac
--- /dev/null
+++ b/src/application/application.ml
@@ -0,0 +1,49 @@
+(** The Make module build the main application loop.contents
+
+    The function [run] update the state on each event, and return a new state.
+    Each event must follow the [event] type, which is composed from the type
+    [t], and a module with a fonction [update].
+
+    This example create an application with the state containing a simple
+    counter. An even which increment this counter is created and can be used to
+    update the state.
+
+
+    [
+        type state = { value : int }
+
+        (** Increment the state *)
+        module Incr = struct
+            type t = unit
+
+            let update () state = { value = state.value + 1 }
+        end
+
+        module App = Make(struct type t = state end)
+
+        (* Create the event itself *)
+        let incr_event = App.E ((), (module Incr:App.Event with type t = Incr.t))
+
+    ]
+
+*)
+module Make(S:sig type t end) = struct
+  module type Event = sig
+
+    type t
+
+    val update: t -> S.t -> S.t
+
+  end
+
+  type event = E : 'a * (module Event with type t = 'a) -> event
+
+  (** Simple helper for the main event loop *)
+  let run
+    : ?eq:(S.t -> S.t -> bool) -> S.t -> event Note.E.t -> S.t Note.S.t
+    = fun ?eq init event ->
+      let action = Note.E.map (fun (E (t, (module Event))) st -> Event.update t st) event in
+      Note.S.accum ?eq init action
+end
+
+
diff --git a/src/application/dune b/src/application/dune
new file mode 100755
index 0000000..77eb6b9
--- /dev/null
+++ b/src/application/dune
@@ -0,0 +1,7 @@
+(library
+ (name application)
+ (libraries 
+   brr
+   brr.note
+   )
+ )
diff --git a/src/lib/lexer.mll b/src/lib/lexer.mll
index 0e9cebf..50c25a7 100644
--- a/src/lib/lexer.mll
+++ b/src/lib/lexer.mll
@@ -17,6 +17,7 @@ rule letter = parse
 | 'e'            { E Accent.NONE }
 | '\232'         { E Accent.ACUTE }
 | "è"            { E Accent.AGRAVE }
+| "ê"            { E Accent.AGRAVE }
 | '\233'         { E Accent.ACUTE }
 | "é"            { E Accent.ACUTE }
 | 'f'            { F }
diff --git a/src/lib/modifiers/e.ml b/src/lib/modifiers/e.ml
index 8fd65bf..5f6e6fe 100644
--- a/src/lib/modifiers/e.ml
+++ b/src/lib/modifiers/e.ml
@@ -2,14 +2,26 @@
 let process
   : 'a Sig.modifier
   = fun init ->
-    let ((v2, c) , ending) = init in
+    let ((v, c) , ending) = init in
 
     match ending with
-    | None when v2 = Sounds.schwa ->
+    | None when v = Sounds.schwa ->
       (* If there is no more consononant in the syllabe, change the e
          into eu, like in sera *)
       ((Sounds.eu `Closed, c) , ending)
-    | Some _ when v2 = Sounds.schwa ->
+    | Some _ when v = Sounds.schwa ->
+      (* If there is an ending consonant, change the e into E like essai *)
+      ((Sounds.e `Opened, c) , ending)
+    | _ -> init
+
+(** Transform the final e into E if there is a consonant *)
+let ending_e
+  : 'a Sig.modifier
+  = fun init ->
+    let ((v, c) , ending) = init in
+
+    match ending with
+    | Some _ when v = Sounds.schwa ->
       (* If there is an ending consonant, change the e into E like essai *)
       ((Sounds.e `Opened, c) , ending)
     | _ -> init
diff --git a/src/lib/modifiers/modifiers.ml b/src/lib/modifiers/modifiers.ml
index 3a9ecd6..4e58cba 100644
--- a/src/lib/modifiers/modifiers.ml
+++ b/src/lib/modifiers/modifiers.ml
@@ -4,3 +4,4 @@ let nasal = Nasal.process
 let vocalize_s = Vocalize.process
 let mute_consonant = Mute.process
 let e = E.process
+let ending_e = E.ending_e
diff --git a/src/lib/modifiers/mute.ml b/src/lib/modifiers/mute.ml
index b89fda7..7b58336 100644
--- a/src/lib/modifiers/mute.ml
+++ b/src/lib/modifiers/mute.ml
@@ -1,6 +1,6 @@
 open StdLabels
 
-(** Mute the last consonant if there is no voyel in the syllabus.
+(** Mute the last consonant if there is no voyel in the syllabe.
 
     This modifier is only applied in the first step, and not repeated anymore.
 *)
diff --git a/src/lib/modifiers/nasal.ml b/src/lib/modifiers/nasal.ml
index cc29efc..43f3bd8 100644
--- a/src/lib/modifiers/nasal.ml
+++ b/src/lib/modifiers/nasal.ml
@@ -1,7 +1,7 @@
 (* Remove the ending consonant, and transform the voyel into
    the nasal form  *)
 let transform
-  : Sounds.t Sig.consonants option -> Sounds.t Sig.t -> Sounds.t Sig.t
+  : Sig.consonants option -> Sounds.t Sig.t -> Sounds.t Sig.t
   = fun c init ->
     let ((v, _) , _) = init in
 
diff --git a/src/lib/modifiers/sig.ml b/src/lib/modifiers/sig.ml
index 5f82620..19c4ff7 100644
--- a/src/lib/modifiers/sig.ml
+++ b/src/lib/modifiers/sig.ml
@@ -1,11 +1,11 @@
 type voyel = Sounds.t
 
-type 'a consonants =
-  { ending : 'a option option
-  ; opening : 'a list
-  ; following : 'a option }
+type consonants =
+  { ending : Sounds.t option option
+  ; opening : Sounds.t list
+  ; following : Sounds.t option }
 
-type 'a group = voyel * 'a consonants option
+type 'a group = voyel * consonants option
 
 type 'a t = 'a group * 'a option option
 
diff --git a/src/lib/parser.mly b/src/lib/parser.mly
index e5e6773..8fe4a55 100644
--- a/src/lib/parser.mly
+++ b/src/lib/parser.mly
@@ -11,7 +11,7 @@ See [1] for the theory behind the analysis
 
 
 %{
-
+    open Modifiers.Sig
 
 %}
 %start<Sounds.t List.t> main
@@ -51,6 +51,7 @@ liquid:
 nasal:
   | N               { Sounds.n }
   | M               { Sounds.m }
+  | G N             { Sounds.gn }
 
 consonant: 
   | occlusiv        { $1 }
@@ -69,7 +70,8 @@ opening_consonant:
   | liquid              { $1, None }
   | obstruent liquid    { $1, Some $2 }
   | occlusiv fricativ   { $1, Some $2 }
-  | consonant semi_voyel{ $1, Some $2 }
+
+semi:
   | semi_voyel          { $1, None }
 
 
@@ -87,6 +89,9 @@ voyels:
   | O               { Sounds.o          }
   | U               { Sounds.voyel_y    }
   | OU              { Sounds.voyel_u    }
+
+voyels_semi:
+  | voyels          { $1 }
   | W A             { Sounds.diphtongue Sounds.semi_voyel_w Sounds.a}
   | W I             { Sounds.diphtongue Sounds.semi_voyel_w Sounds.i}
   | I E             { Sounds.diphtongue Sounds.i (Sounds.e `Opened) }
@@ -96,18 +101,20 @@ ending_consonant:
   | B               { Some (Sounds.b ) }
   | T               { Some (Sounds.t )}
   | K               { Some (Sounds.k)}
+  | G               { Some (Sounds.g)}
   | liquid          { Some $1 }
   | nasal           { Some $1 }
 
-consonant_group:
-  | f = fricativ
-    o = opening_consonant 
+
+%inline consonant_group(opening)
+  : f = fricativ
+    o = opening 
     { 
         { ending = None 
         ; opening = f::(fst o)::[]
         ; following = snd o  }
     }
-  | o = opening_consonant 
+  | o = opening 
     { 
         { ending = None 
         ; opening = [ fst o ]
@@ -115,7 +122,7 @@ consonant_group:
     }
   | e = ending_consonant
     Sep?
-    o = opening_consonant 
+    o = opening
     { 
         { ending = Some e
         ; opening = [ fst o ]
@@ -124,18 +131,24 @@ consonant_group:
   | e = ending_consonant
     Sep?
     f = fricativ
-    o = opening_consonant 
+    o = opening
     { 
         { ending = Some e
         ; opening = f::[ fst o ]
         ; following = snd o }
     }
 
+
+(** Exclude a semi voyel in both consonant and voyel position *)
 syllable:
-  | c = consonant_group?
-    v = voyels
+  | c = consonant_group(opening_consonant)?
+    v = voyels_semi
     Sep?
     { (v, c) }
+  | c = consonant_group(semi)
+    v = voyels
+    Sep?
+    { (v, Some c) }
 
 
 syllables:
@@ -145,7 +158,7 @@ syllables:
     
 
 word:
-  | Sep? syllables consonant_group? EOL { Process.rebuild $3 $2 }
+  | Sep? syllables consonant_group(opening_consonant)? EOL { Process.rebuild $3 $2 }
 
 main: 
   | word { $1 }
diff --git a/src/lib/process.ml b/src/lib/process.ml
index f85853f..d6ad291 100644
--- a/src/lib/process.ml
+++ b/src/lib/process.ml
@@ -2,7 +2,7 @@ open StdLabels
 
 type voyel = Sounds.t
 
-type group = voyel * Sounds.t Modifiers.Sig.consonants option
+type group = voyel * Modifiers.Sig.consonants option
 type modifier = Sounds.t Modifiers.Sig.modifier
 
 (** Apply all the modifiers to the syllabic group in order to correct the
@@ -41,9 +41,9 @@ let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> Sounds.
           | Some s ->
             voyel :: s::acc  in
 
-      (* Apply the modifiers to the previous syllabus.
+      (* Apply the modifiers to the previous syllabe.
 
-         Only transform the e into eu / E if there is previous syllabus with
+         Only transform the e into eu / E if there is previous syllabe with
          voyel. *)
       let modifiers = if voyel = Sounds.none then
           []
@@ -75,10 +75,8 @@ let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> Sounds.
 
 *)
 let rebuild
-  : Sounds.t Modifiers.Sig.consonants option -> group list -> Sounds.t list
+  : Modifiers.Sig.consonants option -> group list -> Sounds.t list
   = fun  ending elems ->
-    let elems' = match ending with
-      | None -> elems
-      | Some _ -> (Sounds.none, ending)::elems in
-    _rebuild ~m:[Modifiers.mute_consonant] [] None elems'
+    let elems' = (Sounds.none, ending)::elems in
+    _rebuild ~m:[Modifiers.mute_consonant;Modifiers.ending_e;] [] None elems'
 
diff --git a/src/lib/prononciation.mly b/src/lib/prononciation.mly
index 65e203c..d367170 100644
--- a/src/lib/prononciation.mly
+++ b/src/lib/prononciation.mly
@@ -58,20 +58,23 @@
 %start<Tokens.token list> main
 %%
 
-
-voyel
+voyel_without_i
   : A           { A }
   | E           { letter_e $1 }
-  | I           { I }
   | O           { O }
   | A U         { O }
   | E A U       { O }
   | O U         { OU }
   | U           { U }
 
+voyel
+  : I           { I }
+  | voyel_without_i { $1 }
+
 
 letters
   : voyel  { $1 :: [] }
+  | voyel_without_i I { $1 :: I :: []} 
   | Space   { Space :: [] }
   | Sep     { Sep :: [] }
 
@@ -101,6 +104,7 @@ letters
   | L L     { Nothing :: L :: [] }
   | I L     { I :: L :: [] }
   | I L L   { I :: Y :: [] }
+  | voyel_without_i I L L   { $1 :: Y :: [] }
   | L       { L :: [] }
   | M       { M :: [] }
   | M M     { M :: [] }
diff --git a/src/lib/repr/default.ml b/src/lib/repr/default.ml
index 4110679..2688411 100644
--- a/src/lib/repr/default.ml
+++ b/src/lib/repr/default.ml
@@ -44,6 +44,8 @@ and z = "z"
 and m = "m"
 and n = "n"
 
+and gn = "N"
+
 and l = "L"
 and r = "R"
 
diff --git a/src/lib/sounds/sig.ml b/src/lib/sounds/sig.ml
index 5322a12..016c757 100644
--- a/src/lib/sounds/sig.ml
+++ b/src/lib/sounds/sig.ml
@@ -37,6 +37,7 @@ module type REPR = sig
   val z : t
   val m : t
   val n : t
+  val gn : t
   val l : t
   val r : t
 
diff --git a/src/lib/sounds/sounds.ml b/src/lib/sounds/sounds.ml
index afaf110..58d511b 100644
--- a/src/lib/sounds/sounds.ml
+++ b/src/lib/sounds/sounds.ml
@@ -36,6 +36,7 @@ type code =
 
   | Consonant_M
   | Consonant_N
+  | Consonant_GN
   | Consonant_L
   | Consonant_R
   | Diphtonge of t * t
@@ -168,6 +169,11 @@ let j =
     code = Consonant_J
   ; mutable_ = false }
 
+let gn =
+  { none with
+    code = Consonant_GN
+  ; nasal = true }
+
 let n =
   { none with
     code = Consonant_N
@@ -287,6 +293,7 @@ let repr
 
       | Consonant_M, _ -> Repr.m
       | Consonant_N, _ -> Repr.n
+      | Consonant_GN, _ -> Repr.gn
       | Consonant_L, _ -> Repr.l
       | Consonant_R, _ -> Repr.r
       | Diphtonge (l1, l2), _ -> Repr.diphtongue (_repr l1) (_repr l2)
diff --git a/src/lib/sounds/sounds.mli b/src/lib/sounds/sounds.mli
index 2fae17f..4f0bbc1 100644
--- a/src/lib/sounds/sounds.mli
+++ b/src/lib/sounds/sounds.mli
@@ -60,6 +60,7 @@ val ch: t
 val j: t
 
 val n: t
+val gn: t
 val m: t
 
 val r: t
diff --git a/src/lib/tokens.mly b/src/lib/tokens.mly
index ea1493a..35c8e1d 100644
--- a/src/lib/tokens.mly
+++ b/src/lib/tokens.mly
@@ -3,14 +3,12 @@
 %token Nothing
 %token A
 %token B
-%token C
 %token D
 %token E
 %token E_ACUTE
 %token E_AGRAVE
 %token F
 %token G
-%token H
 %token I
 %token J
 %token K
@@ -19,7 +17,6 @@
 %token N
 %token O
 %token OU
-%token Q
 %token P
 %token R
 %token S
@@ -35,7 +32,6 @@
 %token EOL
 
 %nonassoc Low
-%left R
 %right High
 
 %%
diff --git a/src/test/test.ml b/src/test/test.ml
index 2964127..060e829 100644
--- a/src/test/test.ml
+++ b/src/test/test.ml
@@ -8,6 +8,11 @@ let process (optional_line : string option) expected =
   | None -> ()
   | Some line ->
     match T.Reader.process line with
+    | exception _ ->
+      error := 1;
+      Printf.fprintf stdout
+        "%s : error \n%!"
+        line
     | Error result ->
       error := 1;
       Printf.fprintf stdout
@@ -46,6 +51,8 @@ let tests =
   ; "abaissées",    "abEse(s)"
   ; "abaissera",    "abEs2Ra"
   ; "achat",        "aSa(t)"
+  ; "agneau",       "aNo"
+  ; "aimes",        "Em°(s)"
   ; "aiment",       "Em°(t)"
   ; "anniversaire", "anivERsER°"
   ; "anta",         "@ta"
@@ -69,14 +76,16 @@ let tests =
   ; "co|incidant",  "ko5sid@(t)"
   ; "croire",       "kR[wa]R°"
   ; "demeure",      "d2m9R°"
+  ; "diag|nostic",  "diagnostik"
   ; "ébrouas",      "ebRua(s)"
-  ; "effroi",       "EfRwa"
+  ; "effroi",       "EfR[wa]"
   ; "em|magasinais","@magazinE(s)"
   ; "essai",        "EsE"
   ; "extra",        "EkstRa"
   ; "famille",      "famij°"
+  ; "feuille",      "f9j°"
   ; "final",        "finaL"
-  ; "loin",         "Lw5"
+  ; "loin",         "L[w5]"
   ; "groin",        "gR[w5]"
   ; "hirondelle",   "iR§dEL°"
   ; "joues",        "Zu°(s)"
@@ -96,18 +105,20 @@ let tests =
   ; "platte",       "pLat°"
   ; "soin",         "sw5"
   ; "souris",       "suRi(s)"
-  ; "toiture",      "twatyR°"
+  ; "toiture",      "t[wa]tyR°"
   ; "trois",        "tR[wa](s)"
-  ; "veillons",     "vEj§(s)"
   ; "vil|le",       "viLL°"
   ; "wèb",          "wEb"
   ]
 
 let () =
+  let n = ref 0 in
   let () = List.iter tests
       ~f:(fun (input, expected) ->
+          incr n;
           repeat (Lexing.from_string input) expected)
   in
 
+  Printf.printf "Runned %d tests. Got %d errors\n" (!n) (!error);
   exit !error
 
-- 
cgit v1.2.3