(* See [1] for the theory behind the analysis [1] https://fr.m.wiktionary.org/wiki/Annexe:Prononciation/fran%C3%A7ais#Structure_syllabique *) %{ open Modifiers.Sig %} %start main %% occlusiv: | P { Sounds.p } | B { Sounds.b } | T { Sounds.t } | D { Sounds.d } | K { Sounds.k } | G { Sounds.g } fricativ: | S { Sounds.s } | SZ { Sounds.sz } | Z { Sounds.z } | F { Sounds.f } | V { Sounds.v } | X { Sounds.ch } | J { Sounds.j } obstruent: | occlusiv { $1 } | fricativ { $1 } liquid: | L { Sounds.l } | R { Sounds.r } nasal: | N { Sounds.n } | M { Sounds.m } initial_nasal: | nasal { $1 } | G N { Sounds.gn } opening_consonant: | occlusiv { $1, None } | fricativ { $1, None } | initial_nasal { $1, None } | liquid { $1, None } opening_double: | obstruent liquid { $1, Some $2 } | occlusiv fricativ { $1, Some $2 } (* Each voyel as two associated sounds, depending there is a followng sound or not *) voyels: | A { Sounds.a } | A I { Sounds.voyel_ai } | E I { Sounds.voyel_ai } | I { Sounds.i } | E { Sounds.schwa } | E_ACUTE E? { Sounds.e `Closed } | E_AGRAVE { Sounds.e `Opened } | E U { Sounds.eu `Opened } | O { Sounds.o } | U { Sounds.voyel_y } | OU { Sounds.voyel_u } (* This semi voyel can never be separated *) | W voyels { Sounds.diphtongue Sounds.semi_voyel_w $2 } voyels_semi: | voyels { $1 } | I voyels { Sounds.diphtongue Sounds.semi_voyel_y $2 } | Y voyels { Sounds.diphtongue Sounds.semi_voyel_y $2 } | U voyels { Sounds.diphtongue Sounds.semi_voyel_u $2 } ending_consonant: | Nothing { Some (Sounds.none) } | occlusiv { Some $1 } | liquid { Some $1 } | nasal { Some $1 } %inline consonant_group(opening) : f = fricativ o = opening { { ending = None ; opening = f::(fst o)::[] ; following = snd o } } | o = opening { { ending = None ; opening = [ fst o ] ; following = snd o } } | e = ending_consonant Sep? o = opening { { ending = Some e ; opening = [ fst o ] ; following = snd o } } | e = ending_consonant Sep? f = fricativ 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(opening_consonant)? v = voyels_semi Sep? { (v, c) } | c = consonant_group(opening_double) v = voyels Sep? { (v, Some c) } syllables: | { [] } | ss = syllables s = syllable { s::ss } word: | Sep? syllables consonant_group(opening_consonant)? { Process.rebuild $3 $2 } words: | word { $1::[] } | ww=words Space w=word { w:: [Sounds.space $2] ::ww } main: | words EOL { List.concat (List.rev $1) }