aboutsummaryrefslogtreecommitdiff
path: root/src/sequence/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sequence/mod.rs')
-rw-r--r--src/sequence/mod.rs190
1 files changed, 117 insertions, 73 deletions
diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs
index a0eafb9..3d76725 100644
--- a/src/sequence/mod.rs
+++ b/src/sequence/mod.rs
@@ -1,10 +1,10 @@
-//! combinators applying parsers in sequence
+//! Combinators applying parsers in sequence
#[macro_use]
mod macros;
-use crate::internal::IResult;
use crate::error::ParseError;
+use crate::internal::{IResult, Parser};
/// Gets an object from the first parser,
/// then gets another object from the second parser.
@@ -18,27 +18,34 @@ use crate::error::ParseError;
/// use nom::sequence::pair;
/// use nom::bytes::complete::tag;
///
-/// let parser = pair(tag("abc"), tag("efg"));
+/// let mut parser = pair(tag("abc"), tag("efg"));
///
/// assert_eq!(parser("abcefg"), Ok(("", ("abc", "efg"))));
/// assert_eq!(parser("abcefghij"), Ok(("hij", ("abc", "efg"))));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
-pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, (O1, O2), E>
+pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(
+ mut first: F,
+ mut second: G,
+) -> impl FnMut(I) -> IResult<I, (O1, O2), E>
where
- F: Fn(I) -> IResult<I, O1, E>,
- G: Fn(I) -> IResult<I, O2, E>,
+ F: Parser<I, O1, E>,
+ G: Parser<I, O2, E>,
{
move |input: I| {
- let (input, o1) = first(input)?;
- second(input).map(|(i, o2)| (i, (o1, o2)))
+ let (input, o1) = first.parse(input)?;
+ second.parse(input).map(|(i, o2)| (i, (o1, o2)))
}
}
// this implementation is used for type inference issues in macros
#[doc(hidden)]
-pub fn pairc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, (O1, O2), E>
+pub fn pairc<I, O1, O2, E: ParseError<I>, F, G>(
+ input: I,
+ first: F,
+ second: G,
+) -> IResult<I, (O1, O2), E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@@ -58,27 +65,34 @@ where
/// use nom::sequence::preceded;
/// use nom::bytes::complete::tag;
///
-/// let parser = preceded(tag("abc"), tag("efg"));
+/// let mut parser = preceded(tag("abc"), tag("efg"));
///
/// assert_eq!(parser("abcefg"), Ok(("", "efg")));
/// assert_eq!(parser("abcefghij"), Ok(("hij", "efg")));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
-pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O2, E>
+pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(
+ mut first: F,
+ mut second: G,
+) -> impl FnMut(I) -> IResult<I, O2, E>
where
- F: Fn(I) -> IResult<I, O1, E>,
- G: Fn(I) -> IResult<I, O2, E>,
+ F: Parser<I, O1, E>,
+ G: Parser<I, O2, E>,
{
move |input: I| {
- let (input, _) = first(input)?;
- second(input)
+ let (input, _) = first.parse(input)?;
+ second.parse(input)
}
}
// this implementation is used for type inference issues in macros
#[doc(hidden)]
-pub fn precededc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
+pub fn precededc<I, O1, O2, E: ParseError<I>, F, G>(
+ input: I,
+ first: F,
+ second: G,
+) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@@ -98,27 +112,34 @@ where
/// use nom::sequence::terminated;
/// use nom::bytes::complete::tag;
///
-/// let parser = terminated(tag("abc"), tag("efg"));
+/// let mut parser = terminated(tag("abc"), tag("efg"));
///
/// assert_eq!(parser("abcefg"), Ok(("", "abc")));
/// assert_eq!(parser("abcefghij"), Ok(("hij", "abc")));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
-pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(first: F, second: G) -> impl Fn(I) -> IResult<I, O1, E>
+pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(
+ mut first: F,
+ mut second: G,
+) -> impl FnMut(I) -> IResult<I, O1, E>
where
- F: Fn(I) -> IResult<I, O1, E>,
- G: Fn(I) -> IResult<I, O2, E>,
+ F: Parser<I, O1, E>,
+ G: Parser<I, O2, E>,
{
move |input: I| {
- let (input, o1) = first(input)?;
- second(input).map(|(i, _)| (i, o1))
+ let (input, o1) = first.parse(input)?;
+ second.parse(input).map(|(i, _)| (i, o1))
}
}
// this implementation is used for type inference issues in macros
#[doc(hidden)]
-pub fn terminatedc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O1, E>
+pub fn terminatedc<I, O1, O2, E: ParseError<I>, F, G>(
+ input: I,
+ first: F,
+ second: G,
+) -> IResult<I, O1, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@@ -140,29 +161,38 @@ where
/// use nom::sequence::separated_pair;
/// use nom::bytes::complete::tag;
///
-/// let parser = separated_pair(tag("abc"), tag("|"), tag("efg"));
+/// let mut parser = separated_pair(tag("abc"), tag("|"), tag("efg"));
///
/// assert_eq!(parser("abc|efg"), Ok(("", ("abc", "efg"))));
/// assert_eq!(parser("abc|efghij"), Ok(("hij", ("abc", "efg"))));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
-pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult<I, (O1, O3), E>
+pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
+ mut first: F,
+ mut sep: G,
+ mut second: H,
+) -> impl FnMut(I) -> IResult<I, (O1, O3), E>
where
- F: Fn(I) -> IResult<I, O1, E>,
- G: Fn(I) -> IResult<I, O2, E>,
- H: Fn(I) -> IResult<I, O3, E>,
+ F: Parser<I, O1, E>,
+ G: Parser<I, O2, E>,
+ H: Parser<I, O3, E>,
{
move |input: I| {
- let (input, o1) = first(input)?;
- let (input, _) = sep(input)?;
- second(input).map(|(i, o2)| (i, (o1, o2)))
+ let (input, o1) = first.parse(input)?;
+ let (input, _) = sep.parse(input)?;
+ second.parse(input).map(|(i, o2)| (i, (o1, o2)))
}
}
// this implementation is used for type inference issues in macros
#[doc(hidden)]
-pub fn separated_pairc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, (O1, O3), E>
+pub fn separated_pairc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
+ input: I,
+ first: F,
+ sep: G,
+ second: H,
+) -> IResult<I, (O1, O3), E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@@ -171,63 +201,74 @@ where
separated_pair(first, sep, second)(input)
}
-/// Matches an object from the first parser,
-/// then gets an object from the sep_parser,
-/// then matches another object from the second parser.
+/// Matches an object from the first parser and discards it,
+/// then gets an object from the second parser,
+/// and finally matches an object from the third parser and discards it.
///
/// # Arguments
-/// * `first` The first parser to apply.
-/// * `sep` The separator parser to apply.
+/// * `first` The first parser to apply and discard.
/// * `second` The second parser to apply.
+/// * `third` The third parser to apply and discard.
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
/// use nom::sequence::delimited;
/// use nom::bytes::complete::tag;
///
-/// let parser = delimited(tag("abc"), tag("|"), tag("efg"));
+/// let mut parser = delimited(tag("("), tag("abc"), tag(")"));
///
-/// assert_eq!(parser("abc|efg"), Ok(("", "|")));
-/// assert_eq!(parser("abc|efghij"), Ok(("hij", "|")));
+/// assert_eq!(parser("(abc)"), Ok(("", "abc")));
+/// assert_eq!(parser("(abc)def"), Ok(("def", "abc")));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
-pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult<I, O2, E>
+pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
+ mut first: F,
+ mut second: G,
+ mut third: H,
+) -> impl FnMut(I) -> IResult<I, O2, E>
where
- F: Fn(I) -> IResult<I, O1, E>,
- G: Fn(I) -> IResult<I, O2, E>,
- H: Fn(I) -> IResult<I, O3, E>,
+ F: Parser<I, O1, E>,
+ G: Parser<I, O2, E>,
+ H: Parser<I, O3, E>,
{
move |input: I| {
- let (input, _) = first(input)?;
- let (input, o2) = sep(input)?;
- second(input).map(|(i, _)| (i, o2))
+ let (input, _) = first.parse(input)?;
+ let (input, o2) = second.parse(input)?;
+ third.parse(input).map(|(i, _)| (i, o2))
}
}
// this implementation is used for type inference issues in macros
#[doc(hidden)]
-pub fn delimitedc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, O2, E>
+pub fn delimitedc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
+ input: I,
+ first: F,
+ second: G,
+ third: H,
+) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
H: Fn(I) -> IResult<I, O3, E>,
{
- delimited(first, sep, second)(input)
+ delimited(first, second, third)(input)
}
-/// helper trait for the tuple combinator
+/// Helper trait for the tuple combinator.
///
-/// this trait is implemented for tuples of parsers of up to 21 elements
-pub trait Tuple<I,O,E> {
- /// parses the input and returns a tuple of results of each parser
- fn parse(&self, input: I) -> IResult<I,O,E>;
+/// This trait is implemented for tuples of parsers of up to 21 elements.
+pub trait Tuple<I, O, E> {
+ /// Parses the input and returns a tuple of results of each parser.
+ fn parse(&mut self, input: I) -> IResult<I, O, E>;
}
-impl<Input, Output, Error: ParseError<Input>, F: Fn(Input) -> IResult<Input, Output, Error> > Tuple<Input, (Output,), Error> for (F,) {
- fn parse(&self, input: Input) -> IResult<Input,(Output,),Error> {
- self.0(input).map(|(i,o)| (i, (o,)))
- }
+impl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output, Error>>
+ Tuple<Input, (Output,), Error> for (F,)
+{
+ fn parse(&mut self, input: Input) -> IResult<Input, (Output,), Error> {
+ self.0.parse(input).map(|(i, o)| (i, (o,)))
+ }
}
macro_rules! tuple_trait(
@@ -248,10 +289,10 @@ macro_rules! tuple_trait_impl(
($($name:ident $ty: ident),+) => (
impl<
Input: Clone, $($ty),+ , Error: ParseError<Input>,
- $($name: Fn(Input) -> IResult<Input, $ty, Error>),+
+ $($name: Parser<Input, $ty, Error>),+
> Tuple<Input, ( $($ty),+ ), Error> for ( $($name),+ ) {
- fn parse(&self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
+ fn parse(&mut self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
tuple_trait_inner!(0, self, input, (), $($name)+)
}
@@ -261,17 +302,17 @@ macro_rules! tuple_trait_impl(
macro_rules! tuple_trait_inner(
($it:tt, $self:expr, $input:expr, (), $head:ident $($id:ident)+) => ({
- let (i, o) = $self.$it($input.clone())?;
+ let (i, o) = $self.$it.parse($input.clone())?;
succ!($it, tuple_trait_inner!($self, i, ( o ), $($id)+))
});
($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident $($id:ident)+) => ({
- let (i, o) = $self.$it($input.clone())?;
+ let (i, o) = $self.$it.parse($input.clone())?;
succ!($it, tuple_trait_inner!($self, i, ($($parsed)* , o), $($id)+))
});
($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident) => ({
- let (i, o) = $self.$it($input.clone())?;
+ let (i, o) = $self.$it.parse($input.clone())?;
Ok((i, ($($parsed)* , o)))
});
@@ -280,21 +321,21 @@ macro_rules! tuple_trait_inner(
tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ J, FnK K, FnL L,
FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U);
-/// applies a tuple of parsers one by one and returns their results as a tuple
+///Applies a tuple of parsers one by one and returns their results as a tuple.
///
/// ```rust
/// # use nom::{Err, error::ErrorKind};
/// use nom::sequence::tuple;
/// use nom::character::complete::{alpha1, digit1};
-/// let parser = tuple((alpha1, digit1, alpha1));
+/// let mut parser = tuple((alpha1, digit1, alpha1));
///
/// assert_eq!(parser("abc123def"), Ok(("", ("abc", "123", "def"))));
/// assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
/// ```
-pub fn tuple<I: Clone, O, E: ParseError<I>, List: Tuple<I,O,E>>(l: List) -> impl Fn(I) -> IResult<I, O, E> {
- move |i: I| {
- l.parse(i)
- }
+pub fn tuple<I, O, E: ParseError<I>, List: Tuple<I, O, E>>(
+ mut l: List,
+) -> impl FnMut(I) -> IResult<I, O, E> {
+ move |i: I| l.parse(i)
}
#[cfg(test)]
@@ -303,11 +344,14 @@ mod tests {
#[test]
fn single_element_tuples() {
- use crate::character::complete::{alpha1, digit1};
- use crate::{Err, error::ErrorKind};
+ use crate::character::complete::alpha1;
+ use crate::{error::ErrorKind, Err};
- let parser = tuple((alpha1,));
+ let mut parser = tuple((alpha1,));
assert_eq!(parser("abc123def"), Ok(("123def", ("abc",))));
- assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
+ assert_eq!(
+ parser("123def"),
+ Err(Err::Error(("123def", ErrorKind::Alpha)))
+ );
}
}