From 7d40b8ae24cdf888efbf4d2ce1442561941bac13 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 10 Dec 2022 23:49:02 -0500 Subject: [PATCH] Attempt to put two lifetimes in the context. --- src/parser/mod.rs | 2 +- src/parser/nom_context.rs | 22 +++++++++++----------- src/parser/text_element_parser.rs | 29 ++++++++++++++++------------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 0b76a1c5..3361c109 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5,4 +5,4 @@ mod text; mod text_element_parser; mod token; pub use text_element_parser::document; -type Context<'r> = &'r nom_context::ContextTree<'r>; +type Context<'r, 's> = &'r nom_context::ContextTree<'r, 's>; diff --git a/src/parser/nom_context.rs b/src/parser/nom_context.rs index 5e470436..0b579bf9 100644 --- a/src/parser/nom_context.rs +++ b/src/parser/nom_context.rs @@ -9,33 +9,33 @@ use super::token::Token; type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; #[derive(Debug, Clone)] -pub struct ContextTree<'r> { - tree: List>, +pub struct ContextTree<'r, 's> { + tree: List>, } -impl<'r> ContextTree<'r> { +impl<'r, 's> ContextTree<'r, 's> { pub fn new() -> Self { ContextTree { tree: List::new() } } - pub fn ptr_eq<'x>(&self, other: &ContextTree<'x>) -> bool { + pub fn ptr_eq<'x, 'y>(&self, other: &ContextTree<'x, 'y>) -> bool { self.tree.ptr_eq(&other.tree) } - pub fn with_additional_node(&self, data: ContextElement<'r>) -> ContextTree<'r> { + pub fn with_additional_node(&self, data: ContextElement<'r, 's>) -> ContextTree<'r, 's> { let new_list = self.tree.push_front(data); ContextTree { tree: new_list } } - pub fn pop_front(&mut self) -> (Option>, ContextTree<'r>) { + pub fn pop_front(&mut self) -> (Option>, ContextTree<'r, 's>) { // todo todo!() } - pub fn check_fail_matcher<'s>( + pub fn check_fail_matcher<'b>( &'r self, - i: &'s str, - ) -> IResult<&'s str, &'s str, VerboseError<&'s str>> { + i: &'b str, + ) -> IResult<&'b str, &'b str, VerboseError<&'b str>> { // TODO: Can I do this without incrementing reference counters? Perhaps via implementing an iterator over the list? let mut current_node = self.tree.clone(); while !current_node.is_empty() { @@ -79,9 +79,9 @@ impl<'r> ContextTree<'r> { } #[derive(Debug)] -pub enum ContextElement<'r> { +pub enum ContextElement<'r, 's> { FailMatcherNode(FailMatcherNode<'r>), - PreviousElementNode(PreviousElementNode<'r>), + PreviousElementNode(PreviousElementNode<'s>), } #[derive(Debug)] diff --git a/src/parser/text_element_parser.rs b/src/parser/text_element_parser.rs index 3917baff..a2c760e5 100644 --- a/src/parser/text_element_parser.rs +++ b/src/parser/text_element_parser.rs @@ -41,19 +41,19 @@ use nom::Parser; use tracing::instrument; use tracing::trace; -type UnboundMatcher<'r, I, O, E> = dyn Fn(Context<'r>, I) -> IResult; +type UnboundMatcher<'r, 's, I, O, E> = dyn Fn(Context<'r, 's>, I) -> IResult; -fn context_many_till<'r: 'x, 'x, I, O, E, F, M, T>( - context: Context<'r>, +fn context_many_till<'r, 's, I, O, E, F, M, T>( + context: Context<'r, 's>, mut many_matcher: M, mut till_matcher: T, -) -> impl FnMut(I) -> IResult>, F), E> +) -> impl FnMut(I) -> IResult>, F), E> + 'r where I: Clone + InputLength, E: ParseError, - M: for<'a> Fn(Context<'a>, I) -> IResult, - T: for<'a> Fn(Context<'a>, I) -> IResult, - O: Into>, + M: Fn(Context<'r, 's>, I) -> IResult + 'r, + T: Fn(Context<'r, 's>, I) -> IResult + 'r, + O: Into>, { move |mut i: I| { let mut current_context = context.clone(); @@ -109,21 +109,21 @@ where } pub fn document(input: &str) -> Res<&str, Vec<(Vec, &str)>> { - let initial_context: ContextTree<'_> = ContextTree::new(); + let initial_context: ContextTree<'_, '_> = ContextTree::new(); let paragraph_parser = parser_with_context!(paragraph); let ret = many1(paragraph_parser(initial_context))(input); ret } pub fn context_paragraph_end<'s, 'r>( - context: Context<'r>, + context: Context<'r, 's>, input: &'s str, ) -> Res<&'s str, &'s str> { paragraph_end(input) } pub fn paragraph<'s, 'r>( - context: Context<'r>, + context: Context<'r, 's>, i: &'s str, ) -> Res<&'s str, (Vec>, &'s str)> { // Add a not(eof) check because many_till cannot match a zero-length string @@ -144,7 +144,10 @@ pub fn paragraph<'s, 'r>( todo!() } -fn flat_text_element<'s, 'r>(context: Context<'r>, i: &'s str) -> Res<&'s str, TextElement<'s>> { +fn flat_text_element<'s, 'r>( + context: Context<'r, 's>, + i: &'s str, +) -> Res<&'s str, TextElement<'s>> { not(|i| context.check_fail_matcher(i))(i)?; let bold_matcher = parser_with_context!(flat_bold)(context.clone()); @@ -166,7 +169,7 @@ fn recognize_bold_end(input: &str) -> Res<&str, &str> { recognize(bold_end)(input) } -fn flat_bold<'s, 'r>(context: Context<'r>, i: &'s str) -> Res<&'s str, Bold<'s>> { +fn flat_bold<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Bold<'s>> { let nom_context = context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { fail_matcher: ChainBehavior::AndParent(Some(&recognize_bold_end)), @@ -185,7 +188,7 @@ fn recognize_link_end(input: &str) -> Res<&str, &str> { recognize(link_end)(input) } -fn flat_link<'s, 'r>(context: Context<'r>, i: &'s str) -> Res<&'s str, Link<'s>> { +fn flat_link<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Link<'s>> { let nom_context = context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { fail_matcher: ChainBehavior::AndParent(Some(&recognize_link_end)),