chomp::parse!
[−]
[src]
macro_rules! parse { ( $($t:tt)* ) => { ... }; }
Macro emulating do
-notation for the parser monad, automatically threading the linear type.
parse!{input; parser("parameter"); let value = other_parser(); ret do_something(value); } // is equivalent to: parser(input, "parameter").bind(|i, _| other_parser(i).bind(|i, value| i.ret(do_something(value))))
Example
use chomp::{Input, Error}; use chomp::{take_while1, token}; let i = Input::new("Martin Wernstål\n".as_bytes()); #[derive(Debug, Eq, PartialEq)] struct Name<'a> { first: &'a [u8], last: &'a [u8], } let r = parse!{i; let first = take_while1(|c| c != b' '); token(b' '); let last = take_while1(|c| c != b'\n'); ret @ _, Error<_>: Name{ first: first, last: last, } }; assert_eq!(r.unwrap(), Name{first: b"Martin", last: "Wernstål".as_bytes()});
Grammar
EBNF using $ty
, $expr
, $ident
and $pat
for the equivalent Rust macro patterns.
RET_TYPED = '@' $ty ',' $ty ':' $expr
RET_PLAIN = $expr
ERR_TYPED = '@' $ty ',' $ty ':' $expr
ERR_PLAIN = $expr
VAR = $ident ':' $ty | $pat
ACTION = INLINE_ACTION | NAMED_ACTION
INLINE_ACTION = $ident '->' $expr
NAMED_ACTION = $ident '(' ($expr ',')* ','? ')'
BIND = 'let' VAR '=' ACTION
THEN = ACTION
RET = 'ret' ( RET_TYPED | RET_PLAIN )
ERR = 'err' ( ERR_TYPED | ERR_PLAIN )
EXPR = ( BIND ';' | THEN ';' )* (RET | ERR | THEN)