1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::{anychar, multispace1, newline};
use nom::combinator::{map, recognize, value};
use nom::error::{ErrorKind, VerboseError, VerboseErrorKind};
use nom::multi::fold_many0;
use nom::{Err as NomErr, IResult};
pub type ParserResult<'a, O> = IResult<&'a str, O, VerboseError<&'a str>>;
pub fn cnst<'a, T, E>(t: T) -> impl Fn(&'a str) -> Result<(&'a str, T), E>
where
T: 'a + Clone,
{
move |i| Ok((i, t.clone()))
}
pub fn eoi(i: &str) -> ParserResult<()> {
if i.is_empty() {
Ok((i, ()))
} else {
Err(NomErr::Error(VerboseError {
errors: vec![(i, VerboseErrorKind::Nom(ErrorKind::Eof))],
}))
}
}
pub fn eol(i: &str) -> ParserResult<()> {
alt((
eoi,
value((), newline),
))(i)
}
pub fn till<'a, A, B, F, G>(f: F, g: G) -> impl Fn(&'a str) -> ParserResult<'a, ()>
where
F: Fn(&'a str) -> ParserResult<'a, A>,
G: Fn(&'a str) -> ParserResult<'a, B>,
{
move |mut i| loop {
if let Ok((i2, _)) = g(i) {
break Ok((i2, ()));
}
let (i2, _) = f(i)?;
i = i2;
}
}
pub fn many0_<'a, A, F>(f: F) -> impl Fn(&'a str) -> ParserResult<'a, ()>
where
F: Fn(&'a str) -> ParserResult<'a, A>,
{
move |i| fold_many0(&f, (), |_, _| ())(i)
}
pub fn str_till_eol(i: &str) -> ParserResult<&str> {
map(
recognize(till(alt((value((), tag("\\\n")), value((), anychar))), eol)),
|i| {
if i.as_bytes().last() == Some(&b'\n') {
&i[0..i.len() - 1]
} else {
i
}
},
)(i)
}
pub fn blank_space(i: &str) -> ParserResult<&str> {
recognize(many0_(alt((multispace1, tag("\\\n")))))(i)
}