diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 49 |
1 files changed, 38 insertions, 11 deletions
@@ -184,12 +184,17 @@ pub trait Parser<I: Input>: Sized { } } +pub struct ParserIterState { + finished: bool, +} + pub trait ParserIter<I: Input> { type Item; fn next<OM: Mode, EM: Mode>( &self, it: InputIter<I>, + state: &mut ParserIterState, ) -> Option<ParserResult<I, Self::Item, OM, EM>>; fn many(self) -> impl Parser<I, Output = Vec<Self::Item>> @@ -234,6 +239,7 @@ where fn next<OM: Mode, EM: Mode>( &self, it: InputIter<I>, + _: &mut ParserIterState, ) -> Option<ParserResult<I, Self::Item, OM, EM>> { if it.is_finished() { None @@ -262,8 +268,9 @@ where fn next<OM: Mode, EM: Mode>( &self, it: InputIter<I>, + state: &mut ParserIterState, ) -> Option<ParserResult<I, Self::Item, OM, EM>> { - if it.is_finished() { + if it.is_finished() || state.finished { None } else { let (rest, output) = match self.parser.run::<OM, EM>(it) { @@ -271,15 +278,16 @@ where Err(rest) => return Some(Err(rest)), }; - let rest = match self.delimiter.check(rest.clone()) { + match self.delimiter.check(rest.clone()) { Ok((rest, _)) => match self.parser.check(rest.clone()) { - Ok(_) => rest, - Err(_) => return Some(Err(EM::bind(|| rest))), + Ok(_) => Some(Ok((rest, output))), + Err(_) => Some(Err(EM::bind(|| rest))), }, - _ => rest, - }; - - Some(Ok((rest, output))) + _ => { + state.finished = true; + Some(Ok((rest, output))) + } + } } } } @@ -300,6 +308,7 @@ where fn next<OM: Mode, EM: Mode>( &self, it: InputIter<I>, + _: &mut ParserIterState, ) -> Option<ParserResult<I, Self::Item, OM, EM>> { if it.is_finished() { None @@ -340,9 +349,10 @@ where ) -> ParserResult<I, Self::Output, OM, EM> { let mut outputs = OM::bind(|| Vec::new()); let mut i = 0; + let mut state = ParserIterState { finished: false }; while !it.is_finished() { - it = match self.parser.next::<OM, EM>(it.clone()) { + it = match self.parser.next::<OM, EM>(it.clone(), &mut state) { Some(Ok((rest, output))) => { outputs = OM::combine(outputs, output, |mut acc, e| { acc.push(e); @@ -384,9 +394,10 @@ where mut it: InputIter<I>, ) -> ParserResult<I, Self::Output, OM, EM> { let mut outputs = OM::bind(|| Vec::new()); + let mut state = ParserIterState { finished: false }; for _ in 0..self.count { - it = match self.parser.next::<OM, EM>(it.clone()) { + it = match self.parser.next::<OM, EM>(it.clone(), &mut state) { Some(Ok((rest, output))) => { outputs = OM::combine(outputs, output, |mut acc, e| { acc.push(e); @@ -418,9 +429,10 @@ where mut it: InputIter<I>, ) -> ParserResult<I, Self::Output, OM, EM> { let mut outputs = OM::bind(|| Vec::new()); + let mut state = ParserIterState { finished: false }; while !it.is_finished() { - it = match self.parser.next::<OM, EM>(it.clone()) { + it = match self.parser.next::<OM, EM>(it.clone(), &mut state) { Some(Ok((rest, output))) => { outputs = OM::combine(outputs, output, |mut acc, e| { acc.push(e); @@ -922,6 +934,7 @@ where fn next<OM: Mode, EM: Mode>( &self, mut it: InputIter<I>, + _: &mut ParserIterState, ) -> Option<ParserResult<I, Self::Item, OM, EM>> { while !it.is_finished() { it = match self.parser.run::<OM, EM>(it.clone()) { @@ -1107,6 +1120,20 @@ mod test { } #[test] + fn test_separated_by_with_adjacent_p() { + let input = "p_p_pp_p"; + let it = InputIter::new(input); + + assert!( + tag("p") + .separated_by(tag("_")) + .at_least(1) + .check_finished(it) + .is_err() + ); + } + + #[test] fn test_separated_by_with_trailing_without_trailing() { let input = "1.0"; let it = InputIter::new(input); |
