1use crate::{
4 error::{
5 self, ErrorInfo, ParseError,
6 ParseResult::{self, *},
7 ResultExt, StreamError, Tracked,
8 },
9 lib::marker::PhantomData,
10 stream::{uncons, Stream, StreamOnce},
11 Parser,
12};
13
14#[derive(Copy, Clone)]
15pub struct Any<Input>(PhantomData<fn(Input) -> Input>);
16
17impl<Input> Parser<Input> for Any<Input>
18where
19 Input: Stream,
20{
21 type Output = Input::Token;
22 type PartialState = ();
23
24 #[inline]
25 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
26 uncons(input)
27 }
28}
29
30pub fn any<Input>() -> Any<Input>
45where
46 Input: Stream,
47{
48 Any(PhantomData)
49}
50
51#[derive(Copy, Clone)]
52pub struct Satisfy<Input, P> {
53 predicate: P,
54 _marker: PhantomData<Input>,
55}
56
57fn satisfy_impl<Input, P, R>(input: &mut Input, mut predicate: P) -> ParseResult<R, Input::Error>
58where
59 Input: Stream,
60 P: FnMut(Input::Token) -> Option<R>,
61{
62 let position = input.position();
63 match uncons(input) {
64 PeekOk(c) | CommitOk(c) => match predicate(c) {
65 Some(c) => CommitOk(c),
66 None => PeekErr(Input::Error::empty(position).into()),
67 },
68 PeekErr(err) => PeekErr(err),
69 CommitErr(err) => CommitErr(err),
70 }
71}
72
73impl<Input, P> Parser<Input> for Satisfy<Input, P>
74where
75 Input: Stream,
76 P: FnMut(Input::Token) -> bool,
77{
78 type Output = Input::Token;
79 type PartialState = ();
80
81 #[inline]
82 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> {
83 satisfy_impl(input, |c| {
84 if (self.predicate)(c.clone()) {
85 Some(c)
86 } else {
87 None
88 }
89 })
90 }
91}
92
93pub fn satisfy<Input, P>(predicate: P) -> Satisfy<Input, P>
105where
106 Input: Stream,
107 P: FnMut(Input::Token) -> bool,
108{
109 Satisfy {
110 predicate,
111 _marker: PhantomData,
112 }
113}
114
115#[derive(Copy, Clone)]
116pub struct SatisfyMap<Input, P> {
117 predicate: P,
118 _marker: PhantomData<Input>,
119}
120
121impl<Input, P, R> Parser<Input> for SatisfyMap<Input, P>
122where
123 Input: Stream,
124 P: FnMut(Input::Token) -> Option<R>,
125{
126 type Output = R;
127 type PartialState = ();
128 #[inline]
129 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> {
130 satisfy_impl(input, &mut self.predicate)
131 }
132}
133
134pub fn satisfy_map<Input, P, R>(predicate: P) -> SatisfyMap<Input, P>
159where
160 Input: Stream,
161 P: FnMut(Input::Token) -> Option<R>,
162{
163 SatisfyMap {
164 predicate,
165 _marker: PhantomData,
166 }
167}
168
169#[derive(Copy, Clone)]
170pub struct Token<Input>
171where
172 Input: Stream,
173 Input::Token: PartialEq,
174{
175 c: Input::Token,
176 _marker: PhantomData<Input>,
177}
178
179impl<Input> Parser<Input> for Token<Input>
180where
181 Input: Stream,
182 Input::Token: PartialEq + Clone,
183{
184 type Output = Input::Token;
185 type PartialState = ();
186
187 #[inline]
188 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
189 satisfy_impl(input, |c| if c == self.c { Some(c) } else { None })
190 }
191 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
192 errors.error.add_expected(error::Token(self.c.clone()));
193 }
194}
195
196pub fn token<Input>(c: Input::Token) -> Token<Input>
209where
210 Input: Stream,
211 Input::Token: PartialEq,
212{
213 Token {
214 c,
215 _marker: PhantomData,
216 }
217}
218
219#[derive(Clone)]
220pub struct Tokens<C, E, T, Input>
221where
222 Input: Stream,
223{
224 cmp: C,
225 expected: E,
226 tokens: T,
227 _marker: PhantomData<Input>,
228}
229
230impl<Input, C, E, T> Parser<Input> for Tokens<C, E, T, Input>
231where
232 C: FnMut(T::Item, Input::Token) -> bool,
233 E: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
234 T: Clone + IntoIterator,
235 Input: Stream,
236{
237 type Output = T;
238 type PartialState = ();
239 #[inline]
240 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, Input::Error> {
241 let start = input.position();
242 let mut committed = false;
243 for c in self.tokens.clone() {
244 match crate::stream::uncons(input) {
245 CommitOk(other) | PeekOk(other) => {
246 if !(self.cmp)(c, other.clone()) {
247 return if committed {
248 let mut errors = <Input as StreamOnce>::Error::from_error(
249 start,
250 StreamError::unexpected_token(other),
251 );
252 errors.add_expected(&self.expected);
253 CommitErr(errors)
254 } else {
255 PeekErr(<Input as StreamOnce>::Error::empty(start).into())
256 };
257 }
258 committed = true;
259 }
260 PeekErr(mut error) => {
261 error.error.set_position(start);
262 return if committed {
263 CommitErr(error.error)
264 } else {
265 PeekErr(error)
266 };
267 }
268 CommitErr(mut error) => {
269 error.set_position(start);
270 return CommitErr(error);
271 }
272 }
273 }
274 if committed {
275 CommitOk(self.tokens.clone())
276 } else {
277 PeekOk(self.tokens.clone())
278 }
279 }
280 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
281 errors.error.add_expected(&self.expected);
282 }
283}
284
285pub fn tokens<C, E, T, Input>(cmp: C, expected: E, tokens: T) -> Tokens<C, E, T, Input>
311where
312 C: FnMut(T::Item, Input::Token) -> bool,
313 T: Clone + IntoIterator,
314 Input: Stream,
315{
316 Tokens {
317 cmp,
318 expected,
319 tokens,
320 _marker: PhantomData,
321 }
322}
323
324#[derive(Clone)]
325pub struct TokensCmp<C, T, Input>
326where
327 Input: Stream,
328{
329 cmp: C,
330 tokens: T,
331 _marker: PhantomData<Input>,
332}
333
334impl<Input, C, T> Parser<Input> for TokensCmp<C, T, Input>
335where
336 C: FnMut(T::Item, Input::Token) -> bool,
337 T: Clone + IntoIterator,
338 Input: Stream,
339{
340 type Output = T;
341 type PartialState = ();
342
343 #[inline]
344 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, Input::Error> {
345 let start = input.position();
346 let mut committed = false;
347 for c in self.tokens.clone() {
348 match crate::stream::uncons(input) {
349 CommitOk(other) | PeekOk(other) => {
350 if !(self.cmp)(c, other.clone()) {
351 return if committed {
352 let errors = <Input as StreamOnce>::Error::from_error(
353 start,
354 StreamError::unexpected_token(other),
355 );
356 CommitErr(errors)
357 } else {
358 PeekErr(<Input as StreamOnce>::Error::empty(start).into())
359 };
360 }
361 committed = true;
362 }
363 PeekErr(mut error) => {
364 error.error.set_position(start);
365 return if committed {
366 CommitErr(error.error)
367 } else {
368 PeekErr(error)
369 };
370 }
371 CommitErr(mut error) => {
372 error.set_position(start);
373 return CommitErr(error);
374 }
375 }
376 }
377 if committed {
378 CommitOk(self.tokens.clone())
379 } else {
380 PeekOk(self.tokens.clone())
381 }
382 }
383}
384
385pub fn tokens_cmp<C, T, I>(tokens: T, cmp: C) -> TokensCmp<C, T, I>
411where
412 C: FnMut(T::Item, I::Token) -> bool,
413 T: Clone + IntoIterator,
414 I: Stream,
415{
416 TokensCmp {
417 cmp,
418 tokens,
419 _marker: PhantomData,
420 }
421}
422
423#[derive(Copy, Clone)]
424pub struct Position<Input>
425where
426 Input: Stream,
427{
428 _marker: PhantomData<Input>,
429}
430
431impl<Input> Parser<Input> for Position<Input>
432where
433 Input: Stream,
434{
435 type Output = Input::Position;
436 type PartialState = ();
437
438 #[inline]
439 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Position, Input::Error> {
440 PeekOk(input.position())
441 }
442}
443
444pub fn position<Input>() -> Position<Input>
460where
461 Input: Stream,
462{
463 Position {
464 _marker: PhantomData,
465 }
466}
467
468#[derive(Copy, Clone)]
469pub struct OneOf<T, Input>
470where
471 Input: Stream,
472{
473 tokens: T,
474 _marker: PhantomData<Input>,
475}
476
477impl<Input, T> Parser<Input> for OneOf<T, Input>
478where
479 T: Clone + IntoIterator<Item = Input::Token>,
480 Input: Stream,
481 Input::Token: PartialEq,
482{
483 type Output = Input::Token;
484 type PartialState = ();
485
486 #[inline]
487 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
488 satisfy(|c| self.tokens.clone().into_iter().any(|t| t == c)).parse_lazy(input)
489 }
490
491 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
492 for expected in self.tokens.clone() {
493 errors.error.add_expected(error::Token(expected));
494 }
495 }
496}
497
498pub fn one_of<T, Input>(tokens: T) -> OneOf<T, Input>
510where
511 T: Clone + IntoIterator,
512 Input: Stream,
513 Input::Token: PartialEq<T::Item>,
514{
515 OneOf {
516 tokens,
517 _marker: PhantomData,
518 }
519}
520
521#[derive(Copy, Clone)]
522pub struct NoneOf<T, Input>
523where
524 Input: Stream,
525{
526 tokens: T,
527 _marker: PhantomData<Input>,
528}
529
530impl<Input, T> Parser<Input> for NoneOf<T, Input>
531where
532 T: Clone + IntoIterator<Item = Input::Token>,
533 Input: Stream,
534 Input::Token: PartialEq,
535{
536 type Output = Input::Token;
537 type PartialState = ();
538
539 #[inline]
540 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
541 satisfy(|c| self.tokens.clone().into_iter().all(|t| t != c)).parse_lazy(input)
542 }
543}
544
545pub fn none_of<T, Input>(tokens: T) -> NoneOf<T, Input>
568where
569 T: Clone + IntoIterator,
570 Input: Stream,
571 Input::Token: PartialEq<T::Item>,
572{
573 NoneOf {
574 tokens,
575 _marker: PhantomData,
576 }
577}
578
579#[derive(Copy, Clone)]
580pub struct Value<Input, T>(T, PhantomData<fn(Input) -> Input>);
581impl<Input, T> Parser<Input> for Value<Input, T>
582where
583 Input: Stream,
584 T: Clone,
585{
586 type Output = T;
587 type PartialState = ();
588 #[inline]
589 fn parse_lazy(&mut self, _: &mut Input) -> ParseResult<T, Input::Error> {
590 PeekOk(self.0.clone())
591 }
592}
593
594pub fn value<Input, T>(v: T) -> Value<Input, T>
607where
608 Input: Stream,
609 T: Clone,
610{
611 Value(v, PhantomData)
612}
613
614#[derive(Copy, Clone)]
615pub struct Produce<Input, F>(F, PhantomData<fn(Input) -> Input>);
616impl<Input, F, R> Parser<Input> for Produce<Input, F>
617where
618 Input: Stream,
619 F: FnMut() -> R,
620{
621 type Output = R;
622 type PartialState = ();
623 #[inline]
624 fn parse_lazy(&mut self, _: &mut Input) -> ParseResult<R, Input::Error> {
625 PeekOk((self.0)())
626 }
627}
628
629pub fn produce<Input, F, R>(f: F) -> Produce<Input, F>
643where
644 Input: Stream,
645 F: FnMut() -> R,
646{
647 Produce(f, PhantomData)
648}
649
650#[derive(Copy, Clone)]
651pub struct Eof<Input>(PhantomData<Input>);
652impl<Input> Parser<Input> for Eof<Input>
653where
654 Input: Stream,
655{
656 type Output = ();
657 type PartialState = ();
658
659 #[inline]
660 fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<(), Input::Error> {
661 let before = input.checkpoint();
662 match input.uncons() {
663 Err(ref err) if err.is_unexpected_end_of_input() => PeekOk(()),
664 _ => {
665 ctry!(input.reset(before).committed());
666 PeekErr(<Input as StreamOnce>::Error::empty(input.position()).into())
667 }
668 }
669 }
670
671 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
672 errors.error.add_expected("end of input");
673 }
674}
675
676pub fn eof<Input>() -> Eof<Input>
696where
697 Input: Stream,
698{
699 Eof(PhantomData)
700}