Going to switch to using immutable fn instead of FnMut so I can easily make a context tree.
This commit is contained in:
parent
806070169a
commit
6f416f6997
@ -7,147 +7,29 @@ use nom::error::VerboseError;
|
||||
use nom::IResult;
|
||||
use nom::Parser;
|
||||
|
||||
type ContextReference<T> = Option<Rc<ContextLayer<T>>>;
|
||||
type ContextReference<'r, T> = Option<&'r ContextLayer<'r, T>>;
|
||||
type MatcherRef = dyn for<'s> FnMut(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>;
|
||||
|
||||
pub struct ContextLayer<T> {
|
||||
pub struct ContextLayer<'r, T> {
|
||||
data: T,
|
||||
parent: ContextReference<T>,
|
||||
parent: ContextReference<'r, T>,
|
||||
}
|
||||
|
||||
impl<T> ContextLayer<T> {
|
||||
pub fn with_new_layer(self: Rc<Self>, new_layer: T) -> ContextLayer<T> {
|
||||
ContextLayer {
|
||||
data: new_layer,
|
||||
parent: Some(self),
|
||||
}
|
||||
}
|
||||
pub struct TestContext<'r, T> {
|
||||
head: ContextReference<'r, T>,
|
||||
}
|
||||
|
||||
pub struct TestContext<T> {
|
||||
head: ContextReference<T>,
|
||||
}
|
||||
|
||||
// type ContextReference<T> = Option<Rc<ContextLayer<T>>>;
|
||||
|
||||
// struct ContextLayer<T> {
|
||||
// data: T,
|
||||
// parent: ContextReference<T>,
|
||||
// }
|
||||
|
||||
pub struct ContextData<'r> {
|
||||
fail_matcher: ChainBehavior<'r>,
|
||||
}
|
||||
|
||||
impl<'r> TestContext<ContextData<'r>> {
|
||||
impl<'r> TestContext<'r, ContextData<'r>> {
|
||||
pub fn new() -> Self {
|
||||
TestContext { head: None }
|
||||
}
|
||||
|
||||
pub fn with_additional_fail_matcher(
|
||||
&self,
|
||||
new_matcher: MatcherRef<'r>,
|
||||
) -> TestContext<ContextData<'r>> {
|
||||
TestContext {
|
||||
head: Some(Rc::new(ContextLayer {
|
||||
data: ContextData {
|
||||
fail_matcher: ChainBehavior::AndParent(Some(new_matcher)),
|
||||
},
|
||||
parent: self.head.clone(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////
|
||||
///// OLD
|
||||
/////
|
||||
|
||||
type MatcherRef<'r> = Rc<
|
||||
RefCell<dyn for<'s> FnMut(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> + 'r>,
|
||||
>;
|
||||
|
||||
// struct FailChecker<'r>(&'r NomContext<'r>);
|
||||
|
||||
// impl<'r> FailChecker<'r> {
|
||||
// fn new(func: &'r NomContext<'r>) -> Self {
|
||||
// Self(func)
|
||||
// }
|
||||
// }
|
||||
|
||||
enum ChainBehavior<'r> {
|
||||
AndParent(Option<MatcherRef<'r>>),
|
||||
IgnoreParent(Option<MatcherRef<'r>>),
|
||||
AndParent(Option<&'r MatcherRef>),
|
||||
IgnoreParent(Option<&'r MatcherRef>),
|
||||
}
|
||||
|
||||
// pub struct NomContext<'r> {
|
||||
// parent: Option<&'r Self>,
|
||||
// fail_matcher: ChainBehavior<'r>,
|
||||
// /// You can't have nested bolds or links in org-mode
|
||||
// match_bold_allowed: bool,
|
||||
// match_link_allowed: bool,
|
||||
// }
|
||||
|
||||
// impl<'r> NomContext<'r> {
|
||||
// pub fn new(fail_matcher: MatcherRef) -> Self {
|
||||
// NomContext {
|
||||
// parent: None,
|
||||
// fail_matcher: ChainBehavior::IgnoreParent(Some(fail_matcher)),
|
||||
// match_bold_allowed: true,
|
||||
// match_link_allowed: true,
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn with_additional_fail_matcher(&self, other: MatcherRef) -> NomContext {
|
||||
// NomContext {
|
||||
// parent: Some(&self),
|
||||
// fail_matcher: ChainBehavior::AndParent(Some(other)),
|
||||
// match_bold_allowed: self.match_bold_allowed,
|
||||
// match_link_allowed: self.match_link_allowed,
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn without_bold(&self, other: MatcherRef) -> NomContext {
|
||||
// NomContext {
|
||||
// parent: Some(&self),
|
||||
// fail_matcher: ChainBehavior::AndParent(Some(other)),
|
||||
// match_bold_allowed: false,
|
||||
// match_link_allowed: self.match_link_allowed,
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn not_matching_fail<'s>(&self, i: &'s str) -> IResult<&'s str, (), VerboseError<&'s str>> {
|
||||
// not(FailChecker::new(self))(i)
|
||||
// }
|
||||
|
||||
// pub fn can_match_bold(&self) -> bool {
|
||||
// self.match_bold_allowed
|
||||
// }
|
||||
|
||||
// pub fn can_match_link(&self) -> bool {
|
||||
// self.match_link_allowed
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<'r, 's> Parser<&'s str, &'s str, VerboseError<&'s str>> for FailChecker<'r> {
|
||||
// fn parse(&mut self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> {
|
||||
// let fail_func = match &self.0.fail_matcher {
|
||||
// ChainBehavior::AndParent(inner) => inner,
|
||||
// ChainBehavior::IgnoreParent(inner) => inner,
|
||||
// };
|
||||
// if let Some(inner) = fail_func {
|
||||
// let parsed = (&mut *inner.borrow_mut())(i);
|
||||
// if parsed.is_ok() {
|
||||
// return parsed;
|
||||
// }
|
||||
// }
|
||||
// match (self.0.parent, &self.0.fail_matcher) {
|
||||
// (None, _) | (_, ChainBehavior::IgnoreParent(_)) => Err(nom::Err::Error(
|
||||
// nom::error::make_error(i, nom::error::ErrorKind::Alt),
|
||||
// )),
|
||||
// (Some(parent), ChainBehavior::AndParent(_)) => {
|
||||
// let mut parent_fail_checker = FailChecker::new(parent);
|
||||
// parent_fail_checker.parse(i)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -138,8 +138,9 @@ pub fn paragraph_end(input: &str) -> Res<&str, &str> {
|
||||
|
||||
pub fn document(input: &str) -> Res<&str, Vec<(Vec<TextElement>, &str)>> {
|
||||
let initial_context = TestContext::new();
|
||||
let paragraph_context =
|
||||
initial_context.with_additional_fail_matcher(Rc::new(RefCell::new(paragraph_end)));
|
||||
let paragraph_context = initial_context;
|
||||
// let paragraph_context =
|
||||
// initial_context.with_additional_fail_matcher(Rc::new(RefCell::new(paragraph_end)));
|
||||
// let initial_context = NomContext::new(Rc::new(RefCell::new(paragraph_end)));
|
||||
let ret = many1(parser_with_context!(paragraph)(¶graph_context))(input);
|
||||
ret
|
||||
|
@ -47,8 +47,8 @@ fn flat_bold<'s, 'r>(
|
||||
) -> Res<&'s str, TextElement<'s>> {
|
||||
// let fail_matcher = recognize(bold_end);
|
||||
// let new_context = context.with_additional_fail_matcher(Rc::new(RefCell::new(paragraph_end)));
|
||||
let new_context =
|
||||
context.with_additional_fail_matcher(Rc::new(RefCell::new(recognize(bold_end))));
|
||||
// let new_context =
|
||||
// context.with_additional_fail_matcher(Rc::new(RefCell::new(recognize(bold_end))));
|
||||
// let new_context = context.without_bold(Rc::new(RefCell::new(recognize(bold_end))));
|
||||
todo!()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user