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#[inline]
17pub fn syntopunct<T: SynParse, End: TokenParser<bool>>(end: End) -> impl TokenParser<T> {
18 syn(collectuntil(or(end, isempty())))
19}
20
21#[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}