summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhall_syntax/src/parser.rs20
-rw-r--r--pest_consume/src/lib.rs42
2 files changed, 47 insertions, 15 deletions
diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs
index 761795a..15515f0 100644
--- a/dhall_syntax/src/parser.rs
+++ b/dhall_syntax/src/parser.rs
@@ -21,6 +21,8 @@ type ParsedText<E> = InterpolatedText<Expr<E>>;
type ParsedTextContents<E> = InterpolatedTextContents<Expr<E>>;
type ParseInput<'input, 'data> =
pest_consume::ParseInput<'input, 'data, Rule, Rc<str>>;
+type ParseInputs<'input, 'data> =
+ pest_consume::ParseInputs<'input, 'data, Rule, Rc<str>>;
pub type ParseError = pest::error::Error<Rule>;
pub type ParseResult<T> = Result<T, ParseError>;
@@ -152,6 +154,15 @@ struct Parsers;
#[make_parser(Rule)]
impl Parsers {
+ fn entrypoint<E: Clone>(input_str: &str) -> ParseResult<Expr<E>> {
+ let pairs = DhallParser::parse(Rule::final_expression, input_str)?;
+ let rc_input_str = input_str.to_string().into();
+ let inputs = ParseInputs::new(input_str, pairs, &rc_input_str);
+ Ok(match_inputs!(inputs;
+ [expression(e)] => e,
+ ))
+ }
+
fn EOI(_input: ParseInput) -> ParseResult<()> {
Ok(())
}
@@ -939,6 +950,7 @@ impl Parsers {
))
}
+ #[alias(expression)]
fn final_expression<E: Clone>(input: ParseInput) -> ParseResult<Expr<E>> {
Ok(match_inputs!(input.children();
[expression(e), EOI(_)] => e
@@ -947,11 +959,5 @@ impl Parsers {
}
pub fn parse_expr<E: Clone>(input_str: &str) -> ParseResult<Expr<E>> {
- let mut pairs = DhallParser::parse(Rule::final_expression, input_str)?;
- // TODO: proper errors
- let pair = pairs.next().unwrap();
- assert_eq!(pairs.next(), None);
- let rc_input_str = input_str.to_string().into();
- let input = ParseInput::new(pair, &rc_input_str);
- Parsers::final_expression(input)
+ Parsers::entrypoint(input_str)
}
diff --git a/pest_consume/src/lib.rs b/pest_consume/src/lib.rs
index 1a7d4f2..d97c905 100644
--- a/pest_consume/src/lib.rs
+++ b/pest_consume/src/lib.rs
@@ -1,5 +1,5 @@
use pest::error::{Error, ErrorVariant};
-use pest::iterators::Pair;
+use pest::iterators::{Pair, Pairs};
use pest::Span;
pub use pest_consume_macros::{make_parser, match_inputs};
@@ -20,8 +20,9 @@ pub struct ParseInputs<'input, 'data, Rule, Data>
where
Rule: pest::RuleType,
{
- input: ParseInput<'input, 'data, Rule, Data>,
- pairs: pest::iterators::Pairs<'input, Rule>,
+ pairs: Pairs<'input, Rule>,
+ span: Span<'input>,
+ user_data: &'data Data,
}
impl<'input, 'data, Rule, Data> ParseInput<'input, 'data, Rule, Data>
@@ -60,8 +61,9 @@ where
// (see https://github.com/rust-lang/rust/issues/61997).
pub fn children(&self) -> ParseInputs<'input, 'data, Rule, Data> {
ParseInputs {
- input: self.clone(),
pairs: self.as_pair().clone().into_inner(),
+ span: self.as_span(),
+ user_data: self.user_data(),
}
}
@@ -92,9 +94,25 @@ impl<'input, 'data, Rule, Data> ParseInputs<'input, 'data, Rule, Data>
where
Rule: pest::RuleType,
{
+ /// `input` must be the _original_ input that `pairs` is pointing to.
+ pub fn new(
+ input: &'input str,
+ pairs: Pairs<'input, Rule>,
+ user_data: &'data Data,
+ ) -> Self {
+ let span = Span::new(input, 0, input.len()).unwrap();
+ ParseInputs {
+ pairs,
+ span,
+ user_data,
+ }
+ }
/// Create an error that points to the span of the input.
pub fn error(&self, message: String) -> Error<Rule> {
- self.input.error(message)
+ Error::new_from_span(
+ ErrorVariant::CustomError { message },
+ self.span.clone(),
+ )
}
pub fn aliased_rules<T>(&self) -> Vec<String>
where
@@ -102,6 +120,13 @@ where
{
self.clone().map(|p| p.as_rule_alias::<T>()).collect()
}
+ /// Reconstruct the input with a new pair, passing the user data along.
+ fn with_pair(
+ &self,
+ new_pair: Pair<'input, Rule>,
+ ) -> ParseInput<'input, 'data, Rule, Data> {
+ ParseInput::new(new_pair, self.user_data)
+ }
}
/// Used by the macros.
@@ -120,7 +145,7 @@ where
fn next(&mut self) -> Option<Self::Item> {
let child_pair = self.pairs.next()?;
- let child = self.input.with_pair(child_pair);
+ let child = self.with_pair(child_pair);
Some(child)
}
}
@@ -132,7 +157,7 @@ where
{
fn next_back(&mut self) -> Option<Self::Item> {
let child_pair = self.pairs.next_back()?;
- let child = self.input.with_pair(child_pair);
+ let child = self.with_pair(child_pair);
Some(child)
}
}
@@ -157,8 +182,9 @@ where
{
fn clone(&self) -> Self {
ParseInputs {
- input: self.input.clone(),
pairs: self.pairs.clone(),
+ span: self.span.clone(),
+ user_data: self.user_data,
}
}
}