rowan_nom/
lib.rs

1//! Build [rowan] green ASTs using [nom] parsers
2//!
3//! # Example
4//!
5//! ```
6#![doc = include_str!("../examples/basic.rs")]
7//! ```
8
9mod children;
10mod error;
11
12pub use nom::combinator::map;
13
14pub use children::Children;
15pub use error::*;
16use nom::Parser;
17use rowan::SyntaxNode;
18
19pub trait RowanNomLanguage: rowan::Language {
20    /// Returns `true` if the token is a trivia token (whitespace or comment)
21    fn is_trivia(_kind: Self::Kind) -> bool {
22        false
23    }
24
25    fn get_error_kind() -> Self::Kind;
26}
27
28// Yup, that's a trait alias
29use RowanNomLanguage as Language;
30
31type RichToken<'src, Lang> = (<Lang as rowan::Language>::Kind, &'src str);
32
33/// Input type for [nom] parsers
34///
35/// Usually built using [`Input::from`], which takes a slice of `(Language::Kind, &str)`.
36pub struct Input<'slice, 'src, Lang: Language> {
37    src_pos: usize,
38    trivia_tokens: &'slice [RichToken<'src, Lang>],
39    trivia_tokens_text_len: usize,
40    tokens: &'slice [RichToken<'src, Lang>],
41}
42
43fn split_slice_predicate<T>(slice: &[T], predicate: impl FnMut(&T) -> bool) -> (&[T], &[T]) {
44    let non_trivia_idx = slice.iter().position(predicate).unwrap_or(slice.len());
45
46    slice.split_at(non_trivia_idx)
47}
48
49impl<'slice, 'src, Lang: Language> Input<'slice, 'src, Lang> {
50    pub fn src_pos(&self) -> usize {
51        self.src_pos
52    }
53
54    fn next(
55        &self,
56    ) -> Option<(
57        Self,
58        (
59            &'slice [RichToken<'src, Lang>],
60            &'slice RichToken<'src, Lang>,
61        ),
62    )> {
63        match self.tokens {
64            [] => None,
65            [first, rest @ ..] => {
66                let relevant_tokens = (self.trivia_tokens, first);
67
68                let input = Input {
69                    src_pos: self.src_pos + self.trivia_tokens_text_len + first.1.len(),
70                    trivia_tokens: &[],
71                    trivia_tokens_text_len: 0,
72                    tokens: rest,
73                }
74                .advance_trivia();
75
76                Some((input, relevant_tokens))
77            }
78        }
79    }
80
81    fn next_trivia(&self) -> Option<(Self, &'slice RichToken<'src, Lang>)> {
82        if let [token, rest @ ..] = self.trivia_tokens {
83            let token_len = token.1.len();
84
85            Some((
86                Input {
87                    src_pos: self.src_pos + token_len,
88                    trivia_tokens: rest,
89                    trivia_tokens_text_len: self.trivia_tokens_text_len - token_len,
90                    tokens: self.tokens,
91                },
92                token,
93            ))
94        } else {
95            None
96        }
97    }
98
99    fn next_raw(&mut self) {
100        if let Some(trivia) = self.trivia_tokens.first() {
101            let text_len = trivia.1.len();
102            self.src_pos += text_len;
103            self.trivia_tokens_text_len -= text_len;
104            self.trivia_tokens = &self.trivia_tokens[1..];
105        } else if let Some(token) = self.tokens.first() {
106            self.src_pos += token.1.len();
107            self.tokens = &self.tokens[1..];
108        } else {
109            panic!("empty input");
110        }
111    }
112
113    fn advance_trivia(self) -> Self {
114        let (trivia_tokens, rest_tokens) =
115            split_slice_predicate(self.tokens, |(t, _)| !Lang::is_trivia(*t));
116
117        let trivia_tokens_text_len = trivia_tokens.iter().map(|(_, s)| s.len()).sum();
118
119        Self {
120            src_pos: self.src_pos,
121            trivia_tokens,
122            trivia_tokens_text_len,
123            tokens: rest_tokens,
124        }
125    }
126}
127
128impl<'slice, 'src, Lang: Language> Clone for Input<'slice, 'src, Lang> {
129    fn clone(&self) -> Self {
130        Self {
131            src_pos: self.src_pos,
132            trivia_tokens: self.trivia_tokens,
133            trivia_tokens_text_len: self.trivia_tokens_text_len,
134            tokens: self.tokens,
135        }
136    }
137}
138
139impl<'slice, 'src, Lang: Language> From<&'slice [RichToken<'src, Lang>]>
140    for Input<'slice, 'src, Lang>
141{
142    fn from(tokens: &'slice [RichToken<'src, Lang>]) -> Self {
143        Self {
144            src_pos: 0,
145            trivia_tokens: &[],
146            trivia_tokens_text_len: 0,
147            tokens,
148        }
149        .advance_trivia()
150    }
151}
152
153pub type IResult<'slice, 'src, Lang, E, IE = E> =
154    nom::IResult<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>;
155pub type RootIResult<'slice, 'src, Lang, E, IE = E> =
156    nom::IResult<Input<'slice, 'src, Lang>, (SyntaxNode<Lang>, Vec<E>), IE>;
157
158/// Succeeds without consuming the input
159///
160/// May be used as an [alt] case
161pub fn success<'slice, 'src: 'slice, Lang: Language, E, IE>(
162    input: Input<'slice, 'src, Lang>,
163) -> IResult<'slice, 'src, Lang, E, IE> {
164    Ok((input, Children::empty()))
165}
166
167/// Succeeds if the input contains no tokens other than trivia, and returns a [Children] object with
168/// said trivia, effectively emptying last insignificant bits of input
169pub fn eof<'slice, 'src: 'slice, Lang: Language, E, IE: RowanNomError<Lang>>(
170    input: Input<'slice, 'src, Lang>,
171) -> IResult<'slice, 'src, Lang, E, IE> {
172    if let Some((_, (_trivia, unexpected_token))) = input.next() {
173        let start = input.src_pos;
174        let range = start..start + unexpected_token.1.len();
175        Err(nom::Err::Error(IE::from_expected_eof(range)))
176    } else {
177        let trivia_tokens = input.trivia_tokens.iter();
178
179        let input = Input {
180            src_pos: input.src_pos + input.trivia_tokens_text_len,
181            trivia_tokens: &[],
182            trivia_tokens_text_len: 0,
183            tokens: &[],
184        };
185
186        Ok((input, trivia_tokens.collect()))
187    }
188}
189
190/// Parses any token
191pub fn t_any<'slice, 'src: 'slice, Lang: Language, E, IE: RowanNomError<Lang>>(
192    input: Input<'slice, 'src, Lang>,
193) -> IResult<'slice, 'src, Lang, E, IE> {
194    if let Some((new_input, (trivia, current_token))) = input.next() {
195        Ok((
196            new_input,
197            trivia
198                .iter()
199                .chain(std::iter::once(current_token))
200                .collect(),
201        ))
202    } else {
203        Err(nom::Err::Error(IE::from_unexpected_eof(input.src_pos)))
204    }
205}
206
207/// Parses only the given token, fails if the wrong token is read or if the input is empty
208///
209/// Trivia tokens are automatically skipped and prepended to the parsed token
210pub fn t<'slice, 'src: 'slice, Lang: Language, E, IE: RowanNomError<Lang>>(
211    token: Lang::Kind,
212) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE> + Clone + Copy {
213    debug_assert!(
214        !Lang::is_trivia(token),
215        "this parser will always fail with trivia tokens, please use `t_raw`"
216    );
217
218    move |input| {
219        let input_src_pos = input.src_pos;
220
221        if let Some((new_input, (trivia, current_token))) = input.next() {
222            if current_token.0 == token {
223                Ok((
224                    new_input,
225                    trivia
226                        .iter()
227                        .chain(std::iter::once(current_token))
228                        .collect(),
229                ))
230            } else {
231                let range = input_src_pos..input_src_pos + current_token.1.len();
232                Err(nom::Err::Error(IE::from_unexpected_token(
233                    range,
234                    token,
235                    current_token.0,
236                )))
237            }
238        } else {
239            Err(nom::Err::Error(IE::from_unexpected_eof(input.src_pos)))
240        }
241    }
242}
243
244/// Parses only the given token, fails if the wrong token is read or if the input is empty, **but
245/// does not skip trivia tokens**
246///
247/// This may be useful in situations were whitespace or comments are prohibited in a specific
248/// context
249pub fn t_raw<'slice, 'src: 'slice, Lang: Language, E, IE: RowanNomError<Lang>>(
250    token: Lang::Kind,
251) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE> + Clone + Copy {
252    let is_trivia = Lang::is_trivia(token);
253
254    move |input| {
255        let input_src_pos = input.src_pos;
256
257        if is_trivia {
258            if let Some((new_input, current_token)) = input.next_trivia() {
259                if current_token.0 == token {
260                    Ok((new_input, std::iter::once(current_token).collect()))
261                } else {
262                    let range = input_src_pos..input_src_pos + current_token.1.len();
263                    Err(nom::Err::Error(IE::from_unexpected_token(
264                        range,
265                        token,
266                        current_token.0,
267                    )))
268                }
269            } else {
270                Err(nom::Err::Error(IE::from_unexpected_eof(input_src_pos)))
271            }
272        } else {
273            t(token)(input)
274        }
275    }
276}
277
278/// Makes a parser peek without consuming
279///
280/// Returns `Ok((same_input, Children::empty()))` or the error returned by the wrapped parser
281///
282/// Works the same as [`nom::combinator::peek`]
283pub fn peek<'slice, 'src: 'slice, Lang: Language, E, IE>(
284    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
285) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
286where
287    Lang::Kind: 'static,
288{
289    move |input| {
290        let (_, _) = parser.parse(input.clone())?;
291        Ok((input, Children::empty()))
292    }
293}
294
295/// Negated peek, succeeds only if the given parser fails
296///
297///   * On failure, succeeds with and empty [`Children`] and the same input
298///   * On success, fails
299pub fn peek_neg<'slice, 'src: 'slice, Lang: Language, E, IE: RowanNomError<Lang>>(
300    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
301) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
302where
303    Lang::Kind: 'static,
304{
305    move |input| match parser.parse(input.clone()) {
306        Ok(_) => Err(nom::Err::Error(IE::from_message("neg_peek"))),
307        Err(_) => Ok((input, Children::empty())),
308    }
309}
310
311pub fn fallible_with<'slice, 'src: 'slice, Lang: Language, E, IE>(
312    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
313    mut convert: impl FnMut(IE) -> E,
314) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
315where
316    Lang::Kind: 'static,
317{
318    move |input| {
319        let conv = &mut convert;
320        parser.parse(input.clone()).or_else(move |e| match e {
321            nom::Err::Error(e) => Ok((input, Children::from_err(conv(e)))),
322            other => Err(other),
323        })
324    }
325}
326
327/// Tries to apply the given parser to the input without failing on error
328///
329/// If the provided parser fails, an error is produced with the `message` description and the input
330/// is left unchanged.
331pub fn expect<'slice, 'src: 'slice, Lang: Language, E: RowanNomError<Lang>>(
332    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, E>,
333    message: &'static str,
334) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, E>
335where
336    Lang::Kind: 'static,
337{
338    move |input| {
339        let src_pos = input.src_pos;
340        parser.parse(input.clone()).or_else(move |e| match e {
341            nom::Err::Error(_) => Ok((
342                input,
343                Children::from_err(E::from_expected(src_pos, message)),
344            )),
345            other => Err(other),
346        })
347    }
348}
349
350pub fn fallible<'slice, 'src: 'slice, Lang: Language, E, IE>(
351    parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
352) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
353where
354    Lang::Kind: 'static,
355    E: From<IE>,
356{
357    fallible_with(parser, Into::into)
358}
359
360/// Wraps the contained parser's direct and indirect output into a node
361pub fn node<'slice, 'src: 'slice, Lang: Language, E, IE>(
362    node: Lang::Kind,
363    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
364) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
365where
366    Lang::Kind: 'static,
367{
368    move |input| {
369        parser
370            .parse(input)
371            .map(|(input, c)| (input, c.into_node(node)))
372    }
373}
374
375/// Wraps the contained parser's output into a root node inside a [SyntaxNode]
376pub fn root_node<'slice, 'src: 'slice, Lang: Language, E, IE>(
377    node: Lang::Kind,
378    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
379) -> impl FnMut(Input<'slice, 'src, Lang>) -> RootIResult<'slice, 'src, Lang, E, IE>
380where
381    Lang::Kind: 'static,
382{
383    move |input| {
384        parser
385            .parse(input)
386            .map(|(input, c)| (input, c.into_root_node(node)))
387    }
388}
389
390pub trait Joignable<'slice, 'src, Lang: Language, E, IE> {
391    fn parse(&mut self, input: Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>;
392}
393
394macro_rules! impl_joignable {
395    ($arg0:ident, $($arg:ident),*) => {
396        #[allow(unused_parens)]
397        impl<'slice, 'src: 'slice, Lang: Language, CE, IE, $arg0, $($arg),*> Joignable<'slice, 'src, Lang, CE, IE> for ($arg0, $($arg,)*)
398        where
399            Lang::Kind: 'static,
400            $arg0: Parser<Input<'slice, 'src, Lang>, Children<Lang, CE>, IE>,
401            $($arg: Parser<Input<'slice, 'src, Lang>, Children<Lang, CE>, IE>),*
402        {
403            fn parse(&mut self, input: Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, CE, IE> {
404                #[allow(non_snake_case)]
405                let ($arg0, $($arg),*) = self;
406
407                #[allow(unused_mut)]
408                let (input, mut children) = $arg0.parse(input)?;
409                $(let (input, children2) = $arg.parse(input)?; children += children2;)*
410
411                Ok((input, children))
412            }
413        }
414    };
415}
416
417impl_joignable!(A,);
418impl_joignable!(A, B);
419impl_joignable!(A, B, C);
420impl_joignable!(A, B, C, D);
421impl_joignable!(A, B, C, D, E);
422impl_joignable!(A, B, C, D, E, F);
423impl_joignable!(A, B, C, D, E, F, G);
424impl_joignable!(A, B, C, D, E, F, G, H);
425impl_joignable!(A, B, C, D, E, F, G, H, I);
426impl_joignable!(A, B, C, D, E, F, G, H, I, J);
427impl_joignable!(A, B, C, D, E, F, G, H, I, J, K);
428impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L);
429impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M);
430impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
431impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
432impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
433impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
434impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
435impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
436impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
437impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
438impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V);
439impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W);
440impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X);
441impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y);
442impl_joignable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
443
444/// Joins the output trees of multiple parsers without creating a new node (yet)
445pub fn join<'slice, 'src: 'slice, Lang: Language, E, IE>(
446    mut parsers: impl Joignable<'slice, 'src, Lang, E, IE>,
447) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE> {
448    move |input| parsers.parse(input)
449}
450
451/// Optional parser, will return [None] on [`nom::Err::Error`].
452///
453/// Similar to [`nom::combinator::opt`].
454pub fn opt<'slice, 'src: 'slice, Lang: Language, E, IE>(
455    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
456) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
457where
458    Lang::Kind: 'static,
459{
460    move |input| match parser.parse(input.clone()) {
461        Ok(ok) => Ok(ok),
462        Err(nom::Err::Error(_)) => Ok((input, Children::empty())),
463        Err(e) => Err(e),
464    }
465}
466
467pub trait Alt<I, O, E> {
468    fn parse(&mut self, input: I) -> nom::IResult<I, O, E>;
469}
470
471macro_rules! impl_alt {
472    ($arg0:ident, $($arg:ident),*) => {
473        #[allow(unused_parens)]
474        impl<II: Clone, OO, EE, $arg0, $($arg),*> Alt<II, OO, EE> for ($arg0, $($arg,)*)
475        where
476            $arg0: Parser<II, OO, EE>,
477            $($arg: Parser<II, OO, EE>),*
478        {
479            fn parse(&mut self, input: II) -> nom::IResult<II, OO, EE> {
480                #[allow(non_snake_case)]
481                let ($arg0, $($arg),*) = self;
482
483                $arg0.parse(input.clone())
484                $(.or_else(|_| $arg.parse(input.clone())))*
485            }
486        }
487    };
488}
489
490impl_alt!(A,);
491impl_alt!(A, B);
492impl_alt!(A, B, C);
493impl_alt!(A, B, C, D);
494impl_alt!(A, B, C, D, E);
495impl_alt!(A, B, C, D, E, F);
496impl_alt!(A, B, C, D, E, F, G);
497impl_alt!(A, B, C, D, E, F, G, H);
498impl_alt!(A, B, C, D, E, F, G, H, I);
499impl_alt!(A, B, C, D, E, F, G, H, I, J);
500impl_alt!(A, B, C, D, E, F, G, H, I, J, K);
501impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L);
502impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M);
503impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
504impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
505impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
506impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
507impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
508impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
509impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
510impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
511impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V);
512impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W);
513impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X);
514impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y);
515impl_alt!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
516
517/// Tests a list of parsers one by one until one succeeds
518///
519/// Similar to [`nom::branch::alt`].
520pub fn alt<I, O, E>(mut parsers: impl Alt<I, O, E>) -> impl FnMut(I) -> nom::IResult<I, O, E> {
521    move |input| parsers.parse(input)
522}
523
524/// Repeats the given parser 0 or more times until it fails, and join all the results in a
525/// `Children` object
526pub fn many0<'slice, 'src: 'slice, Lang: Language, E, IE>(
527    mut parser: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, E>,
528) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
529where
530    Lang::Kind: 'static,
531{
532    move |input| {
533        let (mut input, mut first) = match parser.parse(input.clone()) {
534            Ok(x) => x,
535            Err(_) => return Ok((input, Children::empty())),
536        };
537
538        while let Ok((new_input, new_children)) = parser.parse(input.clone()) {
539            input = new_input;
540            first += new_children;
541        }
542
543        Ok((input, first))
544    }
545}
546
547/// Similar to [`nom::multi::fold_many1`], but more specialized
548///
549/// Useful for parsing left-associative expressions
550pub fn fold_many1<'slice, 'src: 'slice, Lang: Language, C, E, IE>(
551    mut init: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
552    mut then: impl Parser<Input<'slice, 'src, Lang>, C, IE>,
553    mut merge: impl FnMut(Children<Lang, E>, C) -> Children<Lang, E>,
554) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
555where
556    Lang::Kind: 'static,
557{
558    move |input| {
559        let (mut input, mut children) = init.parse(input)?;
560
561        while let Ok((new_input, new_children)) = then.parse(input.clone()) {
562            input = new_input;
563            children = merge(children, new_children);
564        }
565
566        Ok((input, children))
567    }
568}
569
570/// Similar to [`fold_many1`], but folds right instead of left
571///
572/// For parsing right-associative expressions, [`fold_many1_right_expr`] is more appropriate
573pub fn fold_many1_right<'slice, 'src: 'slice, Lang: Language, C, E, IE: RowanNomError<Lang>>(
574    mut cont: impl Parser<Input<'slice, 'src, Lang>, C, IE>,
575    mut end: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
576    mut merge: impl FnMut(Children<Lang, E>, C) -> Children<Lang, E>,
577) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
578where
579    Lang::Kind: 'static,
580{
581    move |mut input| {
582        let mut stack = Vec::new();
583
584        loop {
585            if let Ok((new_input, new_children)) = cont.parse(input.clone()) {
586                input = new_input;
587                stack.push(new_children);
588            } else if let Ok((input, new_children)) = end.parse(input) {
589                let children = stack.into_iter().rfold(new_children, |a, b| merge(a, b));
590                break Ok((input, children));
591            } else {
592                break Err(nom::Err::Error(IE::from_message("couldn't finish fold")));
593            }
594        }
595    }
596}
597
598/// Similar to [`fold_many1`], but folds right instead of left — expression version
599///
600/// Useful for parsing right-associative expressions
601pub fn fold_many1_right_expr<'slice, 'src: 'slice, Lang: Language, C, E, IE: RowanNomError<Lang>>(
602    mut atom: impl Parser<Input<'slice, 'src, Lang>, Children<Lang, E>, IE>,
603    mut operator: impl Parser<Input<'slice, 'src, Lang>, (Children<Lang, E>, C), IE>,
604    mut merge: impl FnMut(Children<Lang, E>, (Children<Lang, E>, C)) -> Children<Lang, E>,
605) -> impl FnMut(Input<'slice, 'src, Lang>) -> IResult<'slice, 'src, Lang, E, IE>
606where
607    Lang::Kind: 'static,
608{
609    move |mut input| {
610        let mut stack = Vec::new();
611
612        loop {
613            if let Ok((new_input, children)) = atom.parse(input.clone()) {
614                if let Ok((new_input, (new_children, c))) = operator.parse(new_input.clone()) {
615                    input = new_input;
616                    stack.push((children + new_children, c));
617                } else {
618                    let children = stack.into_iter().rfold(children, |a, b| merge(a, b));
619                    break Ok((new_input, children));
620                }
621            } else {
622                break Err(nom::Err::Error(IE::from_message("couldn't finish fold")));
623            }
624        }
625    }
626}