remove _complete versions of alt and separated_list

This commit is contained in:
Geoffroy Couprie 2019-05-08 19:03:50 +02:00
parent 45f142e3fa
commit e159af1b39
4 changed files with 1 additions and 277 deletions

View File

@ -33,6 +33,7 @@
- `sized_buffer` and `length_bytes!`: they can be replaced with the `length_data` function
- `non_empty`, `begin` and `rest_s` function
- `cond_reduce!`, `cond_with_error!`, `closure!`, `apply`, `map_res_err!`
- `alt_complete`, `separated_list_complete`, `separated_nonempty_list_complete`
## 4.2.3 - 2019-03-23

View File

@ -131,9 +131,6 @@
/// );
/// ```
///
/// If you want the `complete!` combinator to be applied to all rules then use the convenience
/// `alt_complete!` macro (see below).
///
/// This behaviour of `alt!` can get especially confusing if multiple alternatives have different
/// sizes but a common prefix, like this:
///
@ -257,108 +254,6 @@ macro_rules! alt (
);
);
/// Is equivalent to the `alt!` combinator, except that it will not return `Incomplete`
/// when one of the constituting parsers returns `Incomplete`. Instead, it will try the
/// next alternative in the chain.
///
/// You should use this combinator only if you know you
/// will not receive partial input for the rules you're trying to match (this
/// is almost always the case for parsing programming languages).
///
/// ```rust,ignore
/// alt_complete!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O>
/// ```
/// All the parsers must have the same return type.
///
/// If one of the parsers return `Incomplete`, `alt_complete!` will try the next alternative.
/// If there is no other parser left to try, an `Error` will be returned.
///
/// ```rust,ignore
/// alt_complete!(parser_1 | parser_2 | ... | parser_n)
/// ```
/// **For more in depth examples, refer to the documentation of `alt!`**
#[macro_export(local_inner_macros)]
macro_rules! alt_complete (
// Recursive rules (must include `complete!` around the head)
($i:expr, $e:path | $($rest:tt)*) => (
alt_complete!($i, complete!(call!($e)) | $($rest)*);
);
($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => (
{
use $crate::lib::std::result::Result::*;
use $crate::Err;
let i_ = $i.clone();
let res = complete!(i_, $subrule!($($args)*));
match res {
Ok((_,_)) => res,
Err(Err::Failure(e)) => Err(Err::Failure(e)),
e => {
let out = alt_complete!($i, $($rest)*);
if let (&Err(Err::Error(ref e1)), &Err(Err::Error(ref e2))) = (&e, &out) {
// Compile-time hack to ensure that res's E type is not under-specified.
// This all has no effect at runtime.
fn unify_types<T>(_: &T, _: &T) {}
unify_types(e1, e2);
}
out
},
}
}
);
($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => (
{
use $crate::lib::std::result::Result::*;
use $crate::Err;
let i_ = $i.clone();
match complete!(i_, $subrule!($($args)*)) {
Ok((i,o)) => Ok((i,$gen(o))),
Err(Err::Failure(e)) => Err(Err::Failure(e)),
e => {
let out = alt_complete!($i, $($rest)*);
if let (&Err(Err::Error(ref e1)), &Err(Err::Error(ref e2))) = (&e, &out) {
// Compile-time hack to ensure that res's E type is not under-specified.
// This all has no effect at runtime.
fn unify_types<T>(_: &T, _: &T) {}
unify_types(e1, e2);
}
out
},
}
}
);
($i:expr, $e:path => { $gen:expr } | $($rest:tt)*) => (
alt_complete!($i, complete!(call!($e)) => { $gen } | $($rest)*);
);
// Tail (non-recursive) rules
($i:expr, $e:path => { $gen:expr }) => (
alt_complete!($i, call!($e) => { $gen });
);
($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => (
alt!(__impl $i, complete!($subrule!($($args)*)) => { $gen } | __end)
);
($i:expr, $e:path) => (
alt_complete!($i, call!($e));
);
($i:expr, $subrule:ident!( $($args:tt)*)) => (
alt!(__impl $i, complete!($subrule!($($args)*)) | __end)
);
);
/// `switch!(I -> IResult<I,P>, P => I -> IResult<I,O> | ... | P => I -> IResult<I,O> ) => I -> IResult<I, O>`
/// choose the next parser depending on the result of the first one, if successful,
/// and returns the result of the second parser
@ -983,20 +878,6 @@ mod tests {
assert_eq!(alt1(a), Ok((&b"g"[..], &b"def"[..])));
}
#[test]
fn alt_complete() {
named!(ac<&[u8], &[u8]>,
alt_complete!(tag!("abcd") | tag!("ef") | tag!("ghi") | tag!("kl"))
);
let a = &b""[..];
assert_eq!(ac(a), Err(Err::Error(error_position!(a, ErrorKind::Alt))));
let a = &b"ef"[..];
assert_eq!(ac(a), Ok((&b""[..], &b"ef"[..])));
let a = &b"cde"[..];
assert_eq!(ac(a), Err(Err::Error(error_position!(a, ErrorKind::Alt))));
}
#[allow(unused_variables)]
#[test]
fn switch() {

View File

@ -43,46 +43,6 @@ macro_rules! separated_nonempty_list(
);
);
/// `separated_list_complete!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
/// This is equivalent to the `separated_list!` combinator, except that it will return `Error`
/// when either the separator or element subparser returns `Incomplete`.
#[macro_export(local_inner_macros)]
macro_rules! separated_list_complete(
($i:expr, $sep:ident!( $($args:tt)* ), $submac:ident!( $($args2:tt)* )) => ({
separated_list!($i, complete!($sep!($($args)*)), complete!($submac!($($args2)*)))
});
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
separated_list_complete!($i, $submac!($($args)*), call!($g));
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
separated_list_complete!($i, call!($f), $submac!($($args)*));
);
($i:expr, $f:expr, $g:expr) => (
separated_list_complete!($i, call!($f), call!($g));
);
);
/// `separated_nonempty_list_complete!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
/// This is equivalent to the `separated_nonempty_list!` combinator, except that it will return
/// `Error` when either the separator or element subparser returns `Incomplete`.
#[macro_export(local_inner_macros)]
macro_rules! separated_nonempty_list_complete(
($i:expr, $sep:ident!( $($args:tt)* ), $submac:ident!( $($args2:tt)* )) => ({
separated_nonempty_list!($i, complete!($sep!($($args)*)), complete!($submac!($($args2)*)))
});
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
separated_nonempty_list_complete!($i, $submac!($($args)*), call!($g));
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
separated_nonempty_list_complete!($i, call!($f), $submac!($($args)*));
);
($i:expr, $f:expr, $g:expr) => (
separated_nonempty_list_complete!($i, call!($f), call!($g));
);
);
/// `many0!(I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
/// Applies the parser 0 or more times and returns the list of results in a Vec.
///
@ -586,27 +546,6 @@ mod tests {
assert_eq!(multi(h), Err(Err::Incomplete(Needed::Size(4))));
}
#[test]
#[cfg(feature = "alloc")]
fn separated_list_complete() {
use character::complete::alpha1 as alpha;
named!(multi<&[u8],Vec<&[u8]> >, separated_list_complete!(tag!(","), alpha));
let a = &b"abcdef;"[..];
let b = &b"abcd,abcdef;"[..];
let c = &b"abcd,abcd,ef;"[..];
let d = &b"abc."[..];
let e = &b"abcd,ef."[..];
let f = &b"123"[..];
assert_eq!(multi(a), Ok((&b";"[..], vec![&a[..a.len() - 1]])));
assert_eq!(multi(b), Ok((&b";"[..], vec![&b"abcd"[..], &b"abcdef"[..]])));
assert_eq!(multi(c), Ok((&b";"[..], vec![&b"abcd"[..], &b"abcd"[..], &b"ef"[..]])));
assert_eq!(multi(d), Ok((&b"."[..], vec![&b"abc"[..]])));
assert_eq!(multi(e), Ok((&b"."[..], vec![&b"abcd"[..], &b"ef"[..]])));
assert_eq!(multi(f), Ok((&b"123"[..], Vec::new())));
}
#[test]
#[cfg(feature = "alloc")]
fn separated_nonempty_list() {
@ -635,27 +574,6 @@ mod tests {
assert_eq!(multi(h), Err(Err::Incomplete(Needed::Size(4))));
}
#[test]
#[cfg(feature = "alloc")]
fn separated_nonempty_list_complete() {
use character::complete::alpha1 as alpha;
named!(multi<&[u8],Vec<&[u8]> >, separated_nonempty_list_complete!(tag!(","), alpha));
let a = &b"abcdef;"[..];
let b = &b"abcd,abcdef;"[..];
let c = &b"abcd,abcd,ef;"[..];
let d = &b"abc."[..];
let e = &b"abcd,ef."[..];
let f = &b"123"[..];
assert_eq!(multi(a), Ok((&b";"[..], vec![&a[..a.len() - 1]])));
assert_eq!(multi(b), Ok((&b";"[..], vec![&b"abcd"[..], &b"abcdef"[..]])));
assert_eq!(multi(c), Ok((&b";"[..], vec![&b"abcd"[..], &b"abcd"[..], &b"ef"[..]])));
assert_eq!(multi(d), Ok((&b"."[..], vec![&b"abc"[..]])));
assert_eq!(multi(e), Ok((&b"."[..], vec![&b"abcd"[..], &b"ef"[..]])));
assert_eq!(multi(f), Err(Err::Error(error_position!(&b"123"[..], ErrorKind::Alpha))));
}
#[test]
#[cfg(feature = "alloc")]
fn many0() {

View File

@ -584,60 +584,6 @@ macro_rules! alt_sep (
);
);
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! alt_complete_sep (
($i:expr, $separator:path, $e:path | $($rest:tt)*) => (
alt_complete_sep!($i, $separator, complete!(call!($e)) | $($rest)*);
);
($i:expr, $separator:path, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => (
{
use $crate::lib::std::result::Result::*;
let res = complete!($i, sep!($separator, $subrule!($($args)*)));
match res {
Ok((_,_)) => res,
_ => alt_complete_sep!($i, $separator, $($rest)*),
}
}
);
($i:expr, $separator:path, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => (
{
use $crate::lib::std::result::Result::*;
use $crate::{Err,Needed,IResult};
match complete!($i, sep!($separator, $subrule!($($args)*))) {
Ok((i,o)) => Ok((i,$gen(o))),
_ => alt_complete_sep!($i, $separator, $($rest)*),
}
}
);
($i:expr, $separator:path, $e:path => { $gen:expr } | $($rest:tt)*) => (
alt_complete_sep!($i, $separator, complete!(call!($e)) => { $gen } | $($rest)*);
);
// Tail (non-recursive) rules
($i:expr, $separator:path, $e:path => { $gen:expr }) => (
alt_complete_sep!($i, $separator, call!($e) => { $gen });
);
($i:expr, $separator:path, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => (
alt_sep!(__impl $i, $separator, complete!($subrule!($($args)*)) => { $gen })
);
($i:expr, $separator:path, $e:path) => (
alt_complete_sep!($i, $separator, call!($e));
);
($i:expr, $separator:path, $subrule:ident!( $($args:tt)*)) => (
alt_sep!(__impl $i, $separator, complete!($subrule!($($args)*)))
);
);
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! switch_sep (
@ -790,12 +736,6 @@ macro_rules! sep (
alt_sep!($separator, $($rest)*)
)
};
($i:expr, $separator:path, alt_complete ! ($($rest:tt)*) ) => {
wrap_sep!($i,
$separator,
alt_complete_sep!($separator, $($rest)*)
)
};
($i:expr, $separator:path, switch ! ($($rest:tt)*) ) => {
wrap_sep!($i,
$separator,
@ -1095,22 +1035,6 @@ mod tests {
}
/*FIXME: alt_complete works, but ws will return Incomplete on end of input
#[test]
fn alt_complete() {
named!(ac<&[u8], &[u8]>,
ws!(alt_complete!(tag!("abcd") | tag!("ef") | tag!("ghi") | tag!("kl")))
);
let a = &b""[..];
assert_eq!(ac(a), Err(Err::Error(error_position!(a, ErrorKind::Alt))));
let a = &b" \tef "[..];
assert_eq!(ac(a),Ok((&b""[..], &b"ef"[..])));
let a = &b" cde"[..];
assert_eq!(ac(a), Err(Err::Error(error_position!(&a[1..], ErrorKind::Alt))));
}
*/
named!(str_parse(&str) -> &str, ws!(tag!("test")));
#[allow(unused_variables)]
#[test]