pub trait Parser<Input: Stream> {
type Output;
type PartialState: Default;
Show 27 methods
fn parse(
&mut self,
input: Input
) -> Result<(Self::Output, Input), <Input as StreamOnce>::Error> { ... }
fn parse_with_state(
&mut self,
input: &mut Input,
state: &mut Self::PartialState
) -> Result<Self::Output, <Input as StreamOnce>::Error> { ... }
fn parse_stream(
&mut self,
input: &mut Input
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> { ... }
fn parse_lazy(
&mut self,
input: &mut Input
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> { ... }
fn add_error(&mut self, _error: &mut Tracked<<Input as StreamOnce>::Error>) { ... }
fn parse_stream_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> { ... }
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{ ... }
fn with<P2>(self, p: P2) -> With<Self, P2>
where
Self: Sized,
P2: Parser<Input>,
{ ... }
fn skip<P2>(self, p: P2) -> Skip<Self, P2>
where
Self: Sized,
P2: Parser<Input>,
{ ... }
fn and<P2>(self, p: P2) -> (Self, P2)
where
Self: Sized,
P2: Parser<Input>,
{ ... }
fn or<P2>(self, p: P2) -> Or<Self, P2>
where
Self: Sized,
P2: Parser<Input, Output = Self::Output>,
{ ... }
fn then<N, F>(self, f: F) -> Then<Self, F>
where
Self: Sized,
F: FnMut(Self::Output) -> N,
N: Parser<Input>,
{ ... }
fn then_partial<N, F>(self, f: F) -> ThenPartial<Self, F>
where
Self: Sized,
F: FnMut(&mut Self::Output) -> N,
N: Parser<Input>,
{ ... }
fn then_ref<N, F>(self, f: F) -> ThenRef<Self, F>
where
Self: Sized,
F: FnMut(&Self::Output) -> N,
N: Parser<Input>,
{ ... }
fn map<F, B>(self, f: F) -> Map<Self, F>
where
Self: Sized,
F: FnMut(Self::Output) -> B,
{ ... }
fn map_input<F, B>(self, f: F) -> MapInput<Self, F>
where
Self: Sized,
F: FnMut(Self::Output, &mut Input) -> B,
{ ... }
fn flat_map<F, B>(self, f: F) -> FlatMap<Self, F>
where
Self: Sized,
F: FnMut(Self::Output) -> Result<B, <Input as StreamOnce>::Error>,
{ ... }
fn message<S>(self, msg: S) -> Message<Self, S>
where
Self: Sized,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{ ... }
fn expected<S>(self, msg: S) -> Expected<Self, S>
where
Self: Sized,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{ ... }
fn silent(self) -> Silent<Self>
where
Self: Sized,
{ ... }
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>,
{ ... }
fn iter(
self,
input: &mut Input
) -> Iter<'_, Input, Self, Self::PartialState, FirstMode>ⓘNotable traits for Iter<'a, Input, P, S, M>impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> where
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
where
Self: Parser<Input> + Sized,
{ ... }
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>ⓘNotable traits for Iter<'a, Input, P, S, M>impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> where
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
where
Self: Parser<Input> + Sized,
M: ParseMode,
{ ... }
fn boxed<'a>(
self
) -> Box<dyn Parser<Input, Output = Self::Output, PartialState = Self::PartialState> + 'a>ⓘNotable traits for Box<R, Global>impl<R> Read for Box<R, Global> where
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;
where
Self: Sized + 'a,
{ ... }
fn left<R>(self) -> Either<Self, R>
where
Self: Sized,
R: Parser<Input, Output = Self::Output>,
{ ... }
fn right<L>(self) -> Either<L, Self>
where
Self: Sized,
L: Parser<Input, Output = Self::Output>,
{ ... }
fn spanned(self) -> Spanned<Self>
where
Self: Sized,
{ ... }
}
Expand description
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.
Associated Types
type PartialState: Default
type PartialState: Default
Determines the state necessary to resume parsing after more input is supplied.
If partial parsing is not supported this can be set to ()
.
Provided methods
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.
fn parse_with_state(
&mut self,
input: &mut Input,
state: &mut Self::PartialState
) -> Result<Self::Output, <Input as StreamOnce>::Error>
fn parse_with_state(
&mut self,
input: &mut Input,
state: &mut Self::PartialState
) -> Result<Self::Output, <Input as StreamOnce>::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_stream(
&mut self,
input: &mut Input
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
fn parse_stream(
&mut self,
input: &mut Input
) -> ParseResult<Self::Output, <Input as StreamOnce>::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
.
fn parse_lazy(
&mut self,
input: &mut Input
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
fn parse_lazy(
&mut self,
input: &mut Input
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
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.
fn add_error(&mut self, _error: &mut Tracked<<Input as StreamOnce>::Error>)
fn add_error(&mut self, _error: &mut Tracked<<Input as StreamOnce>::Error>)
Adds the first error that would normally be returned by this parser if it failed with an
PeekErr
result.
See parse_lazy
for details.
fn parse_stream_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
fn parse_stream_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
Like parse_stream
but supports partial parsing.
Borrows a parser instead of consuming it.
Used to apply parser combinators on self
without losing ownership.
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")))
);
}
Discards the value of the self
parser and returns the value of p
.
Fails if any of the parsers fails.
let result = digit()
.with(token('i'))
.parse("9i")
.map(|x| x.0);
assert_eq!(result, Ok('i'));
Discards the value of the p
parser and returns the value of self
.
Fails if any of the parsers fails.
let result = digit()
.skip(token('i'))
.parse("9i")
.map(|x| x.0);
assert_eq!(result, Ok('9'));
Parses with self
followed by p
.
Succeeds if both parsers succeed, otherwise fails.
Returns a tuple with both values on success.
let result = digit()
.and(token('i'))
.parse("9i")
.map(|x| x.0);
assert_eq!(result, Ok(('9', 'i')));
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.
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", "")));
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
and right
methods to merge parsers of differing types into one.
If you are using partial parsing you may want to use then_partial
instead.
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_partial<N, F>(self, f: F) -> ThenPartial<Self, F> where
Self: Sized,
F: FnMut(&mut Self::Output) -> N,
N: Parser<Input>,
fn then_partial<N, F>(self, f: F) -> ThenPartial<Self, F> where
Self: Sized,
F: FnMut(&mut Self::Output) -> N,
N: Parser<Input>,
Variant of 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
and right
methods to merge parsers of differing types into one.
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, "")));
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.
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'), "")));
Uses f
to map over the parsed value.
let result = digit()
.map(|c| c == '9')
.parse("9")
.map(|x| x.0);
assert_eq!(result, Ok(true));
fn map_input<F, B>(self, f: F) -> MapInput<Self, F> where
Self: Sized,
F: FnMut(Self::Output, &mut Input) -> B,
Uses f
to map over the output of self
. If f
returns an error the parser fails.
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")));
Parses with self
and if it fails, adds the message msg
to the error.
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())
]
}));
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
”.
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())
]
}));
Parses with self
, if it fails without consuming any input any expected errors that would
otherwise be emitted by self
are suppressed.
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()),
]
}));
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
.
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 iter(
self,
input: &mut Input
) -> Iter<'_, Input, Self, Self::PartialState, FirstMode>ⓘNotable traits for Iter<'a, Input, P, S, M>impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> where
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
where
Self: Parser<Input> + Sized,
fn iter(
self,
input: &mut Input
) -> Iter<'_, Input, Self, Self::PartialState, FirstMode>ⓘNotable traits for Iter<'a, Input, P, S, M>impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> where
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
where
Self: Parser<Input> + Sized,
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
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.
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], "")));
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>ⓘNotable traits for Iter<'a, Input, P, S, M>impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> where
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
where
Self: Parser<Input> + Sized,
M: ParseMode,
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>ⓘNotable traits for Iter<'a, Input, P, S, M>impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> where
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
where
Self: Parser<Input> + Sized,
M: ParseMode,
Input: Stream,
P: Parser<Input>,
S: BorrowMut<P::PartialState>,
M: ParseMode, type Item = P::Output;
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.
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], "")));
fn boxed<'a>(
self
) -> Box<dyn Parser<Input, Output = Self::Output, PartialState = Self::PartialState> + 'a>ⓘNotable traits for Box<R, Global>impl<R> Read for Box<R, Global> where
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;
where
Self: Sized + 'a,
fn boxed<'a>(
self
) -> Box<dyn Parser<Input, Output = Self::Output, PartialState = Self::PartialState> + 'a>ⓘNotable traits for Box<R, Global>impl<R> Read for Box<R, Global> where
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;
where
Self: Sized + 'a,
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;
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.
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'), "")));
Wraps the parser into the Either
enum which allows combinators such as then
to return
multiple different parser types (merging them to one)
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(), "")));
Wraps the parser into the Either
enum which allows combinators such as then
to return
multiple different parser types (merging them to one)
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(), "")));
Marks errors produced inside the self
parser with the span from the start of the parse to
the end of it.
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 },
);