From be51899f7d5f1f9ede689ca0a9707a0aca3d31c4 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 1 Sep 2019 13:51:12 +0200 Subject: Rewrite the make_parser macro as a proc_macro --- dhall_syntax/Cargo.toml | 1 + dhall_syntax/src/parser.rs | 209 ++------------------------------------------- 2 files changed, 7 insertions(+), 203 deletions(-) (limited to 'dhall_syntax') diff --git a/dhall_syntax/Cargo.toml b/dhall_syntax/Cargo.toml index 1da10c7..62ecced 100644 --- a/dhall_syntax/Cargo.toml +++ b/dhall_syntax/Cargo.toml @@ -16,3 +16,4 @@ either = "1.5.2" take_mut = "0.2.2" hex = "0.3.2" dhall_generated_parser = { path = "../dhall_generated_parser" } +dhall_proc_macros = { path = "../dhall_proc_macros" } diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs index 53fd68a..4fd6f57 100644 --- a/dhall_syntax/src/parser.rs +++ b/dhall_syntax/src/parser.rs @@ -189,203 +189,6 @@ macro_rules! parse_children { }; } -macro_rules! make_parser { - (@children_pattern, - $varpat:ident, - ($($acc:tt)*), - [$variant:ident ($x:pat), $($rest:tt)*] - ) => ( - make_parser!(@children_pattern, - $varpat, - ($($acc)* , Rule::$variant), - [$($rest)*] - ) - ); - (@children_pattern, - $varpat:ident, - ($($acc:tt)*), - [$variant:ident ($x:ident).., $($rest:tt)*] - ) => ( - make_parser!(@children_pattern, - $varpat, - ($($acc)* , $varpat..), - [$($rest)*] - ) - ); - (@children_pattern, - $varpat:ident, - (, $($acc:tt)*), [$(,)*] - ) => ([$($acc)*]); - (@children_pattern, - $varpat:ident, - ($($acc:tt)*), [$(,)*] - ) => ([$($acc)*]); - - (@children_filter, - $varpat:ident, - [$variant:ident ($x:pat), $($rest:tt)*] - ) => ( - make_parser!(@children_filter, $varpat, [$($rest)*]) - ); - (@children_filter, - $varpat:ident, - [$variant:ident ($x:ident).., $($rest:tt)*] - ) => ( - $varpat.iter().all(|r| r == &Rule::$variant) && - make_parser!(@children_filter, $varpat, [$($rest)*]) - ); - (@children_filter, $varpat:ident, [$(,)*]) => (true); - - (@body, - ($climbers:expr, $input:expr, $pair:expr), - rule!( - $name:ident<$o:ty>; - $span:ident; - captured_str!($x:pat) => $body:expr - ) - ) => ({ - let $span = Span::make($input.clone(), $pair.as_span()); - let $x = $pair.as_str(); - let res: Result<_, String> = try { $body }; - res.map_err(|msg| custom_parse_error(&$pair, msg)) - }); - (@body, - ($climbers:expr, $input:expr, $pair:expr), - rule!( - $name:ident<$o:ty>; - $span:ident; - children!( $( [$($args:tt)*] => $body:expr ),* $(,)* ) - ) - ) => ({ - let children_rules: Vec = $pair - .clone() - .into_inner() - .map(|p| p.as_rule()) - .collect(); - - let $span = Span::make($input.clone(), $pair.as_span()); - #[allow(unused_mut)] - let mut iter = $pair.clone().into_inner(); - - #[allow(unreachable_code)] - match children_rules.as_slice() { - $( - make_parser!(@children_pattern, x, (), [$($args)*,]) - if make_parser!(@children_filter, x, [$($args)*,]) - => { - parse_children!(($climbers, $input.clone()), iter; - [$($args)*] => { - let res: Result<_, String> = try { $body }; - res.map_err(|msg| custom_parse_error(&$pair, msg)) - } - ) - } - , - )* - [..] => Err(custom_parse_error( - &$pair, - format!("Unexpected children: {:?}", children_rules) - )), - } - }); - (@body, - ($climbers:expr, $input:expr, $pair:expr), - rule!( - $name:ident<$o:ty>; - prec_climb!( - $other_rule:ident, - $_climber:expr, - $args:pat => $body:expr $(,)* - ) - ) - ) => ({ - let climber = $climbers.get(&Rule::$name).unwrap(); - climber.climb( - $pair.clone().into_inner(), - |p| Parsers::$other_rule(($climbers, $input.clone()), p), - |l, op, r| { - let $args = (l?, op, r?); - let res: Result<_, String> = try { $body }; - res.map_err(|msg| custom_parse_error(&$pair, msg)) - }, - ) - }); - (@body, - ($($things:tt)*), - rule!( - $name:ident<$o:ty>; - $($args:tt)* - ) - ) => ({ - make_parser!(@body, - ($($things)*), - rule!( - $name<$o>; - _span; - $($args)* - ) - ) - }); - (@body, - ($($things:tt)*), - rule!($name:ident<$o:ty>) - ) => ({ - Ok(()) - }); - - (@construct_climber, - ($map:expr), - rule!( - $name:ident<$o:ty>; - prec_climb!($other_rule:ident, $climber:expr, $($_rest:tt)* ) - ) - ) => ({ - $map.insert(Rule::$name, $climber) - }); - (@construct_climber, ($($things:tt)*), $($args:tt)*) => (()); - - ($( $submac:ident!( $name:ident<$o:ty> $($args:tt)* ); )*) => ( - struct Parsers; - - impl Parsers { - $( - #[allow(non_snake_case, unused_variables, clippy::let_unit_value)] - fn $name<'a>( - (climbers, input): (&HashMap>, Rc), - pair: Pair<'a, Rule>, - ) -> ParseResult<$o> { - make_parser!(@body, (climbers, input, pair), - $submac!( $name<$o> $($args)* )) - } - )* - } - - fn construct_precclimbers() -> HashMap> { - let mut map = HashMap::new(); - $( - make_parser!(@construct_climber, (map), - $submac!( $name<$o> $($args)* )); - )* - map - } - - struct EntryPoint; - - impl EntryPoint { - $( - #[allow(non_snake_case, dead_code)] - fn $name<'a>( - input: Rc, - pair: Pair<'a, Rule>, - ) -> ParseResult<$o> { - let climbers = construct_precclimbers(); - Parsers::$name((&climbers, input), pair) - } - )* - } - ); -} - // Trim the shared indent off of a vec of lines, as defined by the Dhall semantics of multiline // literals. fn trim_indent(lines: &mut Vec) { @@ -427,7 +230,7 @@ fn trim_indent(lines: &mut Vec) { } } -make_parser! { +dhall_proc_macros::make_parser! { rule!(EOI<()>); rule!(simple_label