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

The type of the data being produced by the parser.

The type of the parser state.

Required Methods

Provides data to the parser.

If parser: Uncommitted<S,Output=T>, then parser.parse(data) either:

  • returns Empty(data) because data 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