combi/tokens/
derived.rs

1use syn::parse::Parse as SynParse;
2
3use crate::{
4    core::{choice, mapsuc, nothing, recover, seq},
5    derived::{many0, many1},
6    logical::{not, or},
7};
8
9use super::{
10    basic::{collectuntil, isempty, matchpunct, peekpunct, syn},
11    recovery::until,
12    TokenParser,
13};
14
15/// Use syn to parse tokens collected to a parser
16#[inline]
17pub fn syntopunct<T: SynParse, End: TokenParser<bool>>(end: End) -> impl TokenParser<T> {
18    syn(collectuntil(or(end, isempty())))
19}
20
21/// Parse a punct separated list
22#[inline]
23pub fn listsep<S, I: TokenParser<S> + Clone>(sep: char, item: I) -> impl TokenParser<Vec<S>> {
24    choice(
25        isempty(),
26        mapsuc(nothing(), |()| vec![]),
27        many1(
28            choice(
29                peekpunct(sep),
30                mapsuc(matchpunct(sep), |_| true),
31                mapsuc(nothing(), |_| false),
32            ),
33            recover(item, until(peekpunct(sep))),
34        ),
35    )
36}
37
38#[inline]
39pub fn listseptrailing<S, I: TokenParser<S>>(sep: char, item: I) -> impl TokenParser<Vec<S>> {
40    many0(
41        not(isempty()),
42        mapsuc(
43            seq(
44                recover(item, until(peekpunct(sep))),
45                choice(isempty(), nothing(), mapsuc(matchpunct(sep), |_| ())),
46            ),
47            |(i, ())| i,
48        ),
49    )
50}