Attempt to put two lifetimes in the context.

This commit is contained in:
Tom Alexander 2022-12-10 23:49:02 -05:00
parent 75ab876b0b
commit 7d40b8ae24
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 28 additions and 25 deletions

View File

@ -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>;

View File

@ -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<ContextElement<'r>>,
pub struct ContextTree<'r, 's> {
tree: List<ContextElement<'r, 's>>,
}
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<ContextElement<'r>>, ContextTree<'r>) {
pub fn pop_front(&mut self) -> (Option<ContextElement<'r, 's>>, 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)]

View File

@ -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<I, O, E>;
type UnboundMatcher<'r, 's, I, O, E> = dyn Fn(Context<'r, 's>, I) -> IResult<I, O, E>;
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<I, (Vec<Token<'x>>, F), E>
) -> impl FnMut(I) -> IResult<I, (Vec<Token<'s>>, F), E> + 'r
where
I: Clone + InputLength,
E: ParseError<I>,
M: for<'a> Fn(Context<'a>, I) -> IResult<I, O, E>,
T: for<'a> Fn(Context<'a>, I) -> IResult<I, F, E>,
O: Into<Token<'x>>,
M: Fn(Context<'r, 's>, I) -> IResult<I, O, E> + 'r,
T: Fn(Context<'r, 's>, I) -> IResult<I, F, E> + 'r,
O: Into<Token<'s>>,
{
move |mut i: I| {
let mut current_context = context.clone();
@ -109,21 +109,21 @@ where
}
pub fn document(input: &str) -> Res<&str, Vec<(Vec<TextElement>, &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<TextElement<'s>>, &'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)),