From 595a52018e31126ecbf1be49794750f1a59a66b1 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 9 Sep 2019 22:24:27 +0200 Subject: Move pest_consume into its own crate --- Cargo.lock | 9 ++++ Cargo.toml | 1 + dhall_syntax/Cargo.toml | 1 + dhall_syntax/src/parser.rs | 132 ++------------------------------------------- pest_consume/Cargo.toml | 13 +++++ pest_consume/src/lib.rs | 123 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 129 deletions(-) create mode 100644 pest_consume/Cargo.toml create mode 100644 pest_consume/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d5ce864..b9ca159 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,6 +117,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_consume 0.1.0", "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -237,6 +238,14 @@ dependencies = [ "ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pest_consume" +version = "0.1.0" +dependencies = [ + "dhall_proc_macros 0.1.0", + "pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pest_generator" version = "2.1.1" diff --git a/Cargo.toml b/Cargo.toml index 1e40748..b26b5c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "dhall_syntax", "dhall_proc_macros", "improved_slice_patterns", + "pest_consume", "serde_dhall" ] diff --git a/dhall_syntax/Cargo.toml b/dhall_syntax/Cargo.toml index eb492d0..450175c 100644 --- a/dhall_syntax/Cargo.toml +++ b/dhall_syntax/Cargo.toml @@ -18,3 +18,4 @@ hex = "0.3.2" lazy_static = "1.4.0" dhall_generated_parser = { path = "../dhall_generated_parser" } dhall_proc_macros = { path = "../dhall_proc_macros" } +pest_consume = { path = "../pest_consume" } diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs index c8b3fe6..6c47de4 100644 --- a/dhall_syntax/src/parser.rs +++ b/dhall_syntax/src/parser.rs @@ -6,7 +6,7 @@ use pest::Parser; use std::rc::Rc; use dhall_generated_parser::{DhallParser, Rule}; -use dhall_proc_macros::{make_parser, parse_children}; +use pest_consume::{make_parser, parse_children}; use crate::map::{DupTreeMap, DupTreeSet}; use crate::ExprF::*; @@ -19,138 +19,12 @@ use crate::*; type ParsedText = InterpolatedText>; type ParsedTextContents = InterpolatedTextContents>; +type ParseInput<'input, 'data> = + pest_consume::ParseInput<'input, 'data, Rule, Rc>; pub type ParseError = pest::error::Error; - pub type ParseResult = Result; -pub mod pest_consume { - use pest::error::{Error, ErrorVariant}; - use pest::iterators::Pair; - use pest::Span; - - /// Carries a pest Pair alongside custom user data. - #[derive(Debug, Clone)] - pub struct ParseInput<'input, 'data, Rule, Data> - where - Rule: pest::RuleType, - { - pair: Pair<'input, Rule>, - user_data: &'data Data, - } - - impl<'input, 'data, Rule, Data> ParseInput<'input, 'data, Rule, Data> - where - Rule: pest::RuleType, - { - pub fn new(pair: Pair<'input, Rule>, user_data: &'data Data) -> Self { - ParseInput { pair, user_data } - } - /// Create an error that points to the span of the input. - pub fn error(&self, message: String) -> Error { - let message = format!( - "{} while matching on:\n{}", - message, - debug_pair(self.pair.clone()) - ); - Error::new_from_span( - ErrorVariant::CustomError { message }, - self.as_span(), - ) - } - /// Reconstruct the input with a new pair, passing the user data along. - pub fn with_pair(&self, new_pair: Pair<'input, Rule>) -> Self { - ParseInput { - pair: new_pair, - user_data: self.user_data, - } - } - /// If the contained pair has exactly one child, return a new Self containing it. - pub fn single_child(&self) -> Option { - let mut children = self.pair.clone().into_inner(); - if let Some(child) = children.next() { - if children.next().is_none() { - return Some(self.with_pair(child)); - } - } - None - } - - pub fn user_data(&self) -> &'data Data { - self.user_data - } - pub fn as_pair(&self) -> &Pair<'input, Rule> { - &self.pair - } - pub fn as_span(&self) -> Span<'input> { - self.pair.as_span() - } - pub fn as_str(&self) -> &'input str { - self.pair.as_str() - } - pub fn as_rule(&self) -> Rule { - self.pair.as_rule() - } - } - - /// Used by the macros. - pub trait PestConsumer { - type Rule: pest::RuleType; - fn rule_alias(rule: Self::Rule) -> String; - fn allows_shortcut(rule: Self::Rule) -> bool; - } - - /// Pretty-print a pair and its nested children. - fn debug_pair(pair: Pair) -> String { - use std::fmt::Write; - let mut s = String::new(); - fn aux( - s: &mut String, - indent: usize, - prefix: String, - pair: Pair, - ) { - let indent_str = "| ".repeat(indent); - let rule = pair.as_rule(); - let contents = pair.as_str(); - let mut inner = pair.into_inner(); - let mut first = true; - while let Some(p) = inner.next() { - if first { - first = false; - let last = inner.peek().is_none(); - if last && p.as_str() == contents { - let prefix = format!("{}{:?} > ", prefix, rule); - aux(s, indent, prefix, p); - continue; - } else { - writeln!( - s, - r#"{}{}{:?}: "{}""#, - indent_str, prefix, rule, contents - ) - .unwrap(); - } - } - aux(s, indent + 1, "".into(), p); - } - if first { - writeln!( - s, - r#"{}{}{:?}: "{}""#, - indent_str, prefix, rule, contents - ) - .unwrap(); - } - } - aux(&mut s, 0, "".into(), pair); - s - } -} - -type ParseInput<'input, 'data> = - pest_consume::ParseInput<'input, 'data, Rule, Rc>; - #[derive(Debug)] enum Either { Left(A), diff --git a/pest_consume/Cargo.toml b/pest_consume/Cargo.toml new file mode 100644 index 0000000..b3f1db7 --- /dev/null +++ b/pest_consume/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "pest_consume" +version = "0.1.0" # remember to update html_root_url +authors = ["Nadrieril "] +license = "MIT OR Apache-2.0" +edition = "2018" +description = "A framework for processing the output of a pest-generated parser" +readme = "README.md" +repository = "https://github.com/Nadrieril/dhall-rust" + +[dependencies] +pest = "2.1" +dhall_proc_macros = { path = "../dhall_proc_macros" } diff --git a/pest_consume/src/lib.rs b/pest_consume/src/lib.rs new file mode 100644 index 0000000..1cedc74 --- /dev/null +++ b/pest_consume/src/lib.rs @@ -0,0 +1,123 @@ +use pest::error::{Error, ErrorVariant}; +use pest::iterators::Pair; +use pest::Span; + +pub use dhall_proc_macros::{make_parser, parse_children}; + +/// Carries a pest Pair alongside custom user data. +#[derive(Debug, Clone)] +pub struct ParseInput<'input, 'data, Rule, Data> +where + Rule: pest::RuleType, +{ + pair: Pair<'input, Rule>, + user_data: &'data Data, +} + +impl<'input, 'data, Rule, Data> ParseInput<'input, 'data, Rule, Data> +where + Rule: pest::RuleType, +{ + pub fn new(pair: Pair<'input, Rule>, user_data: &'data Data) -> Self { + ParseInput { pair, user_data } + } + /// Create an error that points to the span of the input. + pub fn error(&self, message: String) -> Error { + let message = format!( + "{} while matching on:\n{}", + message, + debug_pair(self.pair.clone()) + ); + Error::new_from_span( + ErrorVariant::CustomError { message }, + self.as_span(), + ) + } + /// Reconstruct the input with a new pair, passing the user data along. + pub fn with_pair(&self, new_pair: Pair<'input, Rule>) -> Self { + ParseInput { + pair: new_pair, + user_data: self.user_data, + } + } + /// If the contained pair has exactly one child, return a new Self containing it. + pub fn single_child(&self) -> Option { + let mut children = self.pair.clone().into_inner(); + if let Some(child) = children.next() { + if children.next().is_none() { + return Some(self.with_pair(child)); + } + } + None + } + + pub fn user_data(&self) -> &'data Data { + self.user_data + } + pub fn as_pair(&self) -> &Pair<'input, Rule> { + &self.pair + } + pub fn as_span(&self) -> Span<'input> { + self.pair.as_span() + } + pub fn as_str(&self) -> &'input str { + self.pair.as_str() + } + pub fn as_rule(&self) -> Rule { + self.pair.as_rule() + } +} + +/// Used by the macros. +pub trait PestConsumer { + type Rule: pest::RuleType; + fn rule_alias(rule: Self::Rule) -> String; + fn allows_shortcut(rule: Self::Rule) -> bool; +} + +/// Pretty-print a pair and its nested children. +fn debug_pair(pair: Pair) -> String { + use std::fmt::Write; + let mut s = String::new(); + fn aux( + s: &mut String, + indent: usize, + prefix: String, + pair: Pair, + ) { + let indent_str = "| ".repeat(indent); + let rule = pair.as_rule(); + let contents = pair.as_str(); + let mut inner = pair.into_inner(); + let mut first = true; + while let Some(p) = inner.next() { + if first { + first = false; + let last = inner.peek().is_none(); + if last && p.as_str() == contents { + let prefix = format!("{}{:?} > ", prefix, rule); + aux(s, indent, prefix, p); + continue; + } else { + writeln!( + s, + r#"{}{}{:?}: "{}""#, + indent_str, prefix, rule, contents + ) + .unwrap(); + } + } + aux(s, indent + 1, "".into(), p); + } + if first { + writeln!( + s, + r#"{}{}{:?}: "{}""#, + indent_str, prefix, rule, contents + ) + .unwrap(); + } + } + aux(&mut s, 0, "".into(), pair); + s +} -- cgit v1.2.3