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 text_element_parser;
|
||||||
mod token;
|
mod token;
|
||||||
pub use text_element_parser::document;
|
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>>;
|
type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ContextTree<'r> {
|
pub struct ContextTree<'r, 's> {
|
||||||
tree: List<ContextElement<'r>>,
|
tree: List<ContextElement<'r, 's>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> ContextTree<'r> {
|
impl<'r, 's> ContextTree<'r, 's> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ContextTree { tree: List::new() }
|
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)
|
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);
|
let new_list = self.tree.push_front(data);
|
||||||
ContextTree { tree: new_list }
|
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
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_fail_matcher<'s>(
|
pub fn check_fail_matcher<'b>(
|
||||||
&'r self,
|
&'r self,
|
||||||
i: &'s str,
|
i: &'b str,
|
||||||
) -> IResult<&'s str, &'s str, VerboseError<&'s 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?
|
// TODO: Can I do this without incrementing reference counters? Perhaps via implementing an iterator over the list?
|
||||||
let mut current_node = self.tree.clone();
|
let mut current_node = self.tree.clone();
|
||||||
while !current_node.is_empty() {
|
while !current_node.is_empty() {
|
||||||
@ -79,9 +79,9 @@ impl<'r> ContextTree<'r> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ContextElement<'r> {
|
pub enum ContextElement<'r, 's> {
|
||||||
FailMatcherNode(FailMatcherNode<'r>),
|
FailMatcherNode(FailMatcherNode<'r>),
|
||||||
PreviousElementNode(PreviousElementNode<'r>),
|
PreviousElementNode(PreviousElementNode<'s>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -41,19 +41,19 @@ use nom::Parser;
|
|||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use tracing::trace;
|
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>(
|
fn context_many_till<'r, 's, I, O, E, F, M, T>(
|
||||||
context: Context<'r>,
|
context: Context<'r, 's>,
|
||||||
mut many_matcher: M,
|
mut many_matcher: M,
|
||||||
mut till_matcher: T,
|
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
|
where
|
||||||
I: Clone + InputLength,
|
I: Clone + InputLength,
|
||||||
E: ParseError<I>,
|
E: ParseError<I>,
|
||||||
M: for<'a> Fn(Context<'a>, I) -> IResult<I, O, E>,
|
M: Fn(Context<'r, 's>, I) -> IResult<I, O, E> + 'r,
|
||||||
T: for<'a> Fn(Context<'a>, I) -> IResult<I, F, E>,
|
T: Fn(Context<'r, 's>, I) -> IResult<I, F, E> + 'r,
|
||||||
O: Into<Token<'x>>,
|
O: Into<Token<'s>>,
|
||||||
{
|
{
|
||||||
move |mut i: I| {
|
move |mut i: I| {
|
||||||
let mut current_context = context.clone();
|
let mut current_context = context.clone();
|
||||||
@ -109,21 +109,21 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn document(input: &str) -> Res<&str, Vec<(Vec<TextElement>, &str)>> {
|
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 paragraph_parser = parser_with_context!(paragraph);
|
||||||
let ret = many1(paragraph_parser(initial_context))(input);
|
let ret = many1(paragraph_parser(initial_context))(input);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_paragraph_end<'s, 'r>(
|
pub fn context_paragraph_end<'s, 'r>(
|
||||||
context: Context<'r>,
|
context: Context<'r, 's>,
|
||||||
input: &'s str,
|
input: &'s str,
|
||||||
) -> Res<&'s str, &'s str> {
|
) -> Res<&'s str, &'s str> {
|
||||||
paragraph_end(input)
|
paragraph_end(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paragraph<'s, 'r>(
|
pub fn paragraph<'s, 'r>(
|
||||||
context: Context<'r>,
|
context: Context<'r, 's>,
|
||||||
i: &'s str,
|
i: &'s str,
|
||||||
) -> Res<&'s str, (Vec<TextElement<'s>>, &'s str)> {
|
) -> Res<&'s str, (Vec<TextElement<'s>>, &'s str)> {
|
||||||
// Add a not(eof) check because many_till cannot match a zero-length string
|
// Add a not(eof) check because many_till cannot match a zero-length string
|
||||||
@ -144,7 +144,10 @@ pub fn paragraph<'s, 'r>(
|
|||||||
todo!()
|
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)?;
|
not(|i| context.check_fail_matcher(i))(i)?;
|
||||||
|
|
||||||
let bold_matcher = parser_with_context!(flat_bold)(context.clone());
|
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)
|
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 =
|
let nom_context =
|
||||||
context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode {
|
context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode {
|
||||||
fail_matcher: ChainBehavior::AndParent(Some(&recognize_bold_end)),
|
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)
|
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 =
|
let nom_context =
|
||||||
context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode {
|
context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode {
|
||||||
fail_matcher: ChainBehavior::AndParent(Some(&recognize_link_end)),
|
fail_matcher: ChainBehavior::AndParent(Some(&recognize_link_end)),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user