Skip to main content

dahufi_lib/
parser.rs

1use crate::dict;
2use gobble::*;
3
4parser! { (Converter ->String)
5    chars_until(Letter, eoi).map(|(a, _b)| a)
6}
7
8parser! { (EnStringPos -> ())
9    ((Alpha,NumDigit).iplus(),(Alpha,NumDigit,BothAllow).istar()).ig()
10}
11parser! { (MiStringPos -> ())
12    ((MiChar,NumDigit).iplus(),(MiChar,NumDigit,BothAllow).istar()).ig()
13}
14
15parser! { (Extra->String)
16    ("(",(Alpha,NumDigit,WS,MiChar).star(),")").map(|(_,s,_)|s)
17}
18parser! { (MiEntry->String)
19    (string(MiStringPos),maybe(Extra)).map(|(m,e_op)|
20        match e_op {
21            Some(ex)=>format!("{} ({})",m.trim(),ex.trim()),
22            None=>m.trim().to_string(),
23        }
24    )
25}
26parser! { (EnEntry->String)
27    (string(EnStringPos),maybe(Extra)).map(|(m,e_op)|
28        match e_op {
29            Some(ex)=>format!("{} ({})",m.trim(),ex.trim()),
30            None=>m.trim().to_string(),
31        }
32    )
33}
34
35parser! { (Record->dict::Record)
36    or(
37        (ws_(EnEntry),":" ,ws_(MiEntry)).map(|(english,_,michuhu)| dict::Record{english,michuhu}),
38        (ws_(MiEntry),":" ,ws_(EnEntry)).map(|(michuhu,_,english)| dict::Record{english,michuhu})
39    )
40}
41
42parser! { (EmptyLine ->())
43    (Any.except("\n|").istar(),"\n|".one()).ig()
44}
45
46parser! { (RecordLine->dict::Record)
47    middle(
48        maybe(or_ig!("*",(NumDigit.star(),"."))),
49        Record,
50        (maybe(ws__(",")),"\n|".one()),
51    )
52}
53
54parser! { (NextRecord->dict::Record)
55    star_until(EmptyLine,RecordLine).map(|(_,v)|v)
56}
57
58parser! { (Dict->dict::TwoWayMap)
59    (star(NextRecord),star(EmptyLine),ws_(eoi))
60        .map(|(v,_,_)|{
61            let mut res = dict::TwoWayMap::new();
62            for r in v{
63                res.insert(r);
64            }
65            res
66       })
67}
68
69parser! {(Letter->char)
70    or(MLetter,Any.one())
71}
72
73fn consonant(s: &str) -> u32 {
74    match s {
75        "k" => 0xe000,
76        "d" => 0xe001,
77        "ch" | "c" => 0xe002,
78        "s" => 0xe003,
79        "y" => 0xe004,
80        "h" => 0xe005,
81        "f" => 0xe006,
82        "w" => 0xe007,
83        "m" => 0xe008,
84        "j" => 0xe009,
85        "b" => 0xe00a,
86        "n" => 0xe00b,
87        "th" | "t" => 0xe00c,
88        "fl" | "v" => 0xe00d,
89        "l" => 0xe055,
90        "cl" => 0xe056,
91        "bl" => 0xe057,
92        "sh" | "z" => 0xe058,
93        _ => 0xe001,
94    }
95}
96
97fn vowel(c: char) -> u32 {
98    match c {
99        'a' => 14,
100        'b' => 14 * 2,
101        'c' => 14 * 3,
102        'u' => 14 * 4,
103        _ => 0,
104    }
105}
106
107parser! {( MLetter->char)
108    or!(
109        (MCons,maybe(MVowel)).map(|(k,vop)|{
110            std::char::from_u32( consonant(k)+vop.map(|v|vowel(v)).unwrap_or(0)).unwrap_or('#')
111        }),
112        MVowel.map(|v| std::char::from_u32(0xe054 + vowel(v) ).unwrap_or('#'))
113    )
114}
115
116parser! { (MCons->&'static str)
117    or!("cl","k","d","ch","c","sh","s","y","h","fl","v","f","w","m","j","bl","b","n","th","t","l","z")
118}
119
120parser! { (MVowel->char)
121    or!('a','i','o','u')
122}
123
124char_bool!(MiChar, |c| c >= '' && c <= '');
125char_bool!(BothAllow, "?&/ \t~-");