Fix some issues in argument parsing for switch!

This commit is contained in:
Geoffroy Couprie 2015-12-31 13:23:09 +01:00
parent 27b4fc9579
commit f255e2e71d
2 changed files with 62 additions and 7 deletions

View File

@ -1132,9 +1132,51 @@ macro_rules! alt_parser (
/// assert_eq!(sw(&d[..]), Error(Position(ErrorKind::Switch, &b"blah"[..])));
/// # }
/// ```
///
/// Due to limitations in Rust macros, it is not possible to have simple functions on the right hand
/// side of pattern, like this:
///
/// ```ignore
/// named!(sw,
/// switch!(take!(4),
/// b"abcd" => tag!("XYZ") |
/// b"efgh" => tag!("123")
/// )
/// );
/// ```
///
/// If you want to pass your own functions instead, you can use the `call!` combinator as follows:
///
/// ```ignore
/// named!(xyz, tag!("XYZ"));
/// named!(num, tag!("123"));
/// named!(sw,
/// switch!(take!(4),
/// b"abcd" => call!(xyz) |
/// b"efgh" => call!(num)
/// )
/// );
/// ```
///
#[macro_export]
macro_rules! switch (
($i:expr, $submac:ident!( $($args:tt)*), $($p:pat => $subrule:ident!( $($args2:tt)* ))|*) => (
($i:expr, $submac:ident!( $($args:tt)*), $($rest:tt)*) => (
{
switch_impl!($i, $submac!($($args)*), $($rest)*)
}
);
($i:expr, $e:ident, $($rest:tt)*) => (
{
switch_impl!($i, call!($e), $($rest)*)
}
);
);
/// Internal parser, do not use directly
#[doc(hidden)]
#[macro_export]
macro_rules! switch_impl (
($i:expr, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Error(e) => $crate::IResult::Error($crate::Err::NodePosition(
@ -1155,13 +1197,7 @@ macro_rules! switch (
}
}
);
($i:expr, $e:ident, $($rest:tt)*) => (
{
switch!($i, call!($e), $($rest)*)
}
);
);
/// `opt!(I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
/// make the underlying parser optional
///

View File

@ -1,3 +1,4 @@
//#![feature(trace_macros)]
#[macro_use]
extern crate nom;
@ -95,3 +96,21 @@ fn issue_142(){
let expected = IResult::Done(&b" "[..], vec![12, 34, 5689]);
assert_eq!(subject, expected)
}
/*
DOES NOT COMPILE
#[test]
fn issue_152() {
named!(take4, take!(4));
named!(xyz, tag!("XYZ"));
named!(abc, tag!("abc"));
named!(sw,
switch!(take4,
b"abcd" => xyz |
b"efgh" => abc
)
);
}
*/