Trait combine::Parser
[−]
[src]
pub trait Parser { type Input: Stream; type Output; fn parse(&mut self,
input: Self::Input)
-> Result<(Self::Output, Self::Input), ParseError<Self::Input>> { ... } fn parse_stream(&mut self,
input: Self::Input)
-> ParseResult<Self::Output, Self::Input> { ... } fn parse_stream_consumed(&mut self,
input: Self::Input)
-> ConsumedResult<Self::Output, Self::Input> { ... } fn parse_lazy(&mut self,
input: Self::Input)
-> ConsumedResult<Self::Output, Self::Input> { ... } fn add_error(&mut self, _error: &mut ParseError<Self::Input>) { ... } 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=Self::Input> { ... } fn skip<P2>(self, p: P2) -> Skip<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input> { ... } fn and<P2>(self, p: P2) -> (Self, P2) where Self: Sized, P2: Parser<Input=Self::Input> { ... } fn or<P2>(self, p: P2) -> Or<Self, P2> where Self: Sized, P2: Parser<Input=Self::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=Self::Input> { ... } fn map<F, B>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(Self::Output) -> B { ... } fn flat_map<F, B>(self, f: F) -> FlatMap<Self, F> where Self: Sized,
F: FnMut(Self::Output) -> Result<B, ParseError<Self::Input>> { ... } fn message<S>(self, msg: S) -> Message<Self> where Self: Sized, S: Into<Info<Self::Input::Item, Self::Input::Range>> { ... } fn expected<S>(self, msg: S) -> Expected<Self> where Self: Sized, S: Into<Info<Self::Input::Item, Self::Input::Range>> { ... } fn and_then<F, O, E>(self, f: F) -> AndThen<Self, F> where Self: Sized,
F: FnMut(Self::Output) -> Result<O, E>,
E: Into<Error<Self::Input::Item, Self::Input::Range>> { ... } fn iter(self, input: Self::Input) -> Iter<Self> where Self: Sized { ... } fn boxed<'a>(self)
-> Box<Parser<Input=Self::Input, Output=Self::Output> + 'a> where Self: Sized + 'a { ... } }
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
orparse_lazy
. If parse_lazy
is implemented an implementation of add_error
is
also recommended to improve error reporting.
Associated Types
type Input: Stream
The type which is take as input for the parser. The type must implement the Stream
trait
which allows the parser to read item from the type.
type Output
The type which is returned if the parser is successful.
Provided Methods
fn parse(&mut self,
input: Self::Input)
-> Result<(Self::Output, Self::Input), ParseError<Self::Input>>
input: Self::Input)
-> Result<(Self::Output, Self::Input), ParseError<Self::Input>>
Entrypoint of the parser
Takes some input and tries to parse it returning a ParseResult
fn parse_stream(&mut self,
input: Self::Input)
-> ParseResult<Self::Output, Self::Input>
input: Self::Input)
-> ParseResult<Self::Output, Self::Input>
Parses using the stream input
by calling Stream::uncons one or more times
On success returns Ok((value, new_state))
on failure it returns Err(error)
fn parse_stream_consumed(&mut self,
input: Self::Input)
-> ConsumedResult<Self::Output, Self::Input>
input: Self::Input)
-> ConsumedResult<Self::Output, Self::Input>
Parses using the stream input
by calling Stream::uncons one or more times
On success returns Ok((value, new_state))
on failure it returns Err(error)
fn parse_lazy(&mut self,
input: Self::Input)
-> ConsumedResult<Self::Output, Self::Input>
input: Self::Input)
-> ConsumedResult<Self::Output, Self::Input>
Specialized version of parse_stream where the parser does not need to add an error to the
ParseError
when it does not consume any input before encountering the error.
Instead the error can be added later through the add_error
method
fn add_error(&mut self, _error: &mut ParseError<Self::Input>)
Adds the first error that would normally be returned by this parser if it failed
fn by_ref(&mut self) -> &mut Self where Self: Sized
Borrows a parser instead of consuming it.
Used to apply parser combinators on self
without losing ownership.
fn test() -> ParseResult<(char, char), &'static str> { let mut p = digit(); let ((d, _), input) = try!((p.by_ref(), letter()).parse_stream("1a23")); let (d2, input) = try!(input.combine(|input| p.parse_stream(input))); Ok(((d, d2), input)) } fn main() { assert_eq!(test(), Ok((('1', '2'), Consumed::Consumed("3")))); }
fn with<P2>(self, p: P2) -> With<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input>
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'));
fn skip<P2>(self, p: P2) -> Skip<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input>
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'));
fn and<P2>(self, p: P2) -> (Self, P2) where Self: Sized, P2: Parser<Input=Self::Input>
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')));
fn or<P2>(self, p: P2) -> Or<Self, P2> where Self: Sized, P2: Parser<Input=Self::Input, Output=Self::Output>
Returns a parser which attempts to parse using self
. If self
fails without consuming any
input it tries to consume the same input using p
.
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 'try' to make failing parsers always act as if they have not consumed any input let mut parser3 = try(string("two")).or(try(string("three"))); assert_eq!(parser3.parse("three"), Ok(("three", "")));
fn then<N, F>(self, f: F) -> Then<Self, F> where Self: Sized, F: FnMut(Self::Output) -> N, N: Parser<Input=Self::Input>
Parses using self
and then passes the value to f
which returns a parser used to parse
the rest of the input
let result = digit() .then(|d| parser(move |input| { // Force input to be a &str let _: &str = input; if d == '9' { Ok((9, Consumed::Empty(input))) } else { let position = input.position(); let err = ParseError::new(position, Error::Message("Not a nine".into())); Err((Consumed::Empty(err))) } })) .parse("9"); assert_eq!(result, Ok((9, "")));
fn map<F, B>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(Self::Output) -> B
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 flat_map<F, B>(self, f: F) -> FlatMap<Self, F> where Self: Sized,
F: FnMut(Self::Output) -> Result<B, ParseError<Self::Input>>
F: FnMut(Self::Output) -> Result<B, ParseError<Self::Input>>
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")));
fn message<S>(self, msg: S) -> Message<Self> where Self: Sized, S: Into<Info<Self::Input::Item, Self::Input::Range>>
Parses with self
and if it fails, adds the message msg
to the error
let result = token('9') .message("Not a nine") .parse(State::new("8")); assert_eq!(result, Err(ParseError { position: <char as Positioner>::start(), errors: vec![ Error::Unexpected('8'.into()), Error::Expected('9'.into()), Error::Message("Not a nine".into()) ] }));
fn expected<S>(self, msg: S) -> Expected<Self> where Self: Sized, S: Into<Info<Self::Input::Item, Self::Input::Range>>
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") .parse(State::new("8")); assert_eq!(result, Err(ParseError { position: <char as Positioner>::start(), errors: vec![Error::Unexpected('8'.into()), Error::Expected("nine".into())] }));
fn and_then<F, O, E>(self, f: F) -> AndThen<Self, F> where Self: Sized,
F: FnMut(Self::Output) -> Result<O, E>,
E: Into<Error<Self::Input::Item, Self::Input::Range>>
F: FnMut(Self::Output) -> Result<O, E>,
E: Into<Error<Self::Input::Item, Self::Input::Range>>
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.parse("1234"); assert_eq!(result, Ok((1234, ""))); let err = parser.parse("abc"); assert!(err.is_err());
fn iter(self, input: Self::Input) -> Iter<Self> where Self: Sized
Creates an iterator from a parser and a state. Can be used as an alternative to many
when
collecting directly into a FromIterator
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<Parser<Input=Self::Input, Output=Self::Output> + 'a> where Self: Sized + 'a
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<Parser<Input = &'input str, Output = (char, char)>> where F: FnMut(char) -> bool + 'static { (token(c), satisfy(f)).boxed() } let result = test('a', |c| c >= 'a' && c <= 'f') .parse("ac"); assert_eq!(result, Ok((('a', 'c'), "")));
Implementors
impl<'a, I, O, P: ?Sized> Parser for &'a mut P where I: Stream,
P: Parser<Input=I, Output=O>impl<I, O, P: ?Sized> Parser for Box<P> where I: Stream,
P: Parser<Input=I, Output=O>impl<I> Parser for Any<I> where I: Stream
impl<I, P> Parser for Satisfy<I, P> where I: Stream, P: FnMut(I::Item) -> bool
impl<I, P, R> Parser for SatisfyMap<I, P> where I: Stream,
P: FnMut(I::Item) -> Option<R>impl<I> Parser for Token<I> where I: Stream, I::Item: PartialEq + Clone
impl<C, T, I> Parser for Tokens<C, T, I> where C: FnMut(T::Item, I::Item) -> bool,
T: Clone + IntoIterator,
I: Streamimpl<I> Parser for Position<I> where I: Stream
impl<I, O, S, P> Parser for Choice<S, P> where I: Stream,
S: AsMut<[P]>,
P: Parser<Input=I, Output=O>impl<T, I> Parser for OneOf<T, I> where T: Clone + IntoIterator<Item=I::Item>,
I: Stream,
I::Item: PartialEqimpl<T, I> Parser for NoneOf<T, I> where T: Clone + IntoIterator<Item=I::Item>,
I: Stream,
I::Item: PartialEqimpl<P, F> Parser for Count<F, P> where P: Parser, F: FromIterator<P::Output>
impl<I> Parser for Unexpected<I> where I: Stream
impl<I, T> Parser for Value<I, T> where I: Stream, T: Clone
impl<P> Parser for NotFollowedBy<P> where P: Parser
impl<I> Parser for Eof<I> where I: Stream
impl<F, P> Parser for Many<F, P> where P: Parser, F: FromIterator<P::Output>
impl<F, P> Parser for Many1<F, P> where F: FromIterator<P::Output>, P: Parser
impl<P> Parser for SkipMany<P> where P: Parser
impl<P> Parser for SkipMany1<P> where P: Parser
impl<F, P, S> Parser for SepBy<F, P, S> where F: FromIterator<P::Output>,
P: Parser,
S: Parser<Input=P::Input>impl<F, P, S> Parser for SepBy1<F, P, S> where F: FromIterator<P::Output>,
P: Parser,
S: Parser<Input=P::Input>impl<F, P, S> Parser for SepEndBy<F, P, S> where F: FromIterator<P::Output>,
P: Parser,
S: Parser<Input=P::Input>impl<F, P, S> Parser for SepEndBy1<F, P, S> where F: FromIterator<P::Output>,
P: Parser,
S: Parser<Input=P::Input>impl<'a, I: Stream, O> Parser for FnMut(I) -> ParseResult<O, I> + 'a
impl<I, O, F> Parser for FnParser<I, F> where I: Stream,
F: FnMut(I) -> ParseResult<O, I>impl<I, O> Parser for fn(_: I) -> ParseResult<O, I> where I: Stream
impl<P> Parser for Optional<P> where P: Parser
impl<L, R, P> Parser for Between<L, R, P> where L: Parser,
R: Parser<Input=L::Input>,
P: Parser<Input=L::Input>impl<I, P, Op> Parser for Chainl1<P, Op> where I: Stream,
P: Parser<Input=I>,
Op: Parser<Input=I>,
Op::Output: FnOnce(P::Output, P::Output) -> P::Outputimpl<I, P, Op> Parser for Chainr1<P, Op> where I: Stream,
P: Parser<Input=I>,
Op: Parser<Input=I>,
Op::Output: FnOnce(P::Output, P::Output) -> P::Outputimpl<I, O, P> Parser for Try<P> where I: Stream, P: Parser<Input=I, Output=O>
impl<I, O, P> Parser for LookAhead<P> where I: Stream,
P: Parser<Input=I, Output=O>impl<I, P1, P2> Parser for With<P1, P2> where I: Stream,
P1: Parser<Input=I>,
P2: Parser<Input=I>impl<I, P1, P2> Parser for Skip<P1, P2> where I: Stream,
P1: Parser<Input=I>,
P2: Parser<Input=I>impl<I, P> Parser for Message<P> where I: Stream, P: Parser<Input=I>
impl<I, O, P1, P2> Parser for Or<P1, P2> where I: Stream,
P1: Parser<Input=I, Output=O>,
P2: Parser<Input=I, Output=O>impl<I, A, B, P, F> Parser for Map<P, F> where I: Stream,
P: Parser<Input=I, Output=A>,
F: FnMut(A) -> Bimpl<I, A, B, P, F> Parser for FlatMap<P, F> where I: Stream,
P: Parser<Input=I, Output=A>,
F: FnMut(A) -> Result<B, ParseError<I>>impl<P, N, F> Parser for Then<P, F> where F: FnMut(P::Output) -> N,
P: Parser,
N: Parser<Input=P::Input>impl<P> Parser for Expected<P> where P: Parser
impl<P, F, O, E> Parser for AndThen<P, F> where P: Parser,
F: FnMut(P::Output) -> Result<O, E>,
E: Into<Error<P::Input::Item, P::Input::Range>>impl<Input: Stream, A, B> Parser for (A, B) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>impl<Input: Stream, A, B, C> Parser for (A, B, C) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>impl<Input: Stream, A, B, C, D> Parser for (A, B, C, D) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E> Parser for (A, B, C, D, E) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F> Parser for (A, B, C, D, E, F) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F, G> Parser for (A, B, C, D, E, F, G) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>,
G: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F, G, H> Parser for (A, B, C, D, E, F, G, H) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>,
G: Parser<Input=Input>,
H: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F, G, H, I> Parser for (A, B, C, D, E, F, G, H, I) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>,
G: Parser<Input=Input>,
H: Parser<Input=Input>,
I: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F, G, H, I, J> Parser for (A, B, C, D, E, F, G, H, I, J) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>,
G: Parser<Input=Input>,
H: Parser<Input=Input>,
I: Parser<Input=Input>,
J: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F, G, H, I, J, K> Parser for (A, B, C, D, E, F, G, H, I, J, K) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>,
G: Parser<Input=Input>,
H: Parser<Input=Input>,
I: Parser<Input=Input>,
J: Parser<Input=Input>,
K: Parser<Input=Input>impl<Input: Stream, A, B, C, D, E, F, G, H, I, J, K, L> Parser for (A, B, C, D, E, F, G, H, I, J, K, L) where Input: Stream,
A: Parser<Input=Input>,
B: Parser<Input=Input>,
C: Parser<Input=Input>,
D: Parser<Input=Input>,
E: Parser<Input=Input>,
F: Parser<Input=Input>,
G: Parser<Input=Input>,
H: Parser<Input=Input>,
I: Parser<Input=Input>,
J: Parser<Input=Input>,
K: Parser<Input=Input>,
L: Parser<Input=Input>impl<E, I, O> Parser for EnvParser<E, I, O> where E: Clone, I: Stream
impl<I> Parser for Range<I> where I: RangeStream, I::Range: PartialEq + Range
impl<I> Parser for Take<I> where I: RangeStream, I::Range: Range
impl<I, F> Parser for TakeWhile<I, F> where I: RangeStream,
I::Range: Range,
F: FnMut(I::Item) -> boolimpl<I, F> Parser for TakeWhile1<I, F> where I: RangeStream,
I::Range: Range,
F: FnMut(I::Item) -> boolimpl<I> Parser for combine::byte::Digit<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Space<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Spaces<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Newline<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::CrLf<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Tab<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Upper<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Lower<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::AlphaNum<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::Letter<I> where I: Stream<Item=u8>
impl<I> Parser for combine::byte::HexDigit<I> where I: Stream<Item=u8>
impl<'a, I> Parser for Bytes<I> where I: Stream<Item=u8, Range=&'a [u8]>
impl<'a, C, I> Parser for BytesCmp<C, I> where C: FnMut(u8, u8) -> bool,
I: Stream<Item=u8, Range=&'a [u8]>impl<I> Parser for combine::char::Digit<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Space<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Spaces<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Newline<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::CrLf<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Tab<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Upper<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Lower<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::AlphaNum<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::Letter<I> where I: Stream<Item=char>
impl<I> Parser for OctDigit<I> where I: Stream<Item=char>
impl<I> Parser for combine::char::HexDigit<I> where I: Stream<Item=char>
impl<I> Parser for Str<I> where I: Stream<Item=char>
impl<C, I> Parser for StrCmp<C, I> where C: FnMut(char, char) -> bool,
I: Stream<Item=char>