Attempt to put two lifetimes in the context.
This commit is contained in:
parent
75ab876b0b
commit
7d40b8ae24
@ -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>;
|
||||
|
@ -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)]
|
||||
|
@ -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)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user