diff options
-rw-r--r-- | dhall_syntax/src/parser.rs | 32 | ||||
-rw-r--r-- | pest_consume_macros/src/make_parser.rs | 15 | ||||
-rw-r--r-- | pest_consume_macros/src/match_inputs.rs | 28 |
3 files changed, 40 insertions, 35 deletions
diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs index a783f77..0d529bc 100644 --- a/dhall_syntax/src/parser.rs +++ b/dhall_syntax/src/parser.rs @@ -4,7 +4,8 @@ use pest::prec_climber as pcl; use pest::prec_climber::PrecClimber; use std::rc::Rc; -use dhall_generated_parser::{DhallParser, Rule}; +use dgp::Rule; +use dhall_generated_parser as dgp; use pest_consume::{make_parser, match_inputs, PestConsumer}; use crate::map::{DupTreeMap, DupTreeSet}; @@ -147,23 +148,10 @@ lazy_static::lazy_static! { }; } -struct Parsers; - -#[make_parser(DhallParser, Rule)] -impl Parsers { - #[entrypoint] - fn entrypoint<E: Clone>(input_str: &str) -> ParseResult<Expr<E>> { - let rc_input_str = input_str.to_string().into(); - let inputs = Self::parse_with_userdata( - Rule::final_expression, - input_str, - &rc_input_str, - )?; - Ok(match_inputs!(inputs; - [expression(e)] => e, - )) - } +struct DhallParser; +#[make_parser(dgp::DhallParser, dgp::Rule)] +impl DhallParser { fn EOI(_input: ParseInput) -> ParseResult<()> { Ok(()) } @@ -960,5 +948,13 @@ impl Parsers { } pub fn parse_expr<E: Clone>(input_str: &str) -> ParseResult<Expr<E>> { - Parsers::entrypoint(input_str) + let rc_input_str = input_str.to_string().into(); + let inputs = DhallParser::parse_with_userdata( + Rule::final_expression, + input_str, + &rc_input_str, + )?; + Ok(match_inputs!(<DhallParser>; inputs; + [expression(e)] => e, + )) } diff --git a/pest_consume_macros/src/make_parser.rs b/pest_consume_macros/src/make_parser.rs index 0638c19..8a15deb 100644 --- a/pest_consume_macros/src/make_parser.rs +++ b/pest_consume_macros/src/make_parser.rs @@ -6,7 +6,7 @@ use syn::parse::{Parse, ParseStream, Result}; use syn::spanned::Spanned; use syn::{ parse_quote, Error, Expr, FnArg, Ident, ImplItem, ImplItemMethod, ItemImpl, - LitBool, Pat, Token, + LitBool, Pat, Path, Token, }; mod kw { @@ -14,8 +14,8 @@ mod kw { } struct MakeParserAttrs { - parser: Ident, - rule_enum: Ident, + parser: Path, + rule_enum: Path, } struct AliasArgs { @@ -159,7 +159,7 @@ fn parse_fn<'a>( }) } -fn apply_special_attrs(f: &mut ParsedFn, rule_enum: &Ident) -> Result<()> { +fn apply_special_attrs(f: &mut ParsedFn, rule_enum: &Path) -> Result<()> { let function = &mut *f.function; let fn_name = &f.fn_name; let input_arg = &f.input_arg; @@ -170,13 +170,6 @@ fn apply_special_attrs(f: &mut ParsedFn, rule_enum: &Ident) -> Result<()> { ); // `prec_climb` attr - let _: () = function - .attrs - .drain_filter(|attr| attr.path.is_ident("entrypoint")) - .map(|_| ()) - .collect(); - - // `prec_climb` attr let prec_climb_attrs: Vec<_> = function .attrs .drain_filter(|attr| attr.path.is_ident("prec_climb")) diff --git a/pest_consume_macros/src/match_inputs.rs b/pest_consume_macros/src/match_inputs.rs index 3a325a6..d4bc492 100644 --- a/pest_consume_macros/src/match_inputs.rs +++ b/pest_consume_macros/src/match_inputs.rs @@ -3,7 +3,10 @@ use quote::quote; use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::{bracketed, parenthesized, token, Error, Expr, Ident, Pat, Token}; +use syn::{ + bracketed, parenthesized, parse_quote, token, Error, Expr, Ident, Pat, + Token, Type, +}; #[derive(Debug, Clone)] struct ChildrenBranch { @@ -20,6 +23,7 @@ enum ChildrenBranchPatternItem { #[derive(Debug, Clone)] struct ParseChildrenInput { + consumer: Type, input_expr: Expr, branches: Punctuated<ChildrenBranch, Token![,]>, } @@ -62,11 +66,21 @@ impl Parse for ChildrenBranchPatternItem { impl Parse for ParseChildrenInput { fn parse(input: ParseStream) -> Result<Self> { + let consumer = if input.peek(token::Lt) { + let _: token::Lt = input.parse()?; + let consumer = input.parse()?; + let _: token::Gt = input.parse()?; + let _: Token![;] = input.parse()?; + consumer + } else { + parse_quote!(Self) + }; let input_expr = input.parse()?; let _: Token![;] = input.parse()?; let branches = Punctuated::parse_terminated(input)?; Ok(ParseChildrenInput { + consumer, input_expr, branches, }) @@ -76,6 +90,7 @@ impl Parse for ParseChildrenInput { fn make_parser_branch( branch: &ChildrenBranch, i_inputs: &Ident, + consumer: &Type, ) -> Result<TokenStream> { use ChildrenBranchPatternItem::{Multiple, Single}; @@ -139,7 +154,7 @@ fn make_parser_branch( let mut parses = Vec::new(); for (rule_name, binder) in singles_before_multiple.into_iter() { parses.push(quote!( - let #binder = Self::#rule_name( + let #binder = #consumer::#rule_name( #i_inputs.next().unwrap() )?; )) @@ -148,7 +163,7 @@ fn make_parser_branch( // only the unmatched inputs are left for the variable-length pattern, if any. for (rule_name, binder) in singles_after_multiple.into_iter().rev() { parses.push(quote!( - let #binder = Self::#rule_name( + let #binder = #consumer::#rule_name( #i_inputs.next_back().unwrap() )?; )) @@ -156,7 +171,7 @@ fn make_parser_branch( if let Some((rule_name, binder)) = multiple { parses.push(quote!( let #binder = #i_inputs - .map(|i| Self::#rule_name(i)) + .map(|i| #consumer::#rule_name(i)) .collect::<Result<Vec<_>, _>>()? .into_iter(); )) @@ -179,17 +194,18 @@ pub fn match_inputs( let i_inputs = Ident::new("___inputs", Span::call_site()); let input_expr = &input.input_expr; + let consumer = &input.consumer; let branches = input .branches .iter() - .map(|br| make_parser_branch(br, &i_inputs)) + .map(|br| make_parser_branch(br, &i_inputs, consumer)) .collect::<Result<Vec<_>>>()?; Ok(quote!({ #[allow(unused_mut)] let mut #i_inputs = #input_expr; - let #i_input_rules = #i_inputs.aliased_rules::<Self>(); + let #i_input_rules = #i_inputs.aliased_rules::<#consumer>(); let #i_input_rules: Vec<&str> = #i_input_rules .iter() .map(String::as_str) |