blob: 17a88b7d52c0b5af75f9bbc73f6447970b7a5846 [file] [log] [blame]
//! A collection of both concrete parsers as well as parser combinators.
//!
//! Implements the [`Parser`] trait which is the core of `combine` and contains the submodules
//! implementing all combine parsers.
use crate::{
error::{
ErrorInfo, ParseError,
ParseResult::{self, *},
ResultExt, StreamError, Token, Tracked,
},
parser::{
combinator::{
and_then, flat_map, map, map_input, spanned, AndThen, Either, FlatMap, Map, MapInput,
Spanned,
},
error::{expected, message, silent, Expected, Message, Silent},
repeat::Iter,
sequence::{then, then_partial, then_ref, Then, ThenPartial, ThenRef},
},
stream::{Stream, StreamErrorFor, StreamOnce},
ErrorOffset,
};
use self::{
choice::{or, Or},
sequence::{skip, with, Skip, With},
};
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
/// Internal API. May break without a semver bump
#[macro_export]
#[doc(hidden)]
macro_rules! parse_mode {
($input_type: ty) => {
#[inline]
fn parse_partial(
&mut self,
input: &mut $input_type,
state: &mut Self::PartialState,
) -> $crate::error::ParseResult<Self::Output, <$input_type as $crate::StreamOnce>::Error> {
self.parse_mode($crate::parser::PartialMode::default(), input, state)
}
#[inline]
fn parse_first(
&mut self,
input: &mut $input_type,
state: &mut Self::PartialState,
) -> $crate::error::ParseResult<Self::Output, <$input_type as $crate::StreamOnce>::Error> {
self.parse_mode($crate::parser::FirstMode, input, state)
}
};
}
pub mod byte;
pub mod char;
pub mod choice;
pub mod combinator;
pub mod error;
pub mod function;
pub mod range;
#[cfg(feature = "regex")]
#[cfg_attr(docsrs, doc(cfg(feature = "regex")))]
pub mod regex;
pub mod repeat;
pub mod sequence;
pub mod token;
/// By implementing the `Parser` trait a type says that it can be used to parse an input stream
/// into the type `Output`.
///
/// All methods have a default implementation but there needs to be at least an implementation of
/// [`parse_stream`], [`parse_stream`], or [`parse_lazy`]. If the last is implemented, an
/// implementation of [`add_error`] may also be required. See the documentation for
/// [`parse_lazy`] for details.
///
/// [`parse_stream`]: trait.Parser.html#method.parse_stream
/// [`parse_stream`]: trait.Parser.html#method.parse_stream
/// [`parse_lazy`]: trait.Parser.html#method.parse_lazy
/// [`add_error`]: trait.Parser.html#method.add_error
pub trait Parser<Input: Stream> {
/// The type which is returned if the parser is successful.
type Output;
/// Determines the state necessary to resume parsing after more input is supplied.
///
/// If partial parsing is not supported this can be set to `()`.
type PartialState: Default;
/// Entry point of the parser. Takes some input and tries to parse it.
///
/// Returns the parsed result and the remaining input if the parser succeeds, or a
/// error otherwise.
///
/// This is the most straightforward entry point to a parser. Since it does not decorate the
/// input in any way you may find the error messages a hard to read. If that is the case you
/// may want to try wrapping your input with an [`easy::Stream`] or call [`easy_parse`]
/// instead.
///
/// [`easy::Stream`]: super::easy::Stream
/// [`easy_parse`]: super::parser::EasyParser::easy_parse
fn parse(
&mut self,
mut input: Input,
) -> Result<(Self::Output, Input), <Input as StreamOnce>::Error> {
match self.parse_stream(&mut input).into() {
Ok((v, _)) => Ok((v, input)),
Err(error) => Err(error.into_inner().error),
}
}
/// Entry point of the parser when using partial parsing.
/// Takes some input and tries to parse it.
///
/// Returns the parsed result and the remaining input if the parser succeeds, or a
/// error otherwise.
fn parse_with_state(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> Result<Self::Output, <Input as StreamOnce>::Error> {
match self.parse_stream_partial(input, state).into() {
Ok((v, _)) => Ok(v),
Err(error) => Err(error.into_inner().error),
}
}
/// Parses using the stream `input` by calling [`Stream::uncons`] one or more times.
///
/// Semantically equivalent to [`parse_stream`], except this method returns a flattened result
/// type, combining `Result` and [`Commit`] into a single [`ParseResult`].
///
/// [`Stream::uncons`]: super::stream::StreamOnce::uncons
/// [`parse_stream`]: Parser::parse_stream
/// [`Commit`]: super::error::Commit
/// [`ParseResult`]: super::error::ParseResult
#[inline]
fn parse_stream(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let before = input.checkpoint();
let mut state = Default::default();
let mut result = self.parse_first(input, &mut state);
if let ParseResult::PeekErr(ref mut error) = result {
ctry!(input.reset(before.clone()).committed());
if let Ok(t) = input.uncons() {
ctry!(input.reset(before).committed());
error.error.add_unexpected(Token(t));
} else {
error.error.add(StreamErrorFor::<Input>::end_of_input());
}
self.add_error(error);
}
result
}
/// Parses using the stream `input` by calling [`Stream::uncons`] one or more times.
///
/// Specialized version of [`parse_stream`] which permits error value creation to be
/// skipped in the common case.
///
/// When this parser returns `PeekErr`, this method is allowed to return an empty
/// [`Error`]. The error value that would have been returned can instead be obtained by
/// calling [`add_error`]. This allows a parent parser such as `choice` to skip the creation of
/// an unnecessary error value, if an alternative parser succeeds.
///
/// Parsers should seek to implement this function instead of the above two if errors can be
/// encountered before consuming input. The default implementation always returns all errors,
/// with [`add_error`] being a no-op.
///
/// [`Stream::uncons`]: super::stream::StreamOnce::uncons
/// [`parse_stream`]: Parser::parse_stream
/// [`Error`]: super::stream::StreamOnce::Error
/// [`add_error`]: trait.Parser.html#method.add_error
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
if input.is_partial() {
// If a partial parser were called from a non-partial parser (as it is here) we must
// reset the input to before the partial parser were called on errors that committed
// data as that parser's partial state was just temporary and it will not be able to
// resume itself
let before = input.checkpoint();
let result = self.parse_first(input, &mut Default::default());
if let CommitErr(_) = result {
ctry!(input.reset(before).committed());
}
result
} else {
self.parse_first(input, &mut Default::default())
}
}
/// Adds the first error that would normally be returned by this parser if it failed with an
/// `PeekErr` result.
///
/// See [`parse_lazy`] for details.
///
/// [`parse_lazy`]: trait.Parser.html#method.parse_lazy
fn add_error(&mut self, _error: &mut Tracked<<Input as StreamOnce>::Error>) {}
/// Like `parse_stream` but supports partial parsing.
#[inline]
fn parse_stream_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let before = input.checkpoint();
let mut result = self.parse_partial(input, state);
if let ParseResult::PeekErr(ref mut error) = result {
ctry!(input.reset(before.clone()).committed());
if let Ok(t) = input.uncons() {
ctry!(input.reset(before).committed());
error.error.add_unexpected(Token(t));
} else {
error.error.add(StreamErrorFor::<Input>::end_of_input());
}
self.add_error(error);
}
result
}
/// Parses using the stream `input` and allows itself to be resumed at a later point using
/// `parse_partial` by storing the necessary intermediate state in `state`.
///
/// Unlike `parse_partial` function this is allowed to assume that there is no partial state to
/// resume.
///
/// Internal API. May break without a semver bump
/// Always overridden by the `parse_mode!` macro
#[inline]
#[doc(hidden)]
fn parse_first(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
self.parse_partial(input, state)
}
/// Parses using the stream `input` and allows itself to be resumed at a later point using
/// `parse_partial` by storing the necessary intermediate state in `state`
///
/// Internal API. May break without a semver bump
/// Always overridden by the `parse_mode!` macro
#[inline]
#[doc(hidden)]
fn parse_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let _ = state;
self.parse_lazy(input)
}
/// Internal API. May break without a semver bump
#[doc(hidden)]
#[inline]
fn parse_mode<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
Self: Sized,
{
mode.parse(self, input, state)
}
/// Internal API. May break without a semver bump
#[doc(hidden)]
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
Self: Sized,
{
if mode.is_first() {
self.parse_first(input, state)
} else {
self.parse_partial(input, state)
}
}
/// Internal API. May break without a semver bump
#[doc(hidden)]
#[inline]
fn parse_committed_mode<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
Self: Sized,
{
if mode.is_first() {
FirstMode.parse_committed(self, input, state)
} else {
PartialMode::default().parse_committed(self, input, state)
}
}
/// Returns how many parsers this parser contains
///
/// Internal API: This should not be implemented explicitly outside of combine.
#[doc(hidden)]
fn parser_count(&self) -> ErrorOffset {
ErrorOffset(1)
}
/// Internal API: This should not be implemented explicitly outside of combine.
#[doc(hidden)]
fn add_committed_expected_error(&mut self, _error: &mut Tracked<<Input as StreamOnce>::Error>) {
}
/// Borrows a parser instead of consuming it.
///
/// Used to apply parser combinators on `self` without losing ownership.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::error::Commit;
/// # use combine::parser::char::{digit, letter};
/// fn test(input: &mut &'static str) -> StdParseResult<(char, char), &'static str> {
/// let mut p = digit();
/// let ((d, _), committed) = (p.by_ref(), letter()).parse_stream(input).into_result()?;
/// let (d2, committed) = committed.combine(|_| p.parse_stream(input).into_result())?;
/// Ok(((d, d2), committed))
/// }
///
/// fn main() {
/// let mut input = "1a23";
/// assert_eq!(
/// test(&mut input).map(|(t, c)| (t, c.map(|_| input))),
/// Ok((('1', '2'), Commit::Commit("3")))
/// );
/// }
/// ```
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
/// Discards the value of the `self` parser and returns the value of `p`.
/// Fails if any of the parsers fails.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # fn main() {
/// let result = digit()
/// .with(token('i'))
/// .parse("9i")
/// .map(|x| x.0);
/// assert_eq!(result, Ok('i'));
/// # }
/// ```
fn with<P2>(self, p: P2) -> With<Self, P2>
where
Self: Sized,
P2: Parser<Input>,
{
with(self, p)
}
/// Discards the value of the `p` parser and returns the value of `self`.
/// Fails if any of the parsers fails.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # fn main() {
/// let result = digit()
/// .skip(token('i'))
/// .parse("9i")
/// .map(|x| x.0);
/// assert_eq!(result, Ok('9'));
/// # }
/// ```
fn skip<P2>(self, p: P2) -> Skip<Self, P2>
where
Self: Sized,
P2: Parser<Input>,
{
skip(self, p)
}
/// Parses with `self` followed by `p`.
/// Succeeds if both parsers succeed, otherwise fails.
/// Returns a tuple with both values on success.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # fn main() {
/// let result = digit()
/// .and(token('i'))
/// .parse("9i")
/// .map(|x| x.0);
/// assert_eq!(result, Ok(('9', 'i')));
/// # }
/// ```
fn and<P2>(self, p: P2) -> (Self, P2)
where
Self: Sized,
P2: Parser<Input>,
{
(self, p)
}
/// Returns a parser which attempts to parse using `self`. If `self` fails without committing
/// it tries to consume the same input using `p`.
///
/// If you are looking to chain 3 or more parsers using `or` you may consider using the
/// [`choice!`] macro instead, which can be clearer and may result in a faster parser.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{digit, string};
/// # fn main() {
/// let mut parser = string("let")
/// .or(digit().map(|_| "digit"))
/// .or(string("led"));
/// assert_eq!(parser.parse("let"), Ok(("let", "")));
/// assert_eq!(parser.parse("1"), Ok(("digit", "")));
/// assert!(parser.parse("led").is_err());
///
/// let mut parser2 = string("two").or(string("three"));
/// // Fails as the parser for "two" consumes the first 't' before failing
/// assert!(parser2.parse("three").is_err());
///
/// // Use 'attempt' to make failing parsers always act as if they have not committed any input
/// let mut parser3 = attempt(string("two")).or(attempt(string("three")));
/// assert_eq!(parser3.parse("three"), Ok(("three", "")));
/// # }
/// ```
///
/// [`choice!`]: super::choice!
fn or<P2>(self, p: P2) -> Or<Self, P2>
where
Self: Sized,
P2: Parser<Input, Output = Self::Output>,
{
or(self, p)
}
/// Parses using `self` and then passes the value to `f` which returns a parser used to parse
/// the rest of the input.
///
/// Since the parser returned from `f` must have a single type it can be useful to use the
/// [`left`](Parser::left) and [`right`](Parser::right) methods to merge parsers of differing types into one.
///
/// If you are using partial parsing you may want to use [`then_partial`](Parser::then_partial) instead.
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # use combine::error::Commit;
/// # use combine::stream::easy;
/// # fn main() {
/// let result = digit()
/// .then(|d| {
/// if d == '9' {
/// value(9).left()
/// }
/// else {
/// unexpected_any(d).message("Not a nine").right()
/// }
/// })
/// .easy_parse("9");
/// assert_eq!(result, Ok((9, "")));
/// # }
/// ```
fn then<N, F>(self, f: F) -> Then<Self, F>
where
Self: Sized,
F: FnMut(Self::Output) -> N,
N: Parser<Input>,
{
then(self, f)
}
/// Variant of [`then`](Parser::then) which parses using `self` and then passes the value to `f` as a `&mut` reference.
///
/// Useful when doing partial parsing since it does not need to store the parser returned by
/// `f` in the partial state. Instead it will call `f` each to request a new parser each time
/// parsing resumes and that parser is needed.
///
/// Since the parser returned from `f` must have a single type it can be useful to use the
/// [`left`](Parser::left) and [`right`](Parser::right) methods to merge parsers of differing types into one.
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # use combine::error::Commit;
/// # use combine::stream::easy;
/// # fn main() {
/// let result = digit()
/// .then_partial(|d| {
/// if *d == '9' {
/// value(9).left()
/// }
/// else {
/// unexpected_any(*d).message("Not a nine").right()
/// }
/// })
/// .easy_parse("9");
/// assert_eq!(result, Ok((9, "")));
/// # }
/// ```
fn then_partial<N, F>(self, f: F) -> ThenPartial<Self, F>
where
Self: Sized,
F: FnMut(&mut Self::Output) -> N,
N: Parser<Input>,
{
then_partial(self, f)
}
/// Parses using `self` and then passes a reference to the value to `f` which returns a parser
/// used to parse the rest of the input. The value is then combined with the output of `f`.
///
/// Since the parser returned from `f` must have a single type it can be useful to use the
/// `left` and `right` methods to merge parsers of differing types into one.
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # use combine::error::Commit;
/// # use combine::stream::easy;
/// # fn main() {
/// let result = digit()
/// .then_ref(|d| {
/// if *d == '9' {
/// digit().left()
/// }
/// else {
/// unexpected_any(*d).message("Not a nine").right()
/// }
/// })
/// .easy_parse("98");
/// assert_eq!(result, Ok((('9', '8'), "")));
/// # }
/// ```
fn then_ref<N, F>(self, f: F) -> ThenRef<Self, F>
where
Self: Sized,
F: FnMut(&Self::Output) -> N,
N: Parser<Input>,
{
then_ref(self, f)
}
/// Uses `f` to map over the parsed value.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # fn main() {
/// let result = digit()
/// .map(|c| c == '9')
/// .parse("9")
/// .map(|x| x.0);
/// assert_eq!(result, Ok(true));
/// # }
/// ```
fn map<F, B>(self, f: F) -> Map<Self, F>
where
Self: Sized,
F: FnMut(Self::Output) -> B,
{
map(self, f)
}
fn map_input<F, B>(self, f: F) -> MapInput<Self, F>
where
Self: Sized,
F: FnMut(Self::Output, &mut Input) -> B,
{
map_input(self, f)
}
/// Uses `f` to map over the output of `self`. If `f` returns an error the parser fails.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # use combine::parser::range::take;
/// # fn main() {
/// let result = take(4)
/// .flat_map(|bs| many(digit()).parse(bs).map(|t| t.0))
/// .parse("12abcd");
/// assert_eq!(result, Ok((String::from("12"), "cd")));
/// # }
/// ```
fn flat_map<F, B>(self, f: F) -> FlatMap<Self, F>
where
Self: Sized,
F: FnMut(Self::Output) -> Result<B, <Input as StreamOnce>::Error>,
{
flat_map(self, f)
}
/// Parses with `self` and if it fails, adds the message `msg` to the error.
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::easy;
/// # use combine::stream::position::{self, SourcePosition};
/// # fn main() {
/// let result = token('9')
/// .message("Not a nine")
/// .easy_parse(position::Stream::new("8"));
/// assert_eq!(result, Err(easy::Errors {
/// position: SourcePosition::default(),
/// errors: vec![
/// easy::Error::Unexpected('8'.into()),
/// easy::Error::Expected('9'.into()),
/// easy::Error::Message("Not a nine".into())
/// ]
/// }));
/// # }
/// ```
fn message<S>(self, msg: S) -> Message<Self, S>
where
Self: Sized,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
message(self, msg)
}
/// Parses with `self` and if it fails without consuming any input any expected errors are
/// replaced by `msg`. `msg` is then used in error messages as "Expected `msg`".
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::error;
/// # use combine::stream::easy;
/// # use combine::stream::position::{self, SourcePosition};
/// # fn main() {
/// let result = token('9')
/// .expected("nine")
/// .easy_parse(position::Stream::new("8"));
/// assert_eq!(result, Err(easy::Errors {
/// position: SourcePosition::default(),
/// errors: vec![
/// easy::Error::Unexpected('8'.into()),
/// easy::Error::Expected("nine".into())
/// ]
/// }));
///
/// let result = token('9')
/// .expected(error::Format(format_args!("That is not a nine!")))
/// .easy_parse(position::Stream::new("8"));
/// assert_eq!(result, Err(easy::Errors {
/// position: SourcePosition::default(),
/// errors: vec![
/// easy::Error::Unexpected('8'.into()),
/// easy::Error::Expected("That is not a nine!".to_string().into())
/// ]
/// }));
/// # }
/// ```
fn expected<S>(self, msg: S) -> Expected<Self, S>
where
Self: Sized,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
expected(self, msg)
}
/// Parses with `self`, if it fails without consuming any input any expected errors that would
/// otherwise be emitted by `self` are suppressed.
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::easy;
/// # use combine::stream::position::{self, SourcePosition};
/// # fn main() {
/// let result = token('9')
/// .expected("nine")
/// .silent()
/// .easy_parse(position::Stream::new("8"));
/// assert_eq!(result, Err(easy::Errors {
/// position: SourcePosition::default(),
/// errors: vec![
/// easy::Error::Unexpected('8'.into()),
/// ]
/// }));
/// # }
/// ```
fn silent(self) -> Silent<Self>
where
Self: Sized,
{
silent(self)
}
/// Parses with `self` and applies `f` on the result if `self` parses successfully.
/// `f` may optionally fail with an error which is automatically converted to a `ParseError`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::position::{self, SourcePosition};
/// # use combine::parser::char::digit;
/// # fn main() {
/// let mut parser = many1(digit())
/// .and_then(|s: String| s.parse::<i32>());
/// let result = parser.easy_parse(position::Stream::new("1234")).map(|(x, state)| (x, state.input));
/// assert_eq!(result, Ok((1234, "")));
/// let result = parser.easy_parse(position::Stream::new("999999999999999999999999"));
/// assert!(result.is_err());
/// // Errors are report as if they occurred at the start of the parse
/// assert_eq!(result.unwrap_err().position, SourcePosition { line: 1, column: 1 });
/// # }
/// ```
fn and_then<F, O, E>(self, f: F) -> AndThen<Self, F>
where
Self: Parser<Input> + Sized,
F: FnMut(Self::Output) -> Result<O, E>,
E: Into<
<Input::Error as ParseError<Input::Token, Input::Range, Input::Position>>::StreamError,
>,
{
and_then(self, f)
}
/// Creates an iterator from a parser and a state. Can be used as an alternative to [`many`]
/// when collecting directly into a `Extend` type is not desirable.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{char, digit};
/// # fn main() {
/// let mut buffer = String::new();
/// let number = parser(|input| {
/// buffer.clear();
/// let mut iter = digit().iter(input);
/// buffer.extend(&mut iter);
/// let i = buffer.parse::<i32>().unwrap();
/// iter.into_result(i)
/// });
/// let result = sep_by(number, char(','))
/// .parse("123,45,6");
/// assert_eq!(result, Ok((vec![123, 45, 6], "")));
/// # }
/// ```
///
/// [`many`]: repeat::many
fn iter(self, input: &mut Input) -> Iter<'_, Input, Self, Self::PartialState, FirstMode>
where
Self: Parser<Input> + Sized,
{
Iter::new(self, FirstMode, input, Default::default())
}
/// Creates an iterator from a parser and a state. Can be used as an alternative to [`many`]
/// when collecting directly into a `Extend` type is not desirable.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{char, digit};
/// # fn main() {
/// let mut buffer = String::new();
/// let number = parser(|input| {
/// buffer.clear();
/// let mut iter = digit().iter(input);
/// buffer.extend(&mut iter);
/// let i = buffer.parse::<i32>().unwrap();
/// iter.into_result(i)
/// });
/// let result = sep_by(number, char(','))
/// .parse("123,45,6");
/// assert_eq!(result, Ok((vec![123, 45, 6], "")));
/// # }
/// ```
///
/// [`many`]: repeat::many
fn partial_iter<'a, 's, M>(
self,
mode: M,
input: &'a mut Input,
partial_state: &'s mut Self::PartialState,
) -> Iter<'a, Input, Self, &'s mut Self::PartialState, M>
where
Self: Parser<Input> + Sized,
M: ParseMode,
{
Iter::new(self, mode, input, partial_state)
}
/// Turns the parser into a trait object by putting it in a `Box`. Can be used to easily
/// return parsers from functions without naming the type.
///
/// ```
/// # use combine::*;
/// # fn main() {
/// fn test<'input, F>(
/// c: char,
/// f: F)
/// -> Box<dyn Parser<&'input str, Output = (char, char), PartialState = ()> + 'input>
/// where F: FnMut(char) -> bool + 'static
/// {
/// combine::parser::combinator::no_partial((token(c), satisfy(f))).boxed()
/// }
/// let result = test('a', |c| c >= 'a' && c <= 'f')
/// .parse("ac");
/// assert_eq!(result, Ok((('a', 'c'), "")));
/// # }
/// ```
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
fn boxed<'a>(
self,
) -> Box<dyn Parser<Input, Output = Self::Output, PartialState = Self::PartialState> + 'a>
where
Self: Sized + 'a,
{
Box::new(self)
}
/// Wraps the parser into the [`Either`](combinator::Either) enum which allows combinators such as [`then`](Parser::then) to return
/// multiple different parser types (merging them to one)
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{digit, letter};
/// # fn main() {
/// let mut parser = any().then(|c|
/// if c == '#' {
/// skip_many(satisfy(|c| c != '\n'))
/// .with(value("".to_string()))
/// .left()
/// } else {
/// many1(letter())
/// .map(move |mut s: String| { s.insert(0, c); s })
/// .right()
/// });
///
/// let result = parser.parse("ac2");
/// assert_eq!(result, Ok(("ac".to_string(), "2")));
///
/// let result = parser.parse("# ac2");
/// assert_eq!(result, Ok(("".to_string(), "")));
/// # }
/// ```
fn left<R>(self) -> Either<Self, R>
where
Self: Sized,
R: Parser<Input, Output = Self::Output>,
{
Either::Left(self)
}
/// Wraps the parser into the [`Either`](combinator::Either) enum which allows combinators such as [`then`](Parser::then) to return
/// multiple different parser types (merging them to one)
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{digit, letter};
/// # fn main() {
/// let mut parser = any().then(|c|
/// if c == '#' {
/// skip_many(satisfy(|c| c != '\n'))
/// .with(value("".to_string()))
/// .left()
/// } else {
/// many1(letter())
/// .map(move |mut s: String| { s.insert(0, c); s })
/// .right()
/// });
///
/// let result = parser.parse("ac2");
/// assert_eq!(result, Ok(("ac".to_string(), "2")));
///
/// let result = parser.parse("# ac2");
/// assert_eq!(result, Ok(("".to_string(), "")));
/// # }
/// ```
fn right<L>(self) -> Either<L, Self>
where
Self: Sized,
L: Parser<Input, Output = Self::Output>,
{
Either::Right(self)
}
/// Marks errors produced inside the `self` parser with the span from the start of the parse to
/// the end of it.
///
/// [`p.spanned()`]: ../trait.Parser.html#method.spanned
///
/// ```
/// use combine::{*, parser::{char::string, combinator::spanned}};
/// use combine::stream::{easy, span};
///
/// let input = "hel";
/// let result = spanned(string("hello")).parse(
/// span::Stream::<_, easy::Errors<_, _, span::Span<_>>>::from(easy::Stream::from(input)),
/// );
/// assert!(result.is_err());
/// assert_eq!(
/// result.unwrap_err().position.map(|p| p.translate_position(input)),
/// span::Span { start: 0, end: 3 },
/// );
/// ```
fn spanned(self) -> Spanned<Self>
where
Self: Sized,
{
spanned(self)
}
}
/// Provides the `easy_parse` method which provides good error messages by default
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub trait EasyParser<Input: Stream>: Parser<crate::easy::Stream<Input>>
where
Input::Token: PartialEq,
Input::Range: PartialEq,
{
/// Entry point of the parser. Takes some input and tries to parse it, returning an easy to use
/// and format error if parsing did not succeed.
///
/// Returns the parsed result and the remaining input if the parser succeeds, or a
/// This function wraps requires `Input == easy::Stream<Input>` which makes it return
/// return `easy::Errors` if an error occurs. Due to this wrapping it is recommended that the
/// parser `Self` is written with a generic input type.
///
/// ```
/// # #[macro_use]
/// # extern crate combine;
///
/// use combine::*;
/// use combine::parser::repeat::many1;
/// use combine::parser::char::letter;
///
/// // Good!
/// parser!{
/// fn my_parser[Input]()(Input) -> String
/// where [Input: Stream<Token = char>]
/// {
/// many1::<String, _, _>(letter())
/// }
/// }
///
/// // Won't compile with `easy_parse` since it is specialized on `&str`
/// parser!{
/// fn my_parser2['a]()(&'a str) -> String
/// where [&'a str: Stream<Token = char, Range = &'a str>]
/// {
/// many1(letter())
/// }
/// }
///
/// fn main() {
/// assert_eq!(my_parser().parse("abc"), Ok(("abc".to_string(), "")));
/// // Would fail to compile if uncommented
/// // my_parser2().parse("abc")
/// }
/// ```
///
/// [`ParseError`]: struct.ParseError.html
fn easy_parse(
&mut self,
input: Input,
) -> Result<
(<Self as Parser<crate::easy::Stream<Input>>>::Output, Input),
crate::easy::ParseError<Input>,
>
where
Input: Stream,
crate::easy::Stream<Input>: StreamOnce<
Token = Input::Token,
Range = Input::Range,
Error = crate::easy::ParseError<crate::easy::Stream<Input>>,
Position = Input::Position,
>,
Input::Position: Default,
Self: Sized + Parser<crate::easy::Stream<Input>>,
{
let input = crate::easy::Stream(input);
self.parse(input).map(|(v, input)| (v, input.0))
}
}
#[cfg(feature = "std")]
impl<Input, P> EasyParser<Input> for P
where
P: ?Sized + Parser<crate::easy::Stream<Input>>,
Input: Stream,
Input::Token: PartialEq,
Input::Range: PartialEq,
{
}
macro_rules! forward_deref {
(Input) => {
type Output = P::Output;
type PartialState = P::PartialState;
#[inline]
fn parse_first(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
(**self).parse_first(input, state)
}
#[inline]
fn parse_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
(**self).parse_partial(input, state)
}
#[inline]
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
(**self).add_error(error)
}
#[inline]
fn add_committed_expected_error(
&mut self,
error: &mut Tracked<<Input as StreamOnce>::Error>,
) {
(**self).add_committed_expected_error(error)
}
#[inline]
fn parser_count(&self) -> ErrorOffset {
(**self).parser_count()
}
};
}
impl<'a, P, Input> Parser<Input> for &'a mut P
where
P: ?Sized + Parser<Input>,
Input: Stream,
{
forward_deref!(Input);
}
#[cfg(feature = "alloc")]
impl<P, Input> Parser<Input> for Box<P>
where
P: ?Sized + Parser<Input>,
Input: Stream,
{
forward_deref!(Input);
}
/// Internal API. May break without a semver bump
#[doc(hidden)]
/// Specifies whether the parser must check for partial state that must be resumed
pub trait ParseMode: Copy {
/// If `true` then the parser has no previous state to resume otherwise the parser *might* have
/// state to resume which it must check.
fn is_first(self) -> bool;
/// Puts the mode into `first` parsing.
fn set_first(&mut self);
fn parse<P, Input>(
self,
parser: &mut P,
input: &mut Input,
state: &mut P::PartialState,
) -> ParseResult<P::Output, Input::Error>
where
P: Parser<Input>,
Input: Stream;
#[inline]
fn parse_committed<P, Input>(
self,
parser: &mut P,
input: &mut Input,
state: &mut P::PartialState,
) -> ParseResult<P::Output, <Input as StreamOnce>::Error>
where
P: Parser<Input>,
Input: Stream,
{
let before = input.checkpoint();
let mut result = parser.parse_mode_impl(self, input, state);
if let ParseResult::PeekErr(ref mut error) = result {
ctry!(input.reset(before.clone()).committed());
if let Ok(t) = input.uncons() {
ctry!(input.reset(before).committed());
error.error.add_unexpected(Token(t));
} else {
error.error.add(StreamErrorFor::<Input>::end_of_input());
}
parser.add_error(error);
}
result
}
}
/// Internal API. May break without a semver bump
#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct FirstMode;
impl ParseMode for FirstMode {
#[inline]
fn is_first(self) -> bool {
true
}
#[inline]
fn set_first(&mut self) {}
fn parse<P, Input>(
self,
parser: &mut P,
input: &mut Input,
state: &mut P::PartialState,
) -> ParseResult<P::Output, Input::Error>
where
P: Parser<Input>,
Input: Stream,
{
parser.parse_mode_impl(FirstMode, input, state)
}
}
/// Internal API. May break without a semver bump
#[doc(hidden)]
#[derive(Copy, Clone, Default)]
pub struct PartialMode {
pub first: bool,
}
impl ParseMode for PartialMode {
#[inline]
fn is_first(self) -> bool {
self.first
}
#[inline]
fn set_first(&mut self) {
self.first = true;
}
fn parse<P, Input>(
self,
parser: &mut P,
input: &mut Input,
state: &mut P::PartialState,
) -> ParseResult<P::Output, Input::Error>
where
P: Parser<Input>,
Input: Stream,
{
if self.is_first() {
parser.parse_mode_impl(FirstMode, input, state)
} else {
parser.parse_mode_impl(self, input, state)
}
}
}