From d26d37381fbfa33ebb2515114f5f9ceb76b61c37 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 27 Jun 2023 20:48:46 -0500 Subject: [PATCH 1/6] refactor(parser): Switch 'parse' to use 'parse_next' --- src/parser.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 753f6ef9..3b998a42 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -41,7 +41,7 @@ use crate::stream::{AsChar, Compare, Location, ParseSlice, Stream, StreamIsParti pub trait Parser { /// Parse all of `input`, generating `O` from it #[inline] - fn parse(&mut self, input: I) -> Result + fn parse(&mut self, mut input: I) -> Result where I: Stream, // Force users to deal with `Incomplete` when `StreamIsPartial` @@ -54,11 +54,11 @@ pub trait Parser { "partial streams need to handle `ErrMode::Incomplete`" ); - let (i, o) = self.parse_peek(input).map_err(|e| { + let o = self.parse_next(&mut input).map_err(|e| { e.into_inner() .expect("complete parsers should not report `ErrMode::Incomplete(_)`") })?; - let _ = crate::combinator::eof(i).map_err(|e| { + let _ = crate::combinator::eof.parse_next(&mut input).map_err(|e| { e.into_inner() .expect("complete parsers should not report `ErrMode::Incomplete(_)`") })?; From 29379d776229258dddc3901ef7e72ca660827ae3 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 28 Jun 2023 09:33:26 -0500 Subject: [PATCH 2/6] fix(parser)!: Switch inherent method from parse_next to parse_peek The `FnMut` impl is still focused on `parse_peek` --- src/combinator/parser.rs | 103 ++++++++++++++++++++++++++++++++++++++- src/parser.rs | 95 ++++++++++++++++++++++++++++++------ 2 files changed, 181 insertions(+), 17 deletions(-) diff --git a/src/combinator/parser.rs b/src/combinator/parser.rs index 0038dad5..72005a70 100644 --- a/src/combinator/parser.rs +++ b/src/combinator/parser.rs @@ -1,6 +1,7 @@ use crate::error::{ContextError, ErrMode, ErrorKind, FromExternalError, ParseError}; use crate::lib::std::borrow::Borrow; use crate::lib::std::ops::Range; +use crate::parser::unpeek; use crate::stream::StreamIsPartial; use crate::stream::{Location, Stream}; use crate::trace::trace; @@ -19,7 +20,15 @@ impl<'p, P> ByRef<'p, P> { } } -impl<'p, I, O, E, P: Parser> Parser for ByRef<'p, P> { +impl<'p, I, O, E, P: Parser> Parser for ByRef<'p, P> +where + I: Clone, +{ + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { self.p.parse_peek(i) } @@ -61,7 +70,13 @@ impl Parser for Map where F: Parser, G: Fn(O) -> O2, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { match self.parser.parse_peek(i) { Err(e) => Err(e), @@ -115,6 +130,11 @@ where I: Clone, E: FromExternalError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult { let i = input.clone(); let (input, o) = self.parser.parse_peek(input)?; @@ -170,6 +190,11 @@ where I: Clone, E: ParseError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult { let i = input.clone(); let (input, o) = self.parser.parse_peek(input)?; @@ -221,7 +246,13 @@ where F: Parser, G: Parser, O: StreamIsPartial, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { let (i, mut o) = self.outer.parse_peek(i)?; let _ = o.complete(); @@ -271,6 +302,11 @@ where O: crate::stream::ParseSlice, E: ParseError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { let input = i.clone(); let (i, o) = self.p.parse_peek(i)?; @@ -324,7 +360,13 @@ where F: Parser, G: FnMut(O) -> H, H: Parser, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { let (i, o) = self.f.parse_peek(i)?; (self.g)(o).parse_peek(i) @@ -349,6 +391,11 @@ where F: Parser, E: ParseError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult { trace("complete_err", |input: I| { let i = input.clone(); @@ -412,6 +459,11 @@ where O2: ?Sized, E: ParseError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult { let i = input.clone(); let (input, o) = self.parser.parse_peek(input)?; @@ -460,7 +512,13 @@ impl Parser for Value where F: Parser, O2: Clone, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult { (self.parser) .parse_peek(input) @@ -497,7 +555,13 @@ where impl Parser for Void where F: Parser, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<(), E> { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult { (self.parser).parse_peek(input).map(|(i, _)| (i, ())) } @@ -536,6 +600,11 @@ where F: Parser, I: Stream, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult::Slice, E> { let checkpoint = input.checkpoint(); match (self.parser).parse_peek(input) { @@ -583,6 +652,11 @@ where F: Parser, I: Stream, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<(O, ::Slice), E> { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult::Slice), E> { let checkpoint = input.checkpoint(); match (self.parser).parse_peek(input) { @@ -630,6 +704,11 @@ where F: Parser, I: Clone + Location, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult, E> { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult, E> { let start = input.location(); self.parser.parse_peek(input).map(move |(remaining, _)| { @@ -672,6 +751,11 @@ where F: Parser, I: Clone + Location, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<(O, Range), E> { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, input: I) -> IResult), E> { let start = input.location(); self.parser @@ -717,7 +801,13 @@ impl Parser for OutputInto where F: Parser, O: Into, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { match self.parser.parse_peek(i) { Ok((i, o)) => Ok((i, o.into())), @@ -760,7 +850,13 @@ impl Parser for ErrInto where F: Parser, E: Into, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { match self.parser.parse_peek(i) { Ok(ok) => Ok(ok), @@ -812,6 +908,11 @@ where E: ContextError, C: Clone + crate::lib::std::fmt::Debug, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + fn parse_peek(&mut self, i: I) -> IResult { #[cfg(feature = "debug")] let name = format!("context={:?}", self.context); diff --git a/src/parser.rs b/src/parser.rs index 3b998a42..5c2e8f4f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -70,24 +70,18 @@ pub trait Parser { /// This includes advancing the [`Stream`] to the next location. /// /// On error, `input` will be left pointing at the error location. - #[inline(always)] - fn parse_next(&mut self, input: &mut I) -> PResult - where - I: Clone, - { - match self.parse_peek((*input).clone()) { - Ok((i, o)) => { - *input = i; - Ok(o) - } - Err(err) => Err(err), - } - } + fn parse_next(&mut self, input: &mut I) -> PResult; /// Take tokens from the [`Stream`], turning it into the output /// /// This includes advancing the [`Stream`] to the next location. - fn parse_peek(&mut self, input: I) -> IResult; + #[inline(always)] + fn parse_peek(&mut self, mut input: I) -> IResult { + match self.parse_next(&mut input) { + Ok(o) => Ok((input, o)), + Err(err) => Err(err), + } + } /// Treat `&mut Self` as a parser /// @@ -632,7 +626,13 @@ pub trait Parser { impl<'a, I, O, E, F> Parser for F where F: FnMut(I) -> IResult + 'a, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult { self(i) @@ -660,6 +660,11 @@ where I: Stream, E: ParseError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult { crate::token::one_of(*self).parse_peek(i) @@ -688,6 +693,11 @@ where ::Token: AsChar + Copy, E: ParseError, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<::Token, E> { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult::Token, E> { crate::token::one_of(*self).parse_peek(i) @@ -717,6 +727,11 @@ where I: Compare<&'s [u8]> + StreamIsPartial, I: Stream, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { crate::token::tag(*self).parse_peek(i) @@ -746,6 +761,11 @@ where I: Compare<&'s [u8; N]> + StreamIsPartial, I: Stream, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { crate::token::tag(*self).parse_peek(i) @@ -775,13 +795,26 @@ where I: Compare<&'s str> + StreamIsPartial, I: Stream, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { crate::token::tag(*self).parse_peek(i) } } -impl> Parser for () { +impl> Parser for () +where + I: Clone, +{ + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<(), E> { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult { Ok((i, ())) @@ -793,8 +826,14 @@ macro_rules! impl_parser_for_tuple { #[allow(non_snake_case)] impl, $($parser),+> Parser for ($($parser),+,) where + I: Clone, $($parser: Parser),+ { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult<($($output),+,), E> { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult { let ($(ref mut $parser),+,) = *self; @@ -848,13 +887,37 @@ impl_parser_for_tuples!( use alloc::boxed::Box; #[cfg(feature = "alloc")] -impl<'a, I, O, E> Parser for Box + 'a> { +impl<'a, I, O, E> Parser for Box + 'a> +where + I: Clone, +{ + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, input: I) -> IResult { (**self).parse_peek(input) } } +#[inline(always)] +pub(crate) fn unpeek<'a, I, O, E>( + mut peek: impl FnMut(I) -> IResult + 'a, +) -> impl FnMut(&mut I) -> PResult +where + I: Clone, +{ + move |input| match peek((*input).clone()) { + Ok((i, o)) => { + *input = i; + Ok(o) + } + Err(err) => Err(err), + } +} + #[cfg(test)] mod tests { use super::*; From 535d8a7ad5c8d45d6b6e7b51a644f188c0eb61f2 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 28 Jun 2023 09:38:46 -0500 Subject: [PATCH 3/6] refactor(parser): Switch built-in impls to use parse_next --- src/parser.rs | 71 +++++++++------------------------------------------ 1 file changed, 12 insertions(+), 59 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 5c2e8f4f..ba12e5e7 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -662,12 +662,7 @@ where { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult { - crate::token::one_of(*self).parse_peek(i) + crate::token::one_of(*self).parse_next(i) } } @@ -695,12 +690,7 @@ where { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult<::Token, E> { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Token, E> { - crate::token::one_of(*self).parse_peek(i) + crate::token::one_of(*self).parse_next(i) } } @@ -729,12 +719,7 @@ where { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { - crate::token::tag(*self).parse_peek(i) + crate::token::tag(*self).parse_next(i) } } @@ -763,12 +748,7 @@ where { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { - crate::token::tag(*self).parse_peek(i) + crate::token::tag(*self).parse_next(i) } } @@ -797,27 +777,14 @@ where { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { - crate::token::tag(*self).parse_peek(i) + crate::token::tag(*self).parse_next(i) } } -impl> Parser for () -where - I: Clone, -{ +impl> Parser for () { #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult<(), E> { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult { - Ok((i, ())) + fn parse_next(&mut self, _i: &mut I) -> PResult<(), E> { + Ok(()) } } @@ -826,21 +793,15 @@ macro_rules! impl_parser_for_tuple { #[allow(non_snake_case)] impl, $($parser),+> Parser for ($($parser),+,) where - I: Clone, $($parser: Parser),+ { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult<($($output),+,), E> { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult { let ($(ref mut $parser),+,) = *self; - $(let(i, $output) = $parser.parse_peek(i)?;)+ + $(let $output = $parser.parse_next(i)?;)+ - Ok((i, ($($output),+,))) + Ok(($($output),+,)) } } ) @@ -887,18 +848,10 @@ impl_parser_for_tuples!( use alloc::boxed::Box; #[cfg(feature = "alloc")] -impl<'a, I, O, E> Parser for Box + 'a> -where - I: Clone, -{ +impl<'a, I, O, E> Parser for Box + 'a> { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - #[inline(always)] - fn parse_peek(&mut self, input: I) -> IResult { - (**self).parse_peek(input) + (**self).parse_next(i) } } From e2b304576109f5c1424a2b8f381994fbdc4b063f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 28 Jun 2023 09:40:57 -0500 Subject: [PATCH 4/6] refactor(parser): Switch inherent parsers to parse_next --- src/combinator/parser.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/combinator/parser.rs b/src/combinator/parser.rs index 72005a70..5e8999ae 100644 --- a/src/combinator/parser.rs +++ b/src/combinator/parser.rs @@ -26,11 +26,7 @@ where { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - self.p.parse_peek(i) + self.p.parse_next(i) } } From edd851466aa145003f3da538b9c212cf61e8be81 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 28 Jun 2023 11:11:42 -0500 Subject: [PATCH 5/6] refactor(parser): Switch inherent parser impls to parse_next --- src/combinator/parser.rs | 296 +++++++++++++++------------------------ src/parser.rs | 45 +++++- 2 files changed, 152 insertions(+), 189 deletions(-) diff --git a/src/combinator/parser.rs b/src/combinator/parser.rs index 5e8999ae..341eddee 100644 --- a/src/combinator/parser.rs +++ b/src/combinator/parser.rs @@ -1,7 +1,7 @@ use crate::error::{ContextError, ErrMode, ErrorKind, FromExternalError, ParseError}; use crate::lib::std::borrow::Borrow; use crate::lib::std::ops::Range; -use crate::parser::unpeek; +use crate::parser::parser; use crate::stream::StreamIsPartial; use crate::stream::{Location, Stream}; use crate::trace::trace; @@ -20,10 +20,7 @@ impl<'p, P> ByRef<'p, P> { } } -impl<'p, I, O, E, P: Parser> Parser for ByRef<'p, P> -where - I: Clone, -{ +impl<'p, I, O, E, P: Parser> Parser for ByRef<'p, P> { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { self.p.parse_next(i) @@ -66,17 +63,12 @@ impl Parser for Map where F: Parser, G: Fn(O) -> O2, - I: Clone, { - #[inline(always)] + #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - match self.parser.parse_peek(i) { + match self.parser.parse_next(i) { Err(e) => Err(e), - Ok((i, o)) => Ok((i, (self.map)(o))), + Ok(o) => Ok((self.map)(o)), } } } @@ -87,7 +79,7 @@ pub struct TryMap where F: Parser, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { parser: F, @@ -103,7 +95,7 @@ impl TryMap where F: Parser, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { pub(crate) fn new(parser: F, map: G) -> Self { @@ -123,21 +115,17 @@ impl Parser for TryMap where F: Parser, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult { - let i = input.clone(); - let (input, o) = self.parser.parse_peek(input)?; - let res = match (self.map)(o) { - Ok(o2) => Ok((input, o2)), - Err(e) => Err(ErrMode::from_external_error(i, ErrorKind::Verify, e)), - }; + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + let start = input.checkpoint(); + let o = self.parser.parse_next(input)?; + let res = (self.map)(o).map_err(|err| { + input.reset(start); + ErrMode::from_external_error(input.clone(), ErrorKind::Verify, err) + }); trace_result("verify", &res); res } @@ -149,7 +137,7 @@ pub struct VerifyMap where F: Parser, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { parser: F, @@ -164,7 +152,7 @@ impl VerifyMap where F: Parser, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { pub(crate) fn new(parser: F, map: G) -> Self { @@ -183,21 +171,17 @@ impl Parser for VerifyMap where F: Parser, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult { - let i = input.clone(); - let (input, o) = self.parser.parse_peek(input)?; - let res = match (self.map)(o) { - Some(o2) => Ok((input, o2)), - None => Err(ErrMode::from_error_kind(i, ErrorKind::Verify)), - }; + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + let start = input.checkpoint(); + let o = self.parser.parse_next(input)?; + let res = (self.map)(o).ok_or_else(|| { + input.reset(start); + ErrMode::from_error_kind(input.clone(), ErrorKind::Verify) + }); trace_result("verify", &res); res } @@ -210,6 +194,7 @@ where F: Parser, G: Parser, O: StreamIsPartial, + I: Stream, { outer: F, inner: G, @@ -224,6 +209,7 @@ where F: Parser, G: Parser, O: StreamIsPartial, + I: Stream, { pub(crate) fn new(outer: F, inner: G) -> Self { Self { @@ -242,18 +228,18 @@ where F: Parser, G: Parser, O: StreamIsPartial, - I: Clone, + I: Stream, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - let (i, mut o) = self.outer.parse_peek(i)?; + let start = i.checkpoint(); + let mut o = self.outer.parse_next(i)?; let _ = o.complete(); - let (_, o2) = self.inner.parse_peek(o)?; - Ok((i, o2)) + let o2 = self.inner.parse_next(&mut o).map_err(|err| { + i.reset(start); + err + })?; + Ok(o2) } } @@ -298,20 +284,16 @@ where O: crate::stream::ParseSlice, E: ParseError, { - #[inline(always)] + #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - let input = i.clone(); - let (i, o) = self.p.parse_peek(i)?; - - let res = o - .parse_slice() - .ok_or_else(|| ErrMode::from_error_kind(input, ErrorKind::Verify)); + let start = i.checkpoint(); + let o = self.p.parse_next(i)?; + let res = o.parse_slice().ok_or_else(|| { + i.reset(start); + ErrMode::from_error_kind(i.clone(), ErrorKind::Verify) + }); trace_result("verify", &res); - Ok((i, res?)) + res } } @@ -356,16 +338,11 @@ where F: Parser, G: FnMut(O) -> H, H: Parser, - I: Clone, { #[inline(always)] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - let (i, o) = self.f.parse_peek(i)?; - (self.g)(o).parse_peek(i) + let o = self.f.parse_next(i)?; + (self.g)(o).parse_next(i) } } @@ -387,22 +364,18 @@ where F: Parser, E: ParseError, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult { - trace("complete_err", |input: I| { - let i = input.clone(); - match (self.f).parse_peek(input) { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + trace( + "complete_err", + parser(|input: &mut I| match (self.f).parse_next(input) { Err(ErrMode::Incomplete(_)) => { - Err(ErrMode::from_error_kind(i, ErrorKind::Complete)) + Err(ErrMode::from_error_kind(input.clone(), ErrorKind::Complete)) } rest => rest, - } - }) - .parse_peek(input) + }), + ) + .parse_next(input) } } @@ -412,7 +385,7 @@ pub struct Verify where F: Parser, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: Borrow, O2: ?Sized, E: ParseError, @@ -429,7 +402,7 @@ impl Verify where F: Parser, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: Borrow, O2: ?Sized, E: ParseError, @@ -450,25 +423,19 @@ impl Parser for Verify where F: Parser, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: Borrow, O2: ?Sized, E: ParseError, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult { - let i = input.clone(); - let (input, o) = self.parser.parse_peek(input)?; - - let res = if (self.filter)(o.borrow()) { - Ok((input, o)) - } else { - Err(ErrMode::from_error_kind(i, ErrorKind::Verify)) - }; + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + let start = input.checkpoint(); + let o = self.parser.parse_next(input)?; + let res = (self.filter)(o.borrow()).then_some(o).ok_or_else(|| { + input.reset(start); + ErrMode::from_error_kind(input.clone(), ErrorKind::Verify) + }); trace_result("verify", &res); res } @@ -508,17 +475,10 @@ impl Parser for Value where F: Parser, O2: Clone, - I: Clone, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult { - (self.parser) - .parse_peek(input) - .map(|(i, _)| (i, self.val.clone())) + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + (self.parser).parse_next(input).map(|_| self.val.clone()) } } @@ -551,15 +511,10 @@ where impl Parser for Void where F: Parser, - I: Clone, { #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult<(), E> { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult { - (self.parser).parse_peek(input).map(|(i, _)| (i, ())) + fn parse_next(&mut self, input: &mut I) -> PResult<(), E> { + (self.parser).parse_next(input).map(|_| ()) } } @@ -596,19 +551,15 @@ where F: Parser, I: Stream, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult::Slice, E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult<::Slice, E> { let checkpoint = input.checkpoint(); - match (self.parser).parse_peek(input) { - Ok((mut input, _)) => { + match (self.parser).parse_next(input) { + Ok(_) => { let offset = input.offset_from(&checkpoint); input.reset(checkpoint); - let (input, recognized) = input.peek_slice(offset); - Ok((input, recognized)) + let recognized = input.next_slice(offset); + Ok(recognized) } Err(e) => Err(e), } @@ -648,19 +599,15 @@ where F: Parser, I: Stream, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult<(O, ::Slice), E> { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult::Slice), E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult<(O, ::Slice), E> { let checkpoint = input.checkpoint(); - match (self.parser).parse_peek(input) { - Ok((mut input, result)) => { + match (self.parser).parse_next(input) { + Ok(result) => { let offset = input.offset_from(&checkpoint); input.reset(checkpoint); - let (input, recognized) = input.peek_slice(offset); - Ok((input, (result, recognized))) + let recognized = input.next_slice(offset); + Ok((result, recognized)) } Err(e) => Err(e), } @@ -700,16 +647,12 @@ where F: Parser, I: Clone + Location, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult, E> { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult, E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult, E> { let start = input.location(); - self.parser.parse_peek(input).map(move |(remaining, _)| { - let end = remaining.location(); - (remaining, (start..end)) + self.parser.parse_next(input).map(move |_| { + let end = input.location(); + start..end }) } } @@ -747,19 +690,13 @@ where F: Parser, I: Clone + Location, { - #[inline(always)] - fn parse_next(&mut self, i: &mut I) -> PResult<(O, Range), E> { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, input: I) -> IResult), E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult<(O, Range), E> { let start = input.location(); - self.parser - .parse_peek(input) - .map(move |(remaining, output)| { - let end = remaining.location(); - (remaining, (output, (start..end))) - }) + self.parser.parse_next(input).map(move |output| { + let end = input.location(); + (output, (start..end)) + }) } } @@ -797,18 +734,10 @@ impl Parser for OutputInto where F: Parser, O: Into, - I: Clone, { - #[inline(always)] + #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - match self.parser.parse_peek(i) { - Ok((i, o)) => Ok((i, o.into())), - Err(err) => Err(err), - } + self.parser.parse_next(i).map(|o| o.into()) } } @@ -846,15 +775,10 @@ impl Parser for ErrInto where F: Parser, E: Into, - I: Clone, { - #[inline(always)] + #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { - match self.parser.parse_peek(i) { + match self.parser.parse_next(i) { Ok(ok) => Ok(ok), Err(ErrMode::Backtrack(e)) => Err(ErrMode::Backtrack(e.into())), Err(ErrMode::Cut(e)) => Err(ErrMode::Cut(e.into())), @@ -904,21 +828,21 @@ where E: ContextError, C: Clone + crate::lib::std::fmt::Debug, { - #[inline(always)] + #[inline] fn parse_next(&mut self, i: &mut I) -> PResult { - unpeek(|i| self.parse_peek(i))(i) - } - - fn parse_peek(&mut self, i: I) -> IResult { #[cfg(feature = "debug")] let name = format!("context={:?}", self.context); #[cfg(not(feature = "debug"))] let name = "context"; - trace(name, move |i: I| { - (self.parser) - .parse_peek(i.clone()) - .map_err(|err| err.map(|err| err.add_context(i, self.context.clone()))) - }) - .parse_peek(i) + trace( + name, + parser(move |i: &mut I| { + let start = i.clone(); + (self.parser) + .parse_next(i) + .map_err(|err| err.map(|err| err.add_context(start, self.context.clone()))) + }), + ) + .parse_next(i) } } diff --git a/src/parser.rs b/src/parser.rs index ba12e5e7..a515e0ff 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -406,7 +406,7 @@ pub trait Parser { where Self: core::marker::Sized, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { TryMap::new(self, map) @@ -440,7 +440,7 @@ pub trait Parser { where Self: core::marker::Sized, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { VerifyMap::new(self, map) @@ -509,6 +509,7 @@ pub trait Parser { Self: core::marker::Sized, G: Parser, O: StreamIsPartial, + I: Stream, { AndThen::new(self, inner) } @@ -568,7 +569,7 @@ pub trait Parser { where Self: core::marker::Sized, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: crate::lib::std::borrow::Borrow, O2: ?Sized, E: ParseError, @@ -871,6 +872,44 @@ where } } +#[inline(always)] +pub(crate) fn parser(parser: impl FnMut(&mut I) -> PResult) -> impl Parser { + struct Wrapper + where + P: FnMut(&mut I) -> PResult, + { + p: P, + i: core::marker::PhantomData, + o: core::marker::PhantomData, + e: core::marker::PhantomData, + } + + impl Wrapper + where + P: FnMut(&mut I) -> PResult, + { + pub(crate) fn new(p: P) -> Self { + Self { + p, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } + } + + impl Parser for Wrapper + where + P: FnMut(&mut I) -> PResult, + { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + (self.p)(i) + } + } + Wrapper::new(parser) +} + #[cfg(test)] mod tests { use super::*; From d3a288c8b6f828a7bc0a755ccd2ee003ea14678c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 28 Jun 2023 15:31:50 -0500 Subject: [PATCH 6/6] refactor(ascii): Remove superfluous closures This will make some `parse_peek` to `parse_next` conversions to be automatic. --- src/ascii/mod.rs | 121 +++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/src/ascii/mod.rs b/src/ascii/mod.rs index aefa647b..be423c87 100644 --- a/src/ascii/mod.rs +++ b/src/ascii/mod.rs @@ -56,7 +56,7 @@ where I: Stream, I: Compare<&'static str>, { - trace("crlf", move |input: I| "\r\n".parse_peek(input)).parse_peek(input) + trace("crlf", "\r\n").parse_peek(input) } /// Recognizes a string of any char except '\r\n' or '\n'. @@ -183,10 +183,7 @@ where I: Stream, I: Compare<&'static str>, { - trace("line_ending", move |input: I| { - alt(("\n", "\r\n")).parse_peek(input) - }) - .parse_peek(input) + trace("line_ending", alt(("\n", "\r\n"))).parse_peek(input) } /// Matches a newline character '\n'. @@ -224,11 +221,7 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("newline", move |input: I| { - '\n'.map(|c: ::Token| c.as_char()) - .parse_peek(input) - }) - .parse_peek(input) + trace("newline", '\n'.map(|c: ::Token| c.as_char())).parse_peek(input) } /// Matches a tab character '\t'. @@ -266,11 +259,7 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("tab", move |input: I| { - '\t'.map(|c: ::Token| c.as_char()) - .parse_peek(input) - }) - .parse_peek(input) + trace("tab", '\t'.map(|c: ::Token| c.as_char())).parse_peek(input) } /// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z @@ -310,9 +299,10 @@ where I: Stream, ::Token: AsChar, { - trace("alpha0", move |input: I| { - take_while(0.., |c: ::Token| c.is_alpha()).parse_peek(input) - }) + trace( + "alpha0", + take_while(0.., |c: ::Token| c.is_alpha()), + ) .parse_peek(input) } @@ -353,9 +343,10 @@ where I: Stream, ::Token: AsChar, { - trace("alpha1", move |input: I| { - take_while(1.., |c: ::Token| c.is_alpha()).parse_peek(input) - }) + trace( + "alpha1", + take_while(1.., |c: ::Token| c.is_alpha()), + ) .parse_peek(input) } @@ -397,9 +388,10 @@ where I: Stream, ::Token: AsChar, { - trace("digit0", move |input: I| { - take_while(0.., |c: ::Token| c.is_dec_digit()).parse_peek(input) - }) + trace( + "digit0", + take_while(0.., |c: ::Token| c.is_dec_digit()), + ) .parse_peek(input) } @@ -456,9 +448,10 @@ where I: Stream, ::Token: AsChar, { - trace("digit1", move |input: I| { - take_while(1.., |c: ::Token| c.is_dec_digit()).parse_peek(input) - }) + trace( + "digit1", + take_while(1.., |c: ::Token| c.is_dec_digit()), + ) .parse_peek(input) } @@ -498,9 +491,10 @@ where I: Stream, ::Token: AsChar, { - trace("hex_digit0", move |input: I| { - take_while(0.., |c: ::Token| c.is_hex_digit()).parse_peek(input) - }) + trace( + "hex_digit0", + take_while(0.., |c: ::Token| c.is_hex_digit()), + ) .parse_peek(input) } @@ -541,9 +535,10 @@ where I: Stream, ::Token: AsChar, { - trace("hex_digit1", move |input: I| { - take_while(1.., |c: ::Token| c.is_hex_digit()).parse_peek(input) - }) + trace( + "hex_digit1", + take_while(1.., |c: ::Token| c.is_hex_digit()), + ) .parse_peek(input) } @@ -584,9 +579,10 @@ where I: Stream, ::Token: AsChar, { - trace("oct_digit0", move |input: I| { - take_while(0.., |c: ::Token| c.is_oct_digit()).parse_peek(input) - }) + trace( + "oct_digit0", + take_while(0.., |c: ::Token| c.is_oct_digit()), + ) .parse_peek(input) } @@ -627,9 +623,10 @@ where I: Stream, ::Token: AsChar, { - trace("oct_digit0", move |input: I| { - take_while(1.., |c: ::Token| c.is_oct_digit()).parse_peek(input) - }) + trace( + "oct_digit0", + take_while(1.., |c: ::Token| c.is_oct_digit()), + ) .parse_peek(input) } @@ -670,9 +667,10 @@ where I: Stream, ::Token: AsChar, { - trace("alphanumeric0", move |input: I| { - take_while(0.., |c: ::Token| c.is_alphanum()).parse_peek(input) - }) + trace( + "alphanumeric0", + take_while(0.., |c: ::Token| c.is_alphanum()), + ) .parse_peek(input) } @@ -713,9 +711,10 @@ where I: Stream, ::Token: AsChar, { - trace("alphanumeric1", move |input: I| { - take_while(1.., |c: ::Token| c.is_alphanum()).parse_peek(input) - }) + trace( + "alphanumeric1", + take_while(1.., |c: ::Token| c.is_alphanum()), + ) .parse_peek(input) } @@ -744,13 +743,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("space0", move |input: I| { + trace( + "space0", take_while(0.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } @@ -791,13 +790,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("space1", move |input: I| { + trace( + "space1", take_while(1.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } @@ -838,13 +837,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("multispace0", move |input: I| { + trace( + "multispace0", take_while(0.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t' | '\r' | '\n') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } @@ -885,13 +884,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("multispace1", move |input: I| { + trace( + "multispace1", take_while(1.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t' | '\r' | '\n') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) }