diff --git a/src/macros.rs b/src/macros.rs index fdc2927b..41c8be17 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -108,7 +108,7 @@ macro_rules! succ ( /// _: spaced(b':'), /// value: alphanumeric1.map(|s: &[u8]| s.to_owned()), /// _: spaced(b':'), -/// point: (num, spaced(b','), num).map(|(x, _, y)| Point(x, y),) +/// point: seq!(Point(num, _: spaced(b','), num)), /// } /// }; /// assert_eq!( @@ -142,6 +142,16 @@ macro_rules! seq { )) }) }; + ($name: ident ( $($elements: tt)* )) => { + $crate::trace::trace(stringify!($name), move |input| { + use $crate::Parser; + $crate::seq_parse_elements!(input; a; $($elements)*); + Ok(( + input, + $crate::seq_elements!( ($($elements)*); $name; a), + )) + }) + }; } #[macro_export] @@ -188,3 +198,48 @@ macro_rules! seq_fields { $crate::seq_fields!(; $name $($tt)* $field: $field,) }; } + +#[macro_export] +#[doc(hidden)] +macro_rules! seq_parse_elements { + ($input: ident ; $var: ident; _ : $parser: expr, $($remaining: tt)*) => { + let ($input, _) = $parser.parse_next($input)?; + $crate::seq_parse_elements!($input; concat_idents!($var, a); $($remaining)*) + }; + ($input: ident ; $var: ident ; $parser: expr, $($remaining: tt)*) => { + let ($input, $var) = $parser.parse_next($input)?; + $crate::seq_parse_elements!($input; concat_idents!($var, a); $($remaining)*) + }; + ($input: ident ; $var: ident ; $parser: expr) => { + let ($input, $var) = $parser.parse_next($input)?; + }; + ($input: ident ; $var: ident ;) => {}; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! seq_elements { + (; $name: ident $($tt: tt)* ; $var: ident) => { + $name ( $($tt)* ) + }; + ( (_ : $parser: expr, $($remaining: tt)+ ); $name: ident $($tt: tt)* ; $var: ident) => { + $crate::seq_elements!( ( $($remaining)+ ) ; $name $($tt)* ; concat_idents!($var, a)) + }; + ( ($parser: expr, $($remaining: tt)+ ); + $name: ident $($tt: tt)* ; $var: ident) => + { + $crate::seq_elements!( ( $($remaining)+ ) ; $name $($tt)* $var, ; concat_idents!($var, a)) + }; + ( ( _ : $parser: expr ); $name: ident $($tt: tt)* ; $var: ident) => { + $crate::seq_elements!( ; $name $($tt)* ; concat_idents!($var, a)) + }; + ( ($parser: expr ); $name: ident $($tt: tt)* ; $var: ident) => { + $crate::seq_elements!(; $name $($tt)* $var, ; concat_idents!($var, a)) + }; + ( ( _ : $parser: expr, ); $name: ident $($tt: tt)* ; $var: ident) => { + $crate::seq_elements!(; $name $($tt)* ; concat_idents!($var, a)) + }; + ( ($parser: expr, ); $name: ident $($tt: tt)* ; $var: ident) => { + $crate::seq_elements!(; $name $($tt)* $var, ; concat_idents!($var, a)) + }; +}