summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2019-09-10 15:04:26 +0200
committerNadrieril2019-09-10 15:04:26 +0200
commite4003cc25efcae79c1332e3481d7edfca1067c4f (patch)
treeb6fc119338bc6c17649356969acfbedde9482314
parent9f41dc5a4680cba3697c64da28855c8d4f437191 (diff)
Allows using match_inputs outside of a make_parser impl
-rw-r--r--dhall_syntax/src/parser.rs32
-rw-r--r--pest_consume_macros/src/make_parser.rs15
-rw-r--r--pest_consume_macros/src/match_inputs.rs28
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)