pub fn choice<T, E>(parsers: T) -> Choice<T, E>
Expand description
Parse using a tuple of many parsers, producing the output of the first to successfully parse.
This primitive has a twofold improvement over a chain of Parser::or
calls:
-
Rust’s trait solver seems to resolve the
Parser
impl for this type much faster, significantly reducing compilation times. -
Parsing is likely a little faster in some cases because the resulting parser is ‘less careful’ about error routing, and doesn’t perform the same fine-grained error prioritisation that
Parser::or
does.
These qualities make this parser ideal for lexers.
The output type of this parser is the output type of the inner parsers.
Examples
#[derive(Clone, Debug, PartialEq)]
enum Token {
If,
For,
While,
Fn,
Int(u64),
Ident(String),
}
let tokens = choice::<_, Simple<char>>((
text::keyword("if").to(Token::If),
text::keyword("for").to(Token::For),
text::keyword("while").to(Token::While),
text::keyword("fn").to(Token::Fn),
text::int(10).from_str().unwrapped().map(Token::Int),
text::ident().map(Token::Ident),
))
.padded()
.repeated();
use Token::*;
assert_eq!(
tokens.parse("if 56 for foo while 42 fn bar"),
Ok(vec![If, Int(56), For, Ident("foo".to_string()), While, Int(42), Fn, Ident("bar".to_string())]),
);