pom_trace/
parser.rs

1use super::{Error, Result, RollbackRecord, RollbackType};
2use crate::range::Bound::*;
3use crate::range::RangeArgument;
4use crate::set::Set;
5use std::fmt::{Debug, Display};
6use std::ops::{Add, BitOr, Mul, Neg, Not, Shr, Sub};
7
8/// The third item, `Option<Error>`, if some, explains why the consumption of the next terminal has failed.
9/// This answers the question "Why didn't the parser continue?". For all fixed-length parsers, like `sym` and `seq`, it should always be none.
10type ParseOutput<O> = (O, usize, Option<Error>);
11
12type Parse<'a, I, O> = dyn Fn(&'a [I], usize) -> Result<ParseOutput<O>> + 'a;
13
14fn merge_errors(name: String, pos: usize, err1: Error, err2: Error) -> Error {
15	match (err1, err2) {
16		(
17			Error::Rollback {
18				rollbacks: rollbacks1,
19			},
20			Error::Rollback {
21				rollbacks: rollbacks2,
22			},
23		) => Error::Rollback {
24			rollbacks: RollbackRecord {
25				name,
26				position: pos,
27				typ: RollbackType::Fail,
28				inner: None,
29				previous_tracks: vec![rollbacks1, rollbacks2],
30			},
31		},
32		// TODO: remove this case
33		/*(err1 @ Error::Rollback { .. }, err2) => {
34			println!(
35				"merge_errors at {} losing rollback data: {:?} <<>> {:?}",
36				name, err1, err2
37			);
38			err2
39		}*/
40		(_, err2) => err2,
41	}
42}
43
44fn merge_continuation_errors(
45	name: String,
46	pos: usize,
47	cont_err1: Option<Error>,
48	cont_err2: Option<Error>,
49) -> Option<Error> {
50	match (cont_err1, cont_err2) {
51		(
52			Some(Error::Rollback {
53				rollbacks: rollbacks1,
54			}),
55			Some(Error::Rollback {
56				rollbacks: rollbacks2,
57			}),
58		) => Some(Error::Rollback {
59			rollbacks: RollbackRecord {
60				name,
61				position: pos,
62				typ: RollbackType::Stop,
63				inner: None,
64				previous_tracks: vec![rollbacks1, rollbacks2],
65			},
66		}),
67		(
68			Some(Error::Rollback {
69				rollbacks: rollbacks1,
70			}),
71			None,
72		) => Some(Error::Rollback {
73			rollbacks: RollbackRecord {
74				name,
75				position: pos,
76				typ: RollbackType::Stop,
77				inner: None,
78				previous_tracks: vec![rollbacks1],
79			},
80		}),
81		// TODO: remove this case
82		/*(cont_err1 @ Some(Error::Rollback { .. }), cont_err2) => {
83			println!(
84				"merge_continuation_errors at {} losing rollback data: {:?} <<>> {:?}",
85				name, cont_err1, cont_err2
86			);
87			cont_err2
88		}*/
89		(_, cont_err2) => cont_err2,
90	}
91}
92
93/// Parser combinator.
94pub struct Parser<'a, I, O> {
95	method: Box<Parse<'a, I, O>>,
96}
97
98impl<'a, I, O> Parser<'a, I, O> {
99	/// Create new parser.
100	pub fn new<P>(parse: P) -> Parser<'a, I, O>
101	where
102		P: Fn(&'a [I], usize) -> Result<ParseOutput<O>> + 'a,
103	{
104		Parser {
105			method: Box::new(parse),
106		}
107	}
108
109	/// Apply the parser to parse input.
110	pub fn parse(&self, input: &'a [I]) -> Result<O> {
111		self.parse_at(input, 0).map(|(out, _, _)| out)
112	}
113
114	/// Parse input at specified position.
115	#[inline]
116	pub fn parse_at(&self, input: &'a [I], start: usize) -> Result<ParseOutput<O>> {
117		(self.method)(input, start)
118	}
119
120	/// Convert parser result to desired value.
121	pub fn map<U, F>(self, f: F) -> Parser<'a, I, U>
122	where
123		F: Fn(O) -> U + 'a,
124		I: 'a,
125		O: 'a,
126		U: 'a,
127	{
128		Parser::new(move |input: &'a [I], start: usize| {
129			self.parse_at(input, start)
130				.map(|(out, pos, cont_err)| (f(out), pos, cont_err))
131		})
132	}
133
134	/// Convert parser result to desired value, fail in case of conversion error.
135	pub fn convert<U, E, F>(self, f: F) -> Parser<'a, I, U>
136	where
137		F: Fn(O, &Option<Error>) -> ::std::result::Result<U, E> + 'a,
138		E: Debug,
139		O: 'a,
140		U: 'a,
141	{
142		Parser::new(move |input: &'a [I], start: usize| {
143			self.parse_at(input, start)
144				.and_then(|(res, pos, cont_err)| match f(res, &cont_err) {
145					Ok(out) => Ok((out, pos, cont_err)),
146					Err(err) => Err(Error::Conversion {
147						message: format!("Conversion error: {:?}", err),
148						position: start,
149					}),
150				})
151		})
152	}
153
154	/// Cache parser output result to speed up backtracking.
155	pub fn cache(self) -> Parser<'a, I, O>
156	where
157		O: Clone + 'a,
158	{
159		use std::cell::RefCell;
160		use std::collections::HashMap;
161		let results = RefCell::new(HashMap::new());
162		Parser::new(move |input: &'a [I], start: usize| {
163			let key = (start, format!("{:p}", &self.method));
164			results
165				.borrow_mut()
166				.entry(key)
167				.or_insert_with(|| self.parse_at(input, start))
168				.clone()
169		})
170	}
171
172	pub fn debug_ok<S>(self, id: S) -> Parser<'a, I, O>
173	where
174		O: std::fmt::Debug + 'a,
175		S: AsRef<str> + 'a,
176	{
177		Parser::new(move |input: &'a [I], start: usize| {
178			let result = self.parse_at(input, start);
179			if result.is_ok() {
180				println!("[debug] {} at {}: {:?}", id.as_ref(), start, result);
181			}
182			result
183		})
184	}
185
186	/// Get input position after matching parser.
187	pub fn pos(self) -> Parser<'a, I, usize>
188	where
189		O: 'a,
190	{
191		Parser::new(move |input: &'a [I], start: usize| {
192			self.parse_at(input, start)
193				.map(|(_, pos, cont_err)| (pos, pos, cont_err))
194		})
195	}
196
197	/// Collect all matched input symbols.
198	pub fn collect(self) -> Parser<'a, I, &'a [I]>
199	where
200		O: 'a,
201	{
202		Parser::new(move |input: &'a [I], start: usize| {
203			self.parse_at(input, start)
204				.map(|(_, end, cont_err)| (&input[start..end], end, cont_err))
205		})
206	}
207
208	/// Discard parser output.
209	pub fn discard(self) -> Parser<'a, I, ()>
210	where
211		O: 'a,
212	{
213		Parser::new(move |input: &'a [I], start: usize| {
214			self.parse_at(input, start)
215				.map(|(_, end, cont_err)| ((), end, cont_err))
216		})
217	}
218
219	/// Make parser optional.
220	pub fn opt(self) -> Parser<'a, I, Option<O>>
221	where
222		O: 'a,
223	{
224		Parser::new(
225			move |input: &'a [I], start: usize| match self.parse_at(input, start) {
226				Ok((out, pos, cont_err)) => Ok((Some(out), pos, cont_err)),
227				Err(err) => Ok((None, start, Some(err))),
228			},
229		)
230	}
231
232	/// `p.repeat(5)` repeat p exactly 5 times
233	/// `p.repeat(0..)` repeat p zero or more times
234	/// `p.repeat(1..)` repeat p one or more times
235	/// `p.repeat(1..4)` match p at least 1 and at most 3 times
236	pub fn repeat<R>(self, range: R) -> Parser<'a, I, Vec<O>>
237	where
238		R: RangeArgument<usize> + Debug + 'a,
239		O: 'a,
240	{
241		Parser::new(move |input: &'a [I], start: usize| {
242			let mut items = vec![];
243			let mut pos = start;
244			let mut cont_err = None;
245			loop {
246				match range.end() {
247					Included(&max_count) => {
248						if items.len() >= max_count {
249							break;
250						}
251					}
252					Excluded(&max_count) => {
253						if items.len() + 1 >= max_count {
254							break;
255						}
256					}
257					Unbounded => (),
258				}
259
260				match self.parse_at(input, pos) {
261					Ok((item, item_pos, item_cont_err)) => {
262						items.push(item);
263						pos = item_pos;
264						cont_err = item_cont_err;
265					}
266					Err(err) => {
267						cont_err = merge_continuation_errors(
268							"<Parser::repeat>".into(),
269							pos,
270							cont_err,
271							Some(err),
272						);
273						break;
274					}
275				}
276			}
277			if let Included(&min_count) = range.start() {
278				if items.len() < min_count {
279					return Err(Error::Mismatch {
280						message: format!(
281							"expect repeat at least {} times, found {} times",
282							min_count,
283							items.len()
284						),
285						position: start,
286						continuation_error: cont_err.map(Box::new),
287					});
288				}
289			}
290			Ok((items, pos, cont_err))
291		})
292	}
293
294	/// Give parser a name to identify parsing errors, and stops rollback tracing propagation.
295	pub fn name(self, name: &'a str) -> Parser<'a, I, O>
296	where
297		O: 'a,
298	{
299		Parser::new(
300			move |input: &'a [I], start: usize| match self.parse_at(input, start) {
301				res @ Ok(_) => res,
302				Err(err) => match err {
303					// TODO: how to handle rollbacks?
304					Error::Custom { .. } => Err(err),
305					_ => Err(Error::Custom {
306						message: format!("failed to parse {}", name),
307						position: start,
308						inner: Some(Box::new(err)),
309					}),
310				},
311			},
312		)
313	}
314
315	/// Trace parser with an identifier for rollback tracing.
316	pub fn trace<S>(self, id: S) -> Parser<'a, I, O>
317	where
318		O: 'a,
319		S: AsRef<str> + 'a,
320	{
321		Parser::new(
322			move |input: &'a [I], start: usize| match self.parse_at(input, start) {
323				res @ Ok((_, _, None)) => res,
324				Ok((out, pos, Some(Error::Rollback { rollbacks }))) => Ok((
325					out,
326					pos,
327					Some(Error::Rollback {
328						rollbacks: RollbackRecord {
329							name: id.as_ref().into(),
330							position: pos,
331							typ: RollbackType::Stop,
332							inner: None,
333							previous_tracks: vec![rollbacks],
334						},
335					}),
336				)),
337				Ok((out, pos, Some(cont_err))) => Ok((
338					out,
339					pos,
340					Some(Error::Rollback {
341						rollbacks: RollbackRecord {
342							name: id.as_ref().into(),
343							position: pos,
344							typ: RollbackType::Stop,
345							inner: Some(Box::new(cont_err)),
346							previous_tracks: vec![],
347						},
348					}),
349				)),
350				Err(err) => match err {
351					Error::Rollback { rollbacks } => Err(Error::Rollback {
352						rollbacks: RollbackRecord {
353							name: id.as_ref().into(),
354							position: start,
355							typ: RollbackType::Fail,
356							inner: None,
357							previous_tracks: vec![rollbacks],
358						},
359					}),
360					_ => Err(Error::Rollback {
361						rollbacks: RollbackRecord {
362							name: id.as_ref().into(),
363							position: start,
364							typ: RollbackType::Fail,
365							inner: Some(Box::new(err)),
366							previous_tracks: vec![],
367						},
368					}),
369				},
370			},
371		)
372	}
373
374	/// Mark parser as expected, abort early when failed in ordered choice.
375	pub fn expect(self, name: &'a str) -> Parser<'a, I, O>
376	where
377		O: 'a,
378	{
379		Parser::new(
380			move |input: &'a [I], start: usize| match self.parse_at(input, start) {
381				res @ Ok(_) => res,
382				Err(err) => Err(Error::Expect {
383					message: format!("Expect {}", name),
384					position: start,
385					inner: Box::new(err),
386				}),
387			},
388		)
389	}
390}
391
392/// Always succeeds, consume no input.
393pub fn empty<'a, I>() -> Parser<'a, I, ()> {
394	Parser::new(|_: &[I], start: usize| Ok(((), start, None)))
395}
396
397/// Match any symbol.
398pub fn any<'a, I>() -> Parser<'a, I, I>
399where
400	I: Clone,
401{
402	Parser::new(|input: &[I], start: usize| {
403		if let Some(s) = input.get(start) {
404			Ok((s.clone(), start + 1, None))
405		} else {
406			Err(Error::Mismatch {
407				message: "end of input reached".to_owned(),
408				position: start,
409				continuation_error: None,
410			})
411		}
412	})
413}
414
415/// Success when current input symbol equals `t`.
416pub fn sym<'a, I>(t: I) -> Parser<'a, I, I>
417where
418	I: Clone + PartialEq + Display,
419{
420	Parser::new(move |input: &'a [I], start: usize| {
421		if let Some(s) = input.get(start) {
422			if t == *s {
423				Ok((s.clone(), start + 1, None))
424			} else {
425				Err(Error::Mismatch {
426					message: format!("expect: {}, found: {}", t, s),
427					position: start,
428					continuation_error: None,
429				})
430			}
431		} else {
432			Err(Error::Incomplete)
433		}
434	})
435}
436
437/// Success when sequence of symbols matches current input.
438pub fn seq<'a, 'b: 'a, I>(tag: &'b [I]) -> Parser<'a, I, &'a [I]>
439where
440	I: PartialEq + Debug,
441{
442	Parser::new(move |input: &'a [I], start: usize| {
443		let mut index = 0;
444		loop {
445			let pos = start + index;
446			if index == tag.len() {
447				return Ok((tag, pos, None));
448			}
449			if let Some(s) = input.get(pos) {
450				if tag[index] != *s {
451					return Err(Error::Mismatch {
452						message: format!("seq {:?} expect: {:?}, found: {:?}", tag, tag[index], s),
453						position: pos,
454						continuation_error: None,
455					});
456				}
457			} else {
458				return Err(Error::Incomplete);
459			}
460			index += 1;
461		}
462	})
463}
464
465/// Success when tag matches current input.
466pub fn tag<'a, 'b: 'a>(tag: &'b str) -> Parser<'a, char, &'a str> {
467	Parser::new(move |input: &'a [char], start: usize| {
468		let mut pos = start;
469		for c in tag.chars() {
470			if let Some(&s) = input.get(pos) {
471				if c != s {
472					return Err(Error::Mismatch {
473						message: format!("tag {:?} expect: {:?}, found: {}", tag, c, s),
474						position: pos,
475						continuation_error: None,
476					});
477				}
478			} else {
479				return Err(Error::Incomplete);
480			}
481			pos += 1;
482		}
483		Ok((tag, pos, None))
484	})
485}
486
487/// Parse separated list.
488pub fn list<'a, I, O, U>(
489	parser: Parser<'a, I, O>,
490	separator: Parser<'a, I, U>,
491) -> Parser<'a, I, Vec<O>>
492where
493	O: 'a,
494	U: 'a,
495{
496	Parser::new(move |input: &'a [I], start: usize| {
497		let mut items = vec![];
498		let mut pos = start;
499		let mut cont_err = None;
500		match parser.parse_at(input, pos) {
501			Ok((first_item, first_pos, _)) => {
502				items.push(first_item);
503				pos = first_pos;
504				loop {
505					match separator.parse_at(input, pos) {
506						Ok((_, sep_pos, _)) => match parser.parse_at(input, sep_pos) {
507							Ok((more_item, more_pos, more_cont_err)) => {
508								items.push(more_item);
509								pos = more_pos;
510								cont_err = more_cont_err;
511							}
512							Err(err) => {
513								cont_err = merge_continuation_errors(
514									"<list>".into(),
515									pos,
516									cont_err,
517									Some(err),
518								);
519								break;
520							}
521						},
522						Err(err) => {
523							cont_err = merge_continuation_errors(
524								"<list>".into(),
525								pos,
526								cont_err,
527								Some(err),
528							);
529							break;
530						}
531					}
532				}
533			}
534			Err(err) => {
535				cont_err = Some(err);
536			}
537		}
538		Ok((items, pos, cont_err))
539	})
540}
541
542/// Success when current input symbol is one of the set.
543pub fn one_of<'a, I, S>(set: &'a S) -> Parser<'a, I, I>
544where
545	I: Clone + PartialEq + Display + Debug,
546	S: Set<I> + ?Sized,
547{
548	Parser::new(move |input: &'a [I], start: usize| {
549		if let Some(s) = input.get(start) {
550			if set.contains(s) {
551				Ok((s.clone(), start + 1, None))
552			} else {
553				Err(Error::Mismatch {
554					message: format!("expect one of: {}, found: {}", set.to_str(), s),
555					position: start,
556					continuation_error: None,
557				})
558			}
559		} else {
560			Err(Error::Incomplete)
561		}
562	})
563}
564
565/// Success when current input symbol is none of the set.
566pub fn none_of<'a, I, S>(set: &'static S) -> Parser<'a, I, I>
567where
568	I: Clone + PartialEq + Display + Debug,
569	S: Set<I> + ?Sized,
570{
571	Parser::new(move |input: &'a [I], start: usize| {
572		if let Some(s) = input.get(start) {
573			if set.contains(s) {
574				Err(Error::Mismatch {
575					message: format!("expect none of: {}, found: {}", set.to_str(), s),
576					position: start,
577					continuation_error: None,
578				})
579			} else {
580				Ok((s.clone(), start + 1, None))
581			}
582		} else {
583			Err(Error::Incomplete)
584		}
585	})
586}
587
588/// Success when predicate returns true on current input symbol.
589pub fn is_a<'a, I, F>(predicate: F) -> Parser<'a, I, I>
590where
591	I: Clone + PartialEq + Display + Debug,
592	F: Fn(I) -> bool + 'a,
593{
594	Parser::new(move |input: &'a [I], start: usize| {
595		if let Some(s) = input.get(start) {
596			if predicate(s.clone()) {
597				Ok((s.clone(), start + 1, None))
598			} else {
599				Err(Error::Mismatch {
600					message: format!("is_a predicate failed on: {}", s),
601					position: start,
602					continuation_error: None,
603				})
604			}
605		} else {
606			Err(Error::Incomplete)
607		}
608	})
609}
610
611/// Success when predicate returns false on current input symbol.
612pub fn not_a<'a, I, F>(predicate: F) -> Parser<'a, I, I>
613where
614	I: Clone + PartialEq + Display + Debug,
615	F: Fn(I) -> bool + 'a,
616{
617	Parser::new(move |input: &'a [I], start: usize| {
618		if let Some(s) = input.get(start) {
619			if predicate(s.clone()) {
620				Err(Error::Mismatch {
621					message: format!("not_a predicate failed on: {}", s),
622					position: start,
623					continuation_error: None,
624				})
625			} else {
626				Ok((s.clone(), start + 1, None))
627			}
628		} else {
629			Err(Error::Incomplete)
630		}
631	})
632}
633
634/// Read n symbols.
635pub fn take<'a, I>(n: usize) -> Parser<'a, I, &'a [I]> {
636	Parser::new(move |input: &'a [I], start: usize| {
637		let pos = start + n;
638		if input.len() >= pos {
639			Ok((&input[start..pos], pos, None))
640		} else {
641			Err(Error::Incomplete)
642		}
643	})
644}
645
646/// Skip n symbols.
647pub fn skip<'a, I>(n: usize) -> Parser<'a, I, ()> {
648	Parser::new(move |input: &'a [I], start: usize| {
649		let pos = start + n;
650		if input.len() >= pos {
651			Ok(((), pos, None))
652		} else {
653			Err(Error::Incomplete)
654		}
655	})
656}
657
658/// Call a parser factory, can be used to create recursive parsers.
659pub fn call<'a, I, O, F>(parser_factory: F) -> Parser<'a, I, O>
660where
661	O: 'a,
662	F: Fn() -> Parser<'a, I, O> + 'a,
663{
664	Parser::new(move |input: &'a [I], start: usize| {
665		let parser = parser_factory();
666		parser.parse_at(input, start)
667	})
668}
669
670/// Success when end of input is reached.
671pub fn end<'a, I>() -> Parser<'a, I, ()>
672where
673	I: Display,
674{
675	Parser::new(|input: &'a [I], start: usize| {
676		if let Some(s) = input.get(start) {
677			Err(Error::Mismatch {
678				message: format!("expect end of input, found: {}", s),
679				position: start,
680				continuation_error: None,
681			})
682		} else {
683			Ok(((), start, None))
684		}
685	})
686}
687
688/// Sequence reserve value
689impl<'a, I, O: 'a, U: 'a> Add<Parser<'a, I, U>> for Parser<'a, I, O> {
690	type Output = Parser<'a, I, (O, U)>;
691
692	fn add(self, other: Parser<'a, I, U>) -> Self::Output {
693		Parser::new(move |input: &'a [I], start: usize| {
694			self.parse_at(input, start)
695				.and_then(
696					|(out1, pos1, cont_err1)| match other.parse_at(input, pos1) {
697						Ok((out2, pos2, cont_err2)) => {
698							let cont_err = if pos2 == pos1 {
699								merge_continuation_errors(
700									"<Add>".into(),
701									pos2,
702									cont_err1,
703									cont_err2,
704								)
705							} else {
706								cont_err2
707							};
708							Ok(((out1, out2), pos2, cont_err))
709						}
710						Err(err2) => Err(cont_err1.map_or(err2.clone(), |err1| {
711							merge_errors("<Add>".into(), pos1, err1, err2)
712						})),
713					},
714				)
715		})
716	}
717}
718
719/// Sequence discard second value
720impl<'a, I, O: 'a, U: 'a> Sub<Parser<'a, I, U>> for Parser<'a, I, O> {
721	type Output = Parser<'a, I, O>;
722
723	fn sub(self, other: Parser<'a, I, U>) -> Self::Output {
724		Parser::new(move |input: &'a [I], start: usize| {
725			self.parse_at(input, start)
726				.and_then(
727					|(out1, pos1, cont_err1)| match other.parse_at(input, pos1) {
728						Ok((_, pos2, cont_err2)) => {
729							let cont_err = if pos2 == pos1 {
730								merge_continuation_errors(
731									"<Sub>".into(),
732									pos2,
733									cont_err1,
734									cont_err2,
735								)
736							} else {
737								cont_err2
738							};
739							Ok((out1, pos2, cont_err))
740						}
741						Err(err2) => Err(cont_err1.map_or(err2.clone(), |err1| {
742							merge_errors("<Sub>".into(), pos1, err1, err2)
743						})),
744					},
745				)
746		})
747	}
748}
749
750/// Sequence discard first value
751impl<'a, I: 'a, O: 'a, U: 'a> Mul<Parser<'a, I, U>> for Parser<'a, I, O> {
752	type Output = Parser<'a, I, U>;
753
754	fn mul(self, other: Parser<'a, I, U>) -> Self::Output {
755		Parser::new(move |input: &'a [I], start: usize| {
756			self.parse_at(input, start)
757				.and_then(|(_, pos1, cont_err1)| match other.parse_at(input, pos1) {
758					Ok((out2, pos2, cont_err2)) => {
759						let cont_err = if pos2 == pos1 {
760							merge_continuation_errors("<Mul>".into(), pos2, cont_err1, cont_err2)
761						} else {
762							cont_err2
763						};
764						Ok((out2, pos2, cont_err))
765					}
766					Err(err2) => Err(cont_err1.map_or(err2.clone(), |err1| {
767						merge_errors("<Mul>".into(), pos1, err1, err2)
768					})),
769				})
770		})
771	}
772}
773
774/// Chain two parsers where the second parser depends on the first's result.
775impl<'a, I, O: 'a, U: 'a, F: Fn(O) -> Parser<'a, I, U> + 'a> Shr<F> for Parser<'a, I, O> {
776	type Output = Parser<'a, I, U>;
777
778	fn shr(self, other: F) -> Self::Output {
779		Parser::new(move |input: &'a [I], start: usize| {
780			self.parse_at(input, start)
781				.and_then(|(out1, pos1, cont_err1)| {
782					other(out1)
783						.parse_at(input, pos1)
784						.map(|(out2, pos2, cont_err2)| {
785							let cont_err = if pos2 == pos1 {
786								merge_continuation_errors(
787									"<Shr>".into(),
788									pos2,
789									cont_err1,
790									cont_err2,
791								)
792							} else {
793								cont_err2
794							};
795							(out2, pos2, cont_err)
796						})
797				})
798		})
799	}
800}
801
802/// Ordered choice
803impl<'a, I, O: 'a> BitOr for Parser<'a, I, O> {
804	type Output = Parser<'a, I, O>;
805
806	fn bitor(self, other: Parser<'a, I, O>) -> Self::Output {
807		Parser::new(
808			move |input: &'a [I], start: usize| match self.parse_at(input, start) {
809				Ok(out) => Ok(out),
810				Err(err) => match err {
811					Error::Expect { .. } => Err(err),
812					_ => match other.parse_at(input, start) {
813						Ok((out, pos, cont_err2)) => {
814							let cont_err = if pos == start {
815								merge_continuation_errors(
816									"<Bitor>".into(),
817									pos,
818									Some(err),
819									cont_err2,
820								)
821							} else {
822								cont_err2
823							};
824							Ok((out, pos, cont_err))
825						}
826						Err(err2) => Err(merge_errors("<Bitor>".into(), start, err, err2)),
827					},
828				},
829			},
830		)
831	}
832}
833
834/// And predicate
835impl<'a, I, O: 'a> Neg for Parser<'a, I, O> {
836	type Output = Parser<'a, I, bool>;
837
838	fn neg(self) -> Self::Output {
839		Parser::new(move |input: &'a [I], start: usize| {
840			self.parse_at(input, start).map(|_| (true, start, None))
841		})
842	}
843}
844
845/// Not predicate
846impl<'a, I, O: 'a> Not for Parser<'a, I, O> {
847	type Output = Parser<'a, I, bool>;
848
849	fn not(self) -> Self::Output {
850		Parser::new(
851			move |input: &'a [I], start: usize| match self.parse_at(input, start) {
852				Ok(_) => Err(Error::Mismatch {
853					message: "not predicate failed".to_string(),
854					position: start,
855					continuation_error: None,
856				}),
857				Err(_) => Ok((true, start, None)),
858			},
859		)
860	}
861}
862
863#[cfg(test)]
864mod tests {
865	use crate::parser::*;
866	use crate::Error;
867
868	#[test]
869	fn byte_works() {
870		let input = b"abcde";
871		let parser = sym(b'a') + one_of(b"ab") - sym(b'C');
872		let output = parser.parse(input);
873		assert_eq!(
874			output,
875			Err(Error::Mismatch {
876				message: "expect: 67, found: 99".to_string(),
877				position: 2,
878				continuation_error: None,
879			})
880		);
881
882		let parser = sym(b'a') * none_of(b"AB") - sym(b'c') + seq(b"de");
883		let output = parser.parse(input);
884		assert_eq!(output, Ok((b'b', &b"de"[..])));
885		assert_eq!(parser.pos().parse(input), Ok(5));
886
887		let parser = sym(b'e') | sym(b'd').expect("d") | empty().map(|_| b'0');
888		let output = parser.parse(input);
889		assert_eq!(
890			output,
891			Err(Error::Expect {
892				message: "Expect d".to_owned(),
893				position: 0,
894				inner: Box::new(Error::Mismatch {
895					message: "expect: 100, found: 97".to_string(),
896					position: 0,
897					continuation_error: None,
898				})
899			})
900		);
901	}
902
903	#[test]
904	fn char_works() {
905		let input = "abcd".chars().collect::<Vec<char>>();
906		let parser = (tag("ab") + sym('c')) | sym('d').map(|_| ("", '0'));
907		let output = parser.parse(&input);
908		assert_eq!(output, Ok(("ab", 'c')));
909	}
910
911	#[test]
912	fn recursive_parser() {
913		#[derive(Debug, PartialEq)]
914		enum Expr {
915			Empty,
916			Group(Box<Expr>),
917		}
918		fn expr() -> Parser<'static, u8, Expr> {
919			(sym(b'(') + call(expr) - sym(b')')).map(|(_, e)| Expr::Group(Box::new(e)))
920				| empty().map(|_| Expr::Empty)
921		}
922		let input = b"(())";
923		let parser = expr();
924		let output = parser.parse(input);
925		assert_eq!(
926			output,
927			Ok(Expr::Group(Box::new(Expr::Group(Box::new(Expr::Empty)))))
928		);
929	}
930
931	#[test]
932	fn chain_parser() {
933		let input = b"5oooooooo";
934		{
935			let parser = one_of(b"0123456789").map(|c| c - b'0')
936				>> |n| take(n as usize) + sym(b'o').repeat(0..);
937			assert_eq!(parser.parse(input), Ok((&b"ooooo"[..], vec![b'o'; 3])));
938		}
939		{
940			let parser =
941				(skip(1) * take(3)) >> |v: &'static [u8]| take(v.len() + 2).map(move |u| (u, v));
942			assert_eq!(parser.parse(input), Ok((&b"ooooo"[..], &b"ooo"[..])));
943		}
944		{
945			let parser = Parser::new(move |input, start| {
946				(skip(1) * take(3))
947					.parse_at(input, start)
948					.and_then(|(v, pos, _)| {
949						take(v.len() + 2)
950							.parse_at(input, pos)
951							.map(|(u, end, _)| ((u, v), end, None))
952					})
953			});
954			assert_eq!(parser.parse(input), Ok((&b"ooooo"[..], &b"ooo"[..])));
955		}
956	}
957
958	#[test]
959	fn repeat_at_least() {
960		let input = b"xxxooo";
961
962		{
963			let parser = sym(b'x').repeat(1..2);
964			let output = parser.parse(input);
965			assert_eq!(output, Ok(vec![b'x'; 1]))
966		}
967
968		{
969			let parser = sym(b'x').repeat(1..);
970			let output = parser.parse(input);
971			assert_eq!(output, Ok(vec![b'x'; 3]))
972		}
973
974		{
975			let parser = sym(b'x').repeat(0..);
976			let output = parser.parse(input);
977			assert_eq!(output, Ok(vec![b'x'; 3]))
978		}
979
980		{
981			let parser = sym(b'y').repeat(0..);
982			let output = parser.parse(input);
983			assert_eq!(output, Ok(vec![]))
984		}
985
986		{
987			let parser = sym(b'y').repeat(1..);
988			let output = parser.parse(input);
989			assert!(output.is_err());
990		}
991
992		{
993			let parser = sym(b'x').repeat(10..);
994			let output = parser.parse(input);
995			assert!(output.is_err());
996		}
997	}
998
999	#[test]
1000	fn repeat_up_to() {
1001		let input = b"xxxooo";
1002
1003		{
1004			let parser = sym(b'x').repeat(..2);
1005			let output = parser.parse(input);
1006			assert_eq!(output, Ok(vec![b'x'; 1]))
1007		}
1008
1009		{
1010			let parser = sym(b'x').repeat(..4);
1011			let output = parser.parse(input);
1012			assert_eq!(output, Ok(vec![b'x'; 3]))
1013		}
1014
1015		{
1016			let parser = sym(b'x').repeat(..);
1017			let output = parser.parse(input);
1018			assert_eq!(output, Ok(vec![b'x'; 3]))
1019		}
1020
1021		{
1022			let parser = sym(b'x').repeat(..0);
1023			let output = parser.parse(input);
1024			assert_eq!(output, Ok(vec![]))
1025		}
1026
1027		{
1028			let parser = sym(b'x').repeat(..10);
1029			let output = parser.parse(input);
1030			assert_eq!(output, Ok(vec![b'x'; 3]))
1031		}
1032	}
1033
1034	#[test]
1035	fn repeat_exactly() {
1036		let input = b"xxxooo";
1037
1038		{
1039			let parser = sym(b'x').repeat(0);
1040			let output = parser.parse(input);
1041			assert_eq!(output, Ok(vec![]))
1042		}
1043
1044		{
1045			let parser = sym(b'x').repeat(1);
1046			let output = parser.parse(input);
1047			assert_eq!(output, Ok(vec![b'x'; 1]))
1048		}
1049
1050		{
1051			let parser = sym(b'x').repeat(2);
1052			let output = parser.parse(input);
1053			assert_eq!(output, Ok(vec![b'x'; 2]))
1054		}
1055
1056		{
1057			let parser = sym(b'x').repeat(3);
1058			let output = parser.parse(input);
1059			assert_eq!(output, Ok(vec![b'x'; 3]))
1060		}
1061
1062		{
1063			let parser = sym(b'x').repeat(4);
1064			let output = parser.parse(input);
1065			assert!(output.is_err())
1066		}
1067	}
1068}