nessie_parse/
parser.rs

1use crate::position::Pos;
2use crate::state::State;
3use crate::{CombineFail, CombineManyFail};
4
5use std::rc::Rc;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum ParseResult<T, E, F = ()> {
9    /// Called on a successful parse!
10    Ok(T, Pos),
11    /// The parser could not parse the input, perhaps another parser could.
12    /// (This is used to implement backtracking)
13    Fail(F, Pos),
14    /// The parser expected it could succeed, but it did not.
15    Err(E, Pos),
16}
17
18/// A parser is a function from a `State` to a `ParseResult`.
19/// The `T` type is the type of the value produced by the parser, the `E` is the
20/// type of the errors it can produce. `F` is the type of failure - this is like
21/// an error, but made to be used for backtracking. It is optional.
22/// The `'a` lifetime is the lifetime of the parser.
23pub struct Parser<'a, T, E, F = ()> {
24    /// This name is useful for debugging.
25    pub(crate) name: Rc<String>,
26    // Maybe here we might want to use a different lifetime?  --v
27    parse: Rc<dyn Fn(State<'a>) -> ParseResult<T, E, F> + 'a>,
28}
29
30impl<T, E, F> std::fmt::Debug for Parser<'_, T, E, F> {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        let name = self.name.as_ref();
33        write!(f, "Parser(\"{name}\")")
34    }
35}
36
37// Need an explicit clone implementation because the #[derive(Clone)] adds
38// constraints `T: Clone` and such that are unneeded!
39impl<'a, T, E, F> Clone for Parser<'a, T, E, F> {
40    fn clone(&self) -> Self {
41        Self {
42            name: self.name.clone(),
43            parse: self.parse.clone(),
44        }
45    }
46}
47
48impl<'a, T, E, F> Parser<'a, T, E, F> {
49    // Here `T` is bound by `'a` because we are storing a `T` in the returned
50    // parser.
51    pub fn ret(value: T) -> Self
52    where
53        T: Clone + 'a,
54    {
55        Parser {
56            name: Rc::new("ret".to_string()),
57            parse: Rc::new(move |state| ParseResult::Ok(value.clone(), state.pos)),
58        }
59    }
60
61    pub fn ret_with(value: impl Fn() -> T + 'a) -> Self {
62        Parser {
63            name: Rc::new("ret_with".to_string()),
64            parse: Rc::new(move |state| ParseResult::Ok(value(), state.pos)),
65        }
66    }
67
68    pub fn fail(value: F) -> Self
69    where
70        F: Clone + 'a,
71    {
72        Parser {
73            name: Rc::new("fail".to_string()),
74            parse: Rc::new(move |state| ParseResult::Fail(value.clone(), state.pos)),
75        }
76    }
77
78    pub fn fail_with(value: impl Fn() -> F + 'a) -> Self {
79        Parser {
80            name: Rc::new("fail_with".to_string()),
81            parse: Rc::new(move |state| ParseResult::Fail(value(), state.pos)),
82        }
83    }
84
85    pub fn err(value: E) -> Self
86    where
87        E: Clone + 'a,
88    {
89        Parser {
90            name: Rc::new("err".to_string()),
91            parse: Rc::new(move |state| ParseResult::Err(value.clone(), state.pos)),
92        }
93    }
94
95    pub fn err_with(value: impl Fn() -> E + 'a) -> Self {
96        Parser {
97            name: Rc::new("err_with".to_string()),
98            parse: Rc::new(move |state| ParseResult::Err(value(), state.pos)),
99        }
100    }
101
102    pub fn from_fn<Func>(func: Func) -> Self
103    where
104        Func: Fn(State<'a>) -> ParseResult<T, E, F> + 'a,
105    {
106        Parser {
107            name: Rc::new("from_fn".to_string()),
108            parse: Rc::new(func),
109        }
110    }
111
112    pub fn parse(&self, state: State<'a>) -> ParseResult<T, E, F> {
113        (self.parse)(state)
114    }
115
116    // More advanced constructors and combinators.
117
118    /// This is useful for debugging parsers.
119    pub fn with_name(mut self, name: impl Into<String>) -> Self {
120        self.name = Rc::new(name.into());
121        self
122    }
123
124    pub fn map<U>(self, f: impl Fn(T) -> U + 'a) -> Parser<'a, U, E, F>
125    where
126        F: 'a,
127        E: 'a,
128        T: 'a,
129    {
130        let name = format!("map({})", self.name);
131        Parser::from_fn(move |state| match self.parse(state) {
132            ParseResult::Ok(value, pos) => ParseResult::Ok(f(value), pos),
133            ParseResult::Fail(fail_value, pos) => ParseResult::Fail(fail_value, pos),
134            ParseResult::Err(err_value, pos) => ParseResult::Err(err_value, pos),
135        })
136        .with_name(name)
137    }
138
139    pub fn map_fail<G>(self, f: impl Fn(F) -> G + 'a) -> Parser<'a, T, E, G>
140    where
141        F: 'a,
142        E: 'a,
143        T: 'a,
144    {
145        let name = format!("map_fail({})", self.name);
146        Parser::from_fn(move |state| match self.parse(state) {
147            ParseResult::Ok(value, pos) => ParseResult::Ok(value, pos),
148            ParseResult::Fail(fail_value, pos) => ParseResult::Fail(f(fail_value), pos),
149            ParseResult::Err(err_value, pos) => ParseResult::Err(err_value, pos),
150        })
151        .with_name(name)
152    }
153
154    pub fn map_err<E2>(self, f: impl Fn(E) -> E2 + 'a) -> Parser<'a, T, E2, F>
155    where
156        F: 'a,
157        E: 'a,
158        T: 'a,
159    {
160        let name = format!("map_err({})", self.name);
161        Parser::from_fn(move |state| match self.parse(state) {
162            ParseResult::Ok(value, pos) => ParseResult::Ok(value, pos),
163            ParseResult::Fail(fail_value, pos) => ParseResult::Fail(fail_value, pos),
164            ParseResult::Err(err_value, pos) => ParseResult::Err(f(err_value), pos),
165        })
166        .with_name(name)
167    }
168
169    pub fn and_then<U, Func>(self, func: Func) -> Parser<'a, U, E, F>
170    where
171        Func: Fn(T) -> Parser<'a, U, E, F> + 'a,
172        F: 'a,
173        E: 'a,
174        T: 'a,
175    {
176        let name = format!("and_then({})", self.name);
177        Parser::from_fn(move |state| match self.parse(state) {
178            ParseResult::Ok(value, pos) => func(value).parse(state.with_pos(pos)),
179            ParseResult::Fail(fail_value, pos) => ParseResult::Fail(fail_value, pos),
180            ParseResult::Err(err_value, pos) => ParseResult::Err(err_value, pos),
181        })
182        .with_name(name)
183    }
184
185    /// This is like `and_then`, but the next parser is called when the first
186    /// parser fails.
187    /// Unlike `and_then`, the next parser is started at the same position as
188    /// the first parser (not at the position that it stopped).
189    pub fn and_then_fail<G, Func>(self, func: Func) -> Parser<'a, T, E, G>
190    where
191        Func: Fn(F) -> Parser<'a, T, E, G> + 'a,
192        F: 'a,
193        E: 'a,
194        T: 'a,
195    {
196        let name = format!("and_then_fail({})", self.name);
197        Parser::from_fn(move |state| match self.parse(state) {
198            ParseResult::Ok(value, pos) => ParseResult::Ok(value, pos),
199            ParseResult::Fail(fail_value, _) => func(fail_value).parse(state),
200            ParseResult::Err(err_value, pos) => ParseResult::Err(err_value, pos),
201        })
202        .with_name(name)
203    }
204
205    /// This is like `and_then`, but the next parser is called when the first
206    /// parser returns an error (Notice - this is different from failure).
207    /// Unlike `and_then`, the next parser is started at the same position as
208    /// the first parser (not at the position that it stopped).
209    pub fn and_then_err<E2, Func>(self, func: Func) -> Parser<'a, T, E2, F>
210    where
211        Func: Fn(E) -> Parser<'a, T, E2, F> + 'a,
212        F: 'a,
213        E: 'a,
214        T: 'a,
215    {
216        let name = format!("and_then_err({})", self.name);
217        Parser::from_fn(move |state| match self.parse(state) {
218            ParseResult::Ok(value, pos) => ParseResult::Ok(value, pos),
219            ParseResult::Fail(fail_value, pos) => ParseResult::Fail(fail_value, pos),
220            ParseResult::Err(err_value, _) => func(err_value).parse(state),
221        })
222        .with_name(name)
223    }
224
225    pub fn or<G, H>(self, other: Parser<'a, T, E, G>) -> Parser<'a, T, E, H>
226    where
227        T: 'a,
228        E: 'a,
229        F: 'a,
230        G: 'a,
231        F: CombineFail<'a, G, H>,
232    {
233        let name = format!("or({} | {})", self.name, other.name);
234        Parser::from_fn(move |state| match self.parse(state) {
235            ParseResult::Ok(value, pos) => ParseResult::Ok(value, pos),
236            ParseResult::Fail(f1, f1_pos) => {
237                match other.parse(state) {
238                    ParseResult::Ok(value, pos) => ParseResult::Ok(value, pos),
239                    ParseResult::Fail(f2, f2_pos) => {
240                        let f =
241                            F::combine_fail(f1, state.with_pos(f1_pos), f2, state.with_pos(f2_pos));
242                        // The position of the failure will just be at the start
243                        ParseResult::Fail(f, state.pos)
244                    }
245                    ParseResult::Err(err_value, pos) => ParseResult::Err(err_value, pos),
246                }
247            }
248            ParseResult::Err(err_value, pos) => ParseResult::Err(err_value, pos),
249        })
250        .with_name(name)
251    }
252
253    pub fn or_ret<G>(self, x: T) -> Parser<'a, T, E, G>
254    where
255        T: Clone + 'a,
256        E: 'a,
257        F: 'a,
258        G: 'a,
259    {
260        self.or(Parser::ret(x)).map_fail(|(_, f)| f)
261    }
262
263    pub fn or_fail<G>(self, f: G) -> Parser<'a, T, E, G>
264    where
265        T: 'a,
266        E: 'a,
267        F: 'a,
268        G: Clone + 'a,
269    {
270        self.map_fail(move |_| f.clone())
271    }
272
273    pub fn or_err<G>(self, e: E) -> Parser<'a, T, E, G>
274    where
275        T: 'a,
276        E: Clone + 'a,
277        F: 'a,
278        G: 'a,
279    {
280        self.or(Parser::err(e)).map_fail(|(_f, g)| g)
281    }
282
283    pub fn one_of<G>(
284        parsers: impl IntoIterator<Item = Parser<'a, T, E, F>> + 'a,
285    ) -> Parser<'a, T, E, G>
286    where
287        T: 'a,
288        E: 'a,
289        F: 'a + CombineManyFail<'a, G>,
290        G: 'a,
291    {
292        let mut ret = Parser::fail_with(Vec::new);
293        let mut names = vec![];
294        for parser in parsers {
295            names.push(parser.name.clone());
296            ret = ret.or(parser).map_fail(|(f1, _f1_state, f2, f2_state)| {
297                let mut f = f1;
298                f.push((f2, f2_state));
299                f
300            });
301        }
302        let name = format!(
303            "one_of({})",
304            names
305                .iter()
306                .map(|s| s.as_str())
307                .collect::<Vec<_>>()
308                .join(", ")
309        );
310        ret.map_fail(F::combine_many_fail).with_name(name)
311    }
312
313    pub fn filter(self, pred: impl Fn(&T) -> bool + 'a) -> Self
314    where
315        T: Clone + 'a,
316        E: 'a,
317        F: Clone + Default + 'a,
318    {
319        let name = format!("filter({})", self.name);
320        Parser::and_then(self, move |value| {
321            if pred(&value) {
322                Parser::ret(value)
323            } else {
324                Parser::fail(F::default())
325            }
326        })
327        .with_name(name)
328    }
329}
330
331impl<'a, E, F> Parser<'a, State<'a>, E, F> {
332    /// A parser that just returns the current state.
333    pub fn state() -> Self {
334        Parser {
335            name: Rc::new("state".to_string()),
336            parse: Rc::new(|state| ParseResult::Ok(state, state.pos)),
337        }
338    }
339}
340
341#[macro_export]
342macro_rules! one_of {
343    ( $($parser:expr),* $(,)? ) => {{
344        $crate::Parser::one_of(
345            vec![
346                $($parser),*
347            ]
348        )
349    }};
350}