From 4cf23db82c37f4d24ea093e268bb96a1ae1afe3d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 20 Mar 2019 18:59:25 +0100 Subject: Obsolete old parser macros; performance is now dead --- dhall_core/src/lib.rs | 2 +- dhall_core/src/parser.rs | 453 +++++++++++++++++++++++++++-------------------- 2 files changed, 266 insertions(+), 189 deletions(-) (limited to 'dhall_core') diff --git a/dhall_core/src/lib.rs b/dhall_core/src/lib.rs index 43c8d9a..508ad3a 100644 --- a/dhall_core/src/lib.rs +++ b/dhall_core/src/lib.rs @@ -1,6 +1,6 @@ #![feature(trace_macros)] #![feature(slice_patterns)] -#![recursion_limit="128"] +#![recursion_limit = "128"] #![allow( clippy::many_single_char_names, clippy::should_implement_trait, diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index 4bbb08a..6718c00 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -71,153 +71,206 @@ fn debug_pair(pair: Pair) -> String { s } -#[derive(Debug)] -enum IterMatchError { - NoMatchFound, - Other(T), // Allow other macros to inject their own errors -} +// #[derive(Debug)] +// enum IterMatchError { +// NoMatchFound, +// Other(T), // Allow other macros to inject their own errors +// } + +// macro_rules! match_iter_typed { +// // Collect untyped arguments to pass to match_iter! +// (@collect, ($($vars:tt)*), ($($args:tt)*), ($($acc:tt)*), ($x:ident : $ty:ident, $($rest:tt)*)) => { +// match_iter_typed!(@collect, ($($vars)*), ($($args)*), ($($acc)*, $x), ($($rest)*)) +// }; +// (@collect, ($($vars:tt)*), ($($args:tt)*), ($($acc:tt)*), ($x:ident.. : $ty:ident, $($rest:tt)*)) => { +// match_iter_typed!(@collect, ($($vars)*), ($($args)*), ($($acc)*, $x..), ($($rest)*)) +// }; +// // Catch extra comma if exists +// (@collect, ($($vars:tt)*), ($($args:tt)*), (,$($acc:tt)*), ($(,)*)) => { +// match_iter_typed!(@collect, ($($vars)*), ($($args)*), ($($acc)*), ()) +// }; +// (@collect, ($iter:expr, $body:expr, $callback:ident, $error:ident), ($($args:tt)*), ($($acc:tt)*), ($(,)*)) => { +// { +// let res = iter_patterns::destructure_iter!($iter; [$($acc)*] => { +// match_iter_typed!(@callback, $callback, $iter, $($args)*); +// $body +// }); +// res.ok_or(IterMatchError::NoMatchFound) +// } +// }; + +// // Pass the matches through the callback +// (@callback, $callback:ident, $iter:expr, $x:ident : $ty:ident $($rest:tt)*) => { +// let $x = $callback!(@type_callback, $ty, $x); +// #[allow(unused_mut)] +// let mut $x = match $x { +// Ok(x) => x, +// Err(e) => break Err(IterMatchError::Other(e)), +// }; +// match_iter_typed!(@callback, $callback, $iter $($rest)*); +// }; +// (@callback, $callback: ident, $iter:expr, $x:ident.. : $ty:ident $($rest:tt)*) => { +// let $x = $x.map(|x| $callback!(@type_callback, $ty, x)).collect(); +// let $x: Vec<_> = match $x { +// Ok(x) => x, +// Err(e) => break Err(IterMatchError::Other(e)), +// }; +// #[allow(unused_mut)] +// let mut $x = $x.into_iter(); +// match_iter_typed!(@callback, $callback, $iter $($rest)*); +// }; +// (@callback, $callback:ident, $iter:expr $(,)*) => {}; + +// ($callback:ident; $iter:expr; ($($args:tt)*) => $body:expr) => { +// { +// #[allow(unused_mut)] +// let mut iter = $iter; +// let res: Result<_, IterMatchError<_>> = loop { +// break match_iter_typed!(@collect, +// (iter, $body, $callback, last_error), +// ($($args)*), (), ($($args)*,) +// ) +// }; +// res +// } +// }; +// } + +// macro_rules! match_iter_branching { +// (@noclone, $callback:ident; $arg:expr; $( $submac:ident!($($args:tt)*) => $body:expr ),* $(,)*) => { +// { +// #[allow(unused_assignments)] +// let mut last_error = IterMatchError::NoMatchFound; +// // Not a real loop; used for error handling +// // Would use loop labels but they create warnings +// #[allow(unreachable_code)] +// loop { +// $( +// let matched: Result<_, IterMatchError<_>> = +// $callback!(@branch_callback, $submac, $arg; ($($args)*) => $body); +// #[allow(unused_assignments)] +// match matched { +// Ok(v) => break Ok(v), +// Err(e) => last_error = e, +// }; +// )* +// break Err(last_error); +// } +// } +// }; +// ($callback:ident; $iter:expr; $($args:tt)*) => { +// { +// #[allow(unused_mut)] +// let mut iter = $iter; +// match_iter_branching!(@noclone, $callback; iter.clone(); $($args)*) +// } +// }; +// } -macro_rules! match_iter_typed { - // Collect untyped arguments to pass to match_iter! - (@collect, ($($vars:tt)*), ($($args:tt)*), ($($acc:tt)*), ($x:ident : $ty:ident, $($rest:tt)*)) => { - match_iter_typed!(@collect, ($($vars)*), ($($args)*), ($($acc)*, $x), ($($rest)*)) - }; - (@collect, ($($vars:tt)*), ($($args:tt)*), ($($acc:tt)*), ($x:ident.. : $ty:ident, $($rest:tt)*)) => { - match_iter_typed!(@collect, ($($vars)*), ($($args)*), ($($acc)*, $x..), ($($rest)*)) - }; - // Catch extra comma if exists - (@collect, ($($vars:tt)*), ($($args:tt)*), (,$($acc:tt)*), ($(,)*)) => { - match_iter_typed!(@collect, ($($vars)*), ($($args)*), ($($acc)*), ()) - }; - (@collect, ($iter:expr, $body:expr, $callback:ident, $error:ident), ($($args:tt)*), ($($acc:tt)*), ($(,)*)) => { - { - let res = iter_patterns::destructure_iter!($iter; [$($acc)*] => { - match_iter_typed!(@callback, $callback, $iter, $($args)*); - $body - }); - res.ok_or(IterMatchError::NoMatchFound) - } +macro_rules! match_pair { + // // (@type_callback, parse_any_fast, $x:expr) => { + // // ParseWrapped::parse_any_fast($x).map(Box::new) + // // }; + // (@type_callback, $ty:ident, $x:expr) => { + // ParseUnwrapped::$ty($x) + // // ParseWrapped::$ty($x).map(|x| x.$ty()) + // // match ParseWrapped::parse_any($x) { + // // match parse_any_fast($x.clone()) { + // // // match ParseWrapped::$ty($x.clone()) { + // // Ok(ParsedValue::$ty(x)) => Ok(x), + // // // _ => ParseUnwrapped::$ty($x), + // // _ => Err(custom_parse_error(&$x, format!("Total failure"))), + // // } + // }; + // (@branch_callback, children, $pair:expr; $($args:tt)*) => { + // { + // #[allow(unused_mut)] + // let mut pairs = $pair.clone().into_inner(); + // match_iter_typed!(match_pair; pairs; $($args)*) + // } + // }; + // (@branch_callback, raw_pair, $pair:expr; ($x:ident) => $body:expr) => { + // { + // let $x = $pair.clone(); + // Ok($body) + // } + // }; + // (@branch_callback, captured_str, $pair:expr; ($x:ident) => $body:expr) => { + // { + // let $x = $pair.as_str(); + // Ok($body) + // } + // }; + + (@make_child_match, $pair:expr, ($($outer_acc:tt)*), ($($acc:tt)*), ($(,)* $x:ident : $ty:ident $($rest_of_match:tt)*) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_child_match, $pair, ($($outer_acc)*), ($($acc)*, ParsedValue::$ty($x)), ($($rest_of_match)*) => $body, $($rest)*) }; - - // Pass the matches through the callback - (@callback, $callback:ident, $iter:expr, $x:ident : $ty:ident $($rest:tt)*) => { - let $x = $callback!(@type_callback, $ty, $x); - #[allow(unused_mut)] - let mut $x = match $x { - Ok(x) => x, - Err(e) => break Err(IterMatchError::Other(e)), - }; - match_iter_typed!(@callback, $callback, $iter $($rest)*); + (@make_child_match, $pair:expr, ($($outer_acc:tt)*), ($($acc:tt)*), ($(,)* $x:ident.. : $ty:ident $($rest_of_match:tt)*) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_child_match, $pair, ($($outer_acc)*), ($($acc)*, x..), ($($rest_of_match)*) => { + let $x = x.map(|x| x.$ty()); + $body + }, $($rest)*) }; - (@callback, $callback: ident, $iter:expr, $x:ident.. : $ty:ident $($rest:tt)*) => { - let $x = $x.map(|x| $callback!(@type_callback, $ty, x)).collect(); - let $x: Vec<_> = match $x { - Ok(x) => x, - Err(e) => break Err(IterMatchError::Other(e)), - }; - #[allow(unused_mut)] - let mut $x = $x.into_iter(); - match_iter_typed!(@callback, $callback, $iter $($rest)*); + (@make_child_match, $pair:expr, ($($outer_acc:tt)*), (, $($acc:tt)*), ($(,)*) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_matches, $pair, ([$($acc)*] => { $body }, $($outer_acc)*), $($rest)*) }; - (@callback, $callback:ident, $iter:expr $(,)*) => {}; - - ($callback:ident; $iter:expr; ($($args:tt)*) => $body:expr) => { - { - #[allow(unused_mut)] - let mut iter = $iter; - let res: Result<_, IterMatchError<_>> = loop { - break match_iter_typed!(@collect, - (iter, $body, $callback, last_error), - ($($args)*), (), ($($args)*,) - ) - }; - res - } + (@make_child_match, $pair:expr, ($($outer_acc:tt)*), (), ($(,)*) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_matches, $pair, ([] => { $body }, $($outer_acc)*), $($rest)*) }; -} -macro_rules! match_iter_branching { - (@noclone, $callback:ident; $arg:expr; $( $submac:ident!($($args:tt)*) => $body:expr ),* $(,)*) => { - { - #[allow(unused_assignments)] - let mut last_error = IterMatchError::NoMatchFound; - // Not a real loop; used for error handling - // Would use loop labels but they create warnings - #[allow(unreachable_code)] - loop { - $( - let matched: Result<_, IterMatchError<_>> = - $callback!(@branch_callback, $submac, $arg; ($($args)*) => $body); - #[allow(unused_assignments)] - match matched { - Ok(v) => break Ok(v), - Err(e) => last_error = e, - }; - )* - break Err(last_error); - } - } + (@make_matches, $pair:expr, ($($acc:tt)*), children!($($args:tt)*) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_child_match, $pair, ($($acc)*), (), ($($args)*) => $body, $($rest)*) + // (@make_matches, $pair:expr, ($($acc:tt)*), children!($($x:ident : $ty:ident),*) => $body:expr, $($rest:tt)*) => { + // match_pair!(@make_child_match, $pair, ($($acc)*), ($(, ParsedValue::$ty($x))*), () => $body, $($rest)*) + // match_pair!(@make_matches, $pair, ([$(ParsedValue::$ty($x)),*] => { $body }, $($acc)*), $($rest)*) }; - ($callback:ident; $iter:expr; $($args:tt)*) => { - { - #[allow(unused_mut)] - let mut iter = $iter; - match_iter_branching!(@noclone, $callback; iter.clone(); $($args)*) - } - }; -} - -macro_rules! match_pair { - (@type_callback, $ty:ident, $x:expr) => { - ParseUnwrapped::$ty($x) - // ParseWrapped::$ty($x).map(|x| x.$ty()) - }; - (@branch_callback, children, $pair:expr; $($args:tt)*) => { - { - #[allow(unused_mut)] - let mut pairs = $pair.clone().into_inner(); - match_iter_typed!(match_pair; pairs; $($args)*) - } - }; - (@branch_callback, self, $pair:expr; ($x:ident : $ty:ident) => $body:expr) => { - { - let $x = match_pair!(@type_callback, $ty, $pair.clone()); - match $x { - Ok($x) => Ok($body), - Err(e) => Err(IterMatchError::Other(e)), - } - } - }; - (@branch_callback, raw_pair, $pair:expr; ($x:ident) => $body:expr) => { - { + (@make_matches, $pair:expr, ($($acc:tt)*), raw_pair!($x:ident) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_matches, $pair, ([..] => { let $x = $pair.clone(); - Ok($body) - } + $body + }, $($acc)*), $($rest)*) }; - (@branch_callback, captured_str, $pair:expr; ($x:ident) => $body:expr) => { - { + (@make_matches, $pair:expr, ($($acc:tt)*), captured_str!($x:ident) => $body:expr, $($rest:tt)*) => { + match_pair!(@make_matches, $pair, ([..] => { let $x = $pair.as_str(); - Ok($body) - } + $body + }, $($acc)*), $($rest)*) }; - - ($pair:expr; $( children!($($x:ident : $ty:ident),*) => $body:expr ),* $(,)*) => { + (@make_matches, $pair:expr, ($($acc:tt)*) $(,)*) => { { - let pair = $pair; + let pair = $pair.clone(); let rule = pair.as_rule(); - let err = custom_parse_error(&pair, "No match found".to_owned()); - let parsed: Vec<_> = pair.into_inner().map(ParseWrapped::parse_any_fast).collect::>()?; + let parsed: Vec<_> = pair.clone().into_inner().map(ParseWrapped::parse_any_fast).collect::>()?; #[allow(unreachable_code)] iter_patterns::match_vec!(parsed; - $( - [$(ParsedValue::$ty($x)),*] => { - $body - }, - )* + $($acc)* [x..] => panic!("Unexpected children while parsing rule '{:?}': {:?}", rule, x.collect::>()), - ).ok_or(err) + ).ok_or_else(|| custom_parse_error(&pair, "No match found".to_owned())) } }; + + // ($pair:expr; $( children!($($x:ident : $ty:ident),*) => $body:expr ),* $(,)*) => { + // match_pair!(@make_matches, $pair, (), $( children!($($x : $ty),*) => $body ),* ,) + // ($pair:expr; $( children!($($args:tt)*) => $body:expr ),* $(,)*) => { + // match_pair!(@make_matches, $pair, (), $( children!($($args)*) => $body ),* ,) + ($pair:expr; $( $submac:ident!($($args:tt)*) => $body:expr ),* $(,)*) => { + match_pair!(@make_matches, $pair, (), $( $submac!($($args)*) => $body ),* ,) + // ($pair:expr; $($args:tt)*) => { + // match_pair!(@make_matches, $pair, (), $($args)*) + // { + // let pair = $pair; + // let rule = pair.as_rule(); + // let err = custom_parse_error(&pair, "No match found".to_owned()); + // let parsed: Vec<_> = pair.into_inner().map(ParseWrapped::parse_any_fast).collect::>()?; + // #[allow(unreachable_code)] + // iter_patterns::match_vec!(parsed; + // $( + // [$(ParsedValue::$ty($x)),*] => { $body }, + // )* + // [x..] => panic!("Unexpected children while parsing rule '{:?}': {:?}", rule, x.collect::>()), + // ).ok_or(err) + // } + }; ($pair:expr; $($args:tt)*) => { { let pair = $pair; @@ -277,7 +330,7 @@ macro_rules! make_parser { #[derive(Debug)] enum ParsedValue<'a> { $( $name($o), )* - parse_any(Box>), + // parse_any(Box>), } impl<'a> ParsedValue<'a> { @@ -290,25 +343,25 @@ macro_rules! make_parser { } } )* - #[allow(non_snake_case, dead_code)] - fn parse_any(self) -> Box> { - match self { - ParsedValue::parse_any(x) => x, - x => Box::new(x), - } - } - #[allow(non_snake_case, dead_code)] - fn parse_any_fast(self) -> Box> { - self.parse_any() - } + // #[allow(non_snake_case, dead_code)] + // fn parse_any(self) -> Box> { + // match self { + // ParsedValue::parse_any(x) => x, + // x => Box::new(x), + // } + // } + // #[allow(non_snake_case, dead_code)] + // fn parse_any_fast(self) -> Box> { + // self.parse_any() + // } } - named!(parse_any>>; - // self!(x: parse_any_fast) => x, - $( - self!(x: $name) => Box::new(ParsedValue::$name(x)), - )* - ); + // named!(parse_any>>; + // // self!(x: parse_any_fast) => x, + // $( + // self!(x: $name) => Box::new(ParsedValue::$name(x)), + // )* + // ); impl ParseWrapped { #[allow(non_snake_case, dead_code)] @@ -317,6 +370,19 @@ macro_rules! make_parser { } } + impl ParseUnwrapped { + #[allow(unused_variables, non_snake_case, dead_code, clippy::all)] + fn expression<'a>(pair: Pair<'a, Rule>) -> ParseResult { + ParseWrapped::expression(pair).map(|x| x.expression()) + } + } + impl ParseWrapped { + #[allow(unused_variables, non_snake_case, dead_code, clippy::all)] + fn expression<'a>(pair: Pair<'a, Rule>) -> ParseResult> { + ParseWrapped::parse_any_fast(pair) + } + } + // fn do_the_parse(s: &str, r: Rule, ty: ParsedType) -> ParseResult { // let pairs = DhallParser::parse(r, s)?; // match_iter!(pairs; (e) => ty.parse(e)) @@ -328,7 +394,6 @@ macro_rules! make_parser { ); } - macro_rules! make_pest_parse_function { ($name:ident<$o:ty>; $submac:ident!( $($args:tt)* )) => ( impl ParseUnwrapped { @@ -347,43 +412,44 @@ macro_rules! make_pest_parse_function { ); } -macro_rules! named { - ($name:ident<$o:ty>; $($args:tt)*) => ( - make_pest_parse_function!($name<$o>; match_pair!( $($args)* )); - ); -} +// macro_rules! named { +// ($name:ident<$o:ty>; $($args:tt)*) => ( +// make_pest_parse_function!($name<$o>; match_pair!( $($args)* )); +// ); +// } macro_rules! rule { ($name:ident<$o:ty>; $($args:tt)*) => ( - make_pest_parse_function!($name<$o>; match_rule!( - Rule::$name => match_pair!( $($args)* ), - )); + make_pest_parse_function!($name<$o>; match_pair!( $($args)* )); + // make_pest_parse_function!($name<$o>; match_rule!( + // Rule::$name => match_pair!( $($args)* ), + // )); ); } macro_rules! rule_group { ($name:ident<$o:ty>; $($ty:ident),*) => ( - make_pest_parse_function!($name<$o>; match_rule!( - $( - Rule::$ty => match_pair!(raw_pair!(p) => ParseUnwrapped::$ty(p)?), - )* - )); + // make_pest_parse_function!($name<$o>; match_rule!( + // $( + // Rule::$ty => match_pair!(raw_pair!(p) => ParseUnwrapped::$ty(p)?), + // )* + // )); ); } -macro_rules! match_rule { - ($pair:expr; $($pat:pat => $submac:ident!( $($args:tt)* ),)*) => { - { - #[allow(unreachable_patterns)] - match $pair.as_rule() { - $( - $pat => $submac!($pair; $($args)*), - )* - r => Err(custom_parse_error(&$pair, format!("Unexpected {:?}", r))), - } - } - }; -} +// macro_rules! match_rule { +// ($pair:expr; $($pat:pat => $submac:ident!( $($args:tt)* ),)*) => { +// { +// #[allow(unreachable_patterns)] +// match $pair.as_rule() { +// $( +// $pat => $submac!($pair; $($args)*), +// )* +// r => Err(custom_parse_error(&$pair, format!("Unexpected {:?}", r))), +// } +// } +// }; +// } // List of rules that can be shortcutted as implemented in binop!() fn can_be_shortcutted(rule: Rule) -> bool { @@ -448,15 +514,14 @@ macro_rules! binop { }; } - -make_parser!{ +make_parser! { rule!(EOI<()>; children!() => ()); -named!(str<&'a str>; captured_str!(s) => s.trim()); +// named!(str<&'a str>; captured_str!(s) => s.trim()); -named!(raw_str<&'a str>; captured_str!(s) => s); +// named!(raw_str<&'a str>; captured_str!(s) => s); -named!(label