Trait parsimonious::Uncommitted
[−]
[src]
pub trait Uncommitted<S>: Parser { type Output; type State: Stateful<S, Output = Self::Output>; fn parse(&self, value: S) -> MaybeParseResult<Self::State, S>
where
Self: Sized; }
A trait for uncommitted parsers.
An uncommitted parser can decide based on the first token of input whether it will commit to parsing, or immediately backtrack and try another option.
The advantage of uncommitted parsers over committed parsers is they support choice:
p.or_else(q)
will try p
, and commit if it commits, but if it backtracks
will then try q
. For example:
fn default_char() -> char { '?' } let parser = character(char::is_numeric) .or_else(character(char::is_alphabetic)) .or_emit(default_char); match parser.init().parse("123") { Done(_,result) => assert_eq!(result,'1'), _ => panic!("Can't happen"), } match parser.init().parse("abc") { Done(_,result) => assert_eq!(result,'a'), _ => panic!("Can't happen"), } match parser.init().parse("!@#") { Done(_,result) => assert_eq!(result,'?'), _ => panic!("Can't happen"), }
Semantically, a parser with input S and output T is a partial function S+ → T whose domain is prefix-closed (that is, if s·t is in the domain, then s is in the domain).
Associated Types
type Output
The type of the data being produced by the parser.
type State: Stateful<S, Output = Self::Output>
The type of the parser state.
Required Methods
fn parse(&self, value: S) -> MaybeParseResult<Self::State, S> where
Self: Sized,
Self: Sized,
Provides data to the parser.
If parser: Uncommitted<S,Output=T>
, then parser.parse(data)
either:
- returns
Empty(data)
becausedata
was empty, - returns
Abort(data)
because the parser should backtrack, or - returns
Commit(result)
because the parser has committed.
For example:
let parser = character(char::is_alphabetic).plus(String::new); match parser.parse("") { Empty("") => (), _ => panic!("can't happen"), } match parser.parse("!abc") { Abort("!abc") => (), _ => panic!("can't happen"), } match parser.parse("abc!") { Commit(Done("!",result)) => assert_eq!(result,"abc"), _ => panic!("can't happen"), } match parser.parse("abc") { Commit(Continue("",parsing)) => match parsing.parse("def!") { Done("!",result) => assert_eq!(result,"abcdef"), _ => panic!("can't happen"), }, _ => panic!("can't happen"), }
Note that the decision to commit or abort must be made on the first token of data (since the parser only retries on empty input) so this is appropriate for LL(1) grammars that only perform one token of lookahead.
Implementors
impl<P, F, S> Uncommitted<S> for MapParser<P, F> where
P: Uncommitted<S>,
F: Copy + Function<P::Output>,impl<P, Q, S> Uncommitted<S> for AndThenParser<P, Q> where
P: Uncommitted<S>,
Q: Committed<S>,impl<P, Q, S> Uncommitted<S> for OrElseParser<P, Q> where
P: Uncommitted<S>,
Q: Uncommitted<S, Output = P::Output>,impl<P, F, S> Uncommitted<S> for PlusParser<P, F> where
P: Copy + Uncommitted<S>,
F: Factory,
F::Output: Consumer<P::Output>,impl<'a, F> Uncommitted<&'a str> for CharacterParser<F> where
F: Function<char, Output = bool>,impl<F, I> Uncommitted<Peekable<I>> for TokenParser<F> where
F: for<'a> Function<&'a I::Item, Output = bool>,
I: Iterator,impl<'a, P> Uncommitted<&'a str> for BufferedParser<P> where
P: Uncommitted<&'a str>,