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::{Error, parse_only};
use chomp::{take_while1, token};

#[derive(Debug, Eq, PartialEq)]
struct Name<'a> {
    first: &'a [u8],
    last:  &'a [u8],
}

let r = |i| 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!(parse_only(r, "Martin Wernstål\n".as_bytes()), Ok(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)