Replace the old nom_context with the contents of new_context.
This commit is contained in:
		
							parent
							
								
									84fa1c3aae
								
							
						
					
					
						commit
						6cfc39ca45
					
				| @ -1,8 +1,7 @@ | ||||
| mod list; | ||||
| mod new_context; | ||||
| mod nom_context; | ||||
| mod parser_with_context; | ||||
| mod text; | ||||
| mod text_element_parser; | ||||
| pub use text_element_parser::document; | ||||
| type Context<'r> = &'r new_context::ContextTree<'r>; | ||||
| type Context<'r> = &'r nom_context::ContextTree<'r>; | ||||
|  | ||||
| @ -1,106 +0,0 @@ | ||||
| use nom::bytes::complete::take; | ||||
| use nom::combinator::not; | ||||
| use nom::error::VerboseError; | ||||
| use nom::IResult; | ||||
| 
 | ||||
| use super::list::List; | ||||
| 
 | ||||
| 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>>, | ||||
| } | ||||
| 
 | ||||
| impl<'r> ContextTree<'r> { | ||||
|     pub fn new() -> Self { | ||||
|         ContextTree { tree: List::new() } | ||||
|     } | ||||
| 
 | ||||
|     pub fn with_additional_node(&self, data: ContextElement<'r>) -> ContextTree<'r> { | ||||
|         let new_list = self.tree.push_front(data); | ||||
|         ContextTree { tree: new_list } | ||||
|     } | ||||
| 
 | ||||
|     pub fn check_fail_matcher<'s>( | ||||
|         &'r self, | ||||
|         i: &'s str, | ||||
|     ) -> IResult<&'s str, &'s str, VerboseError<&'s 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() { | ||||
|             let context_element = current_node | ||||
|                 .get_data() | ||||
|                 .expect("While looop proves its Some()"); | ||||
|             match context_element { | ||||
|                 ContextElement::FailMatcherNode(fail_matcher) => { | ||||
|                     match fail_matcher.fail_matcher { | ||||
|                         ChainBehavior::AndParent(Some(matcher)) => { | ||||
|                             let local_result = matcher(i); | ||||
|                             if local_result.is_ok() { | ||||
|                                 return local_result; | ||||
|                             } | ||||
|                         } | ||||
|                         ChainBehavior::AndParent(None) => {} | ||||
|                         ChainBehavior::IgnoreParent(Some(matcher)) => { | ||||
|                             let local_result = matcher(i); | ||||
|                             if local_result.is_ok() { | ||||
|                                 return local_result; | ||||
|                             } | ||||
|                             // TODO: Make this a custom error
 | ||||
|                             not(take(0usize))(i)?; | ||||
|                         } | ||||
|                         ChainBehavior::IgnoreParent(None) => { | ||||
|                             // TODO: Make this a custom error
 | ||||
|                             not(take(0usize))(i)?; | ||||
|                         } | ||||
|                     }; | ||||
|                 } | ||||
|                 ContextElement::PreviousElementNode(_) => todo!(), | ||||
|             }; | ||||
| 
 | ||||
|             current_node = current_node.without_front(); | ||||
|         } | ||||
| 
 | ||||
|         // TODO: Make this a custom error
 | ||||
|         not(take(0usize))(i)?; | ||||
|         unreachable!() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ContextElement<'r> { | ||||
|     FailMatcherNode(FailMatcherNode<'r>), | ||||
|     PreviousElementNode(PreviousElementNode<'r>), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FailMatcherNode<'r> { | ||||
|     pub fail_matcher: ChainBehavior<'r>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct PreviousElementNode<'r> { | ||||
|     pub dummy: &'r str, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub enum ChainBehavior<'r> { | ||||
|     AndParent(Option<&'r Matcher>), | ||||
|     IgnoreParent(Option<&'r Matcher>), | ||||
| } | ||||
| 
 | ||||
| impl<'r> std::fmt::Debug for ChainBehavior<'r> { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         let mut formatter = f.debug_struct("ChainBehavior"); | ||||
|         // match self {
 | ||||
|         //     ChainBehavior::AndParent(_) => {
 | ||||
|         //         formatter = formatter.field("type", &"AndParent");
 | ||||
|         //     }
 | ||||
|         //     ChainBehavior::IgnoreParent(_) => {
 | ||||
|         //         formatter = formatter.field("type", &"IgnoreParent");
 | ||||
|         //     }
 | ||||
|         // };
 | ||||
|         formatter.finish() | ||||
|     } | ||||
| } | ||||
| @ -1,56 +1,85 @@ | ||||
| use std::cell::RefCell; | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| use nom::branch::alt; | ||||
| use nom::bytes::complete::take; | ||||
| use nom::combinator::not; | ||||
| use nom::error::ContextError; | ||||
| use nom::error::ErrorKind; | ||||
| use nom::error::ParseError; | ||||
| use nom::error::VerboseError; | ||||
| use nom::IResult; | ||||
| use nom::Parser; | ||||
| use tracing::trace; | ||||
| 
 | ||||
| type Link<'r, T> = Option<&'r Node<'r, T>>; | ||||
| use super::list::List; | ||||
| 
 | ||||
| type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; | ||||
| pub type OrgModeContextNode<'r> = ContextTree<'r, ContextElement<'r>>; | ||||
| 
 | ||||
| struct Node<'r, T> { | ||||
|     elem: T, | ||||
|     next: Link<'r, T>, | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct ContextTree<'r> { | ||||
|     tree: List<ContextElement<'r>>, | ||||
| } | ||||
| 
 | ||||
| pub struct ContextTree<'r, T> { | ||||
|     head: Option<Node<'r, T>>, | ||||
| } | ||||
| 
 | ||||
| impl<'r, T> ContextTree<'r, T> { | ||||
| impl<'r> ContextTree<'r> { | ||||
|     pub fn new() -> Self { | ||||
|         ContextTree { head: None } | ||||
|         ContextTree { tree: List::new() } | ||||
|     } | ||||
| 
 | ||||
|     pub fn with_additional_node(&'r self, element: T) -> ContextTree<'r, T> { | ||||
|         let new_node = Node { | ||||
|             elem: element, | ||||
|             next: self.head.as_ref(), | ||||
|         }; | ||||
|     pub fn with_additional_node(&self, data: ContextElement<'r>) -> ContextTree<'r> { | ||||
|         let new_list = self.tree.push_front(data); | ||||
|         ContextTree { tree: new_list } | ||||
|     } | ||||
| 
 | ||||
|         ContextTree { | ||||
|             head: Some(new_node), | ||||
|     pub fn check_fail_matcher<'s>( | ||||
|         &'r self, | ||||
|         i: &'s str, | ||||
|     ) -> IResult<&'s str, &'s str, VerboseError<&'s 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() { | ||||
|             let context_element = current_node | ||||
|                 .get_data() | ||||
|                 .expect("While looop proves its Some()"); | ||||
|             match context_element { | ||||
|                 ContextElement::FailMatcherNode(fail_matcher) => { | ||||
|                     match fail_matcher.fail_matcher { | ||||
|                         ChainBehavior::AndParent(Some(matcher)) => { | ||||
|                             let local_result = matcher(i); | ||||
|                             if local_result.is_ok() { | ||||
|                                 return local_result; | ||||
|                             } | ||||
|                         } | ||||
|                         ChainBehavior::AndParent(None) => {} | ||||
|                         ChainBehavior::IgnoreParent(Some(matcher)) => { | ||||
|                             let local_result = matcher(i); | ||||
|                             if local_result.is_ok() { | ||||
|                                 return local_result; | ||||
|                             } | ||||
|                             // TODO: Make this a custom error
 | ||||
|                             not(take(0usize))(i)?; | ||||
|                         } | ||||
|                         ChainBehavior::IgnoreParent(None) => { | ||||
|                             // TODO: Make this a custom error
 | ||||
|                             not(take(0usize))(i)?; | ||||
|                         } | ||||
|                     }; | ||||
|                 } | ||||
|                 ContextElement::PreviousElementNode(_) => todo!(), | ||||
|             }; | ||||
| 
 | ||||
|             current_node = current_node.without_front(); | ||||
|         } | ||||
| 
 | ||||
|         // TODO: Make this a custom error
 | ||||
|         not(take(0usize))(i)?; | ||||
|         unreachable!() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ContextElement<'r> { | ||||
|     FailMatcherNode(FailMatcherNode<'r>), | ||||
|     PreviousElementNode(PreviousElementNode<'r>), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FailMatcherNode<'r> { | ||||
|     pub fail_matcher: ChainBehavior<'r>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct PreviousElementNode<'r> { | ||||
|     pub dummy: &'r str, | ||||
| } | ||||
| @ -61,77 +90,17 @@ pub enum ChainBehavior<'r> { | ||||
|     IgnoreParent(Option<&'r Matcher>), | ||||
| } | ||||
| 
 | ||||
| pub trait OrgModeContextTree<'r> { | ||||
|     fn with_additional_fail_matcher(&'r self, fail_matcher: &'r Matcher) -> OrgModeContextNode<'r>; | ||||
| 
 | ||||
|     fn match_fail<'s>(&'r self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; | ||||
| } | ||||
| 
 | ||||
| impl<'r> OrgModeContextTree<'r> for OrgModeContextNode<'r> { | ||||
|     fn with_additional_fail_matcher( | ||||
|         &'r self, | ||||
|         fail_matcher: &'r Matcher, | ||||
|     ) -> ContextTree<'r, ContextElement<'r>> { | ||||
|         self.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { | ||||
|             fail_matcher: ChainBehavior::AndParent(Some(fail_matcher)), | ||||
|         })) | ||||
|     } | ||||
| 
 | ||||
|     // fn with_previous_element(&'r self, dummy: &'r str) -> ContextTree<'r, PreviousElementNode<'r>> {
 | ||||
|     //     self.with_additional_node(PreviousElementNode {
 | ||||
|     //         dummy
 | ||||
|     //     })
 | ||||
|     // }
 | ||||
| 
 | ||||
|     fn match_fail<'s>(&'r self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> { | ||||
|         let mut current_node = self.head.as_ref(); | ||||
|         while current_node.is_some() { | ||||
|             let current_node_unwrapped = | ||||
|                 current_node.expect("while loop asserts current_node is some."); | ||||
|             match current_node_unwrapped.elem.get_fail_matcher() { | ||||
|                 ChainBehavior::AndParent(Some(matcher)) => { | ||||
|                     let local_result = matcher(i); | ||||
|                     if local_result.is_ok() { | ||||
|                         return local_result; | ||||
|                     } | ||||
|                 } | ||||
|                 ChainBehavior::AndParent(None) => {} | ||||
|                 ChainBehavior::IgnoreParent(Some(matcher)) => { | ||||
|                     let local_result = matcher(i); | ||||
|                     if local_result.is_ok() { | ||||
|                         return local_result; | ||||
|                     } | ||||
|                     // TODO: Make this a custom error
 | ||||
|                     not(take(0usize))(i)?; | ||||
|                 } | ||||
|                 ChainBehavior::IgnoreParent(None) => { | ||||
|                     // TODO: Make this a custom error
 | ||||
|                     not(take(0usize))(i)?; | ||||
|                 } | ||||
|             }; | ||||
|             current_node = current_node.map(|current_head| current_head.next).flatten(); | ||||
|         } | ||||
|         // TODO: Make this a custom error
 | ||||
|         not(take(0usize))(i)?; | ||||
|         unreachable!() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'r, T> std::fmt::Debug for ContextTree<'r, T> { | ||||
| impl<'r> std::fmt::Debug for ChainBehavior<'r> { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         write!(f, "ContextTree") | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'r> ContextElement<'r> { | ||||
|     pub fn get_fail_matcher(&self) -> ChainBehavior<'r> { | ||||
|         match self { | ||||
|             ContextElement::FailMatcherNode(fail_matcher_node) => { | ||||
|                 fail_matcher_node.fail_matcher.clone() | ||||
|             } | ||||
|             ContextElement::PreviousElementNode(previous_element_node) => { | ||||
|                 ChainBehavior::AndParent(None) | ||||
|             } | ||||
|         } | ||||
|         let mut formatter = f.debug_struct("ChainBehavior"); | ||||
|         // match self {
 | ||||
|         //     ChainBehavior::AndParent(_) => {
 | ||||
|         //         formatter = formatter.field("type", &"AndParent");
 | ||||
|         //     }
 | ||||
|         //     ChainBehavior::IgnoreParent(_) => {
 | ||||
|         //         formatter = formatter.field("type", &"IgnoreParent");
 | ||||
|         //     }
 | ||||
|         // };
 | ||||
|         formatter.finish() | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -5,10 +5,10 @@ use std::rc::Rc; | ||||
| use crate::parser::parser_with_context::parser_with_context; | ||||
| use crate::parser::text::paragraph_end; | ||||
| 
 | ||||
| use super::new_context::ChainBehavior; | ||||
| use super::new_context::ContextElement; | ||||
| use super::new_context::ContextTree; | ||||
| use super::new_context::FailMatcherNode; | ||||
| use super::nom_context::ChainBehavior; | ||||
| use super::nom_context::ContextElement; | ||||
| use super::nom_context::ContextTree; | ||||
| use super::nom_context::FailMatcherNode; | ||||
| use super::text::bold_end; | ||||
| use super::text::bold_start; | ||||
| use super::text::line_break; | ||||
| @ -133,12 +133,12 @@ fn recognize_bold_end(input: &str) -> Res<&str, &str> { | ||||
| } | ||||
| 
 | ||||
| fn flat_bold<'s, 'r>(context: Context<'r>, i: &'s str) -> Res<&'s str, Bold<'s>> { | ||||
|     let new_context = | ||||
|     let nom_context = | ||||
|         context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { | ||||
|             fail_matcher: ChainBehavior::AndParent(Some(&recognize_bold_end)), | ||||
|         })); | ||||
|     // let new_context = context.with_additional_fail_matcher(&recognize_bold_end);
 | ||||
|     let text_element_parser = parser_with_context!(flat_text_element)(new_context); | ||||
|     // let nom_context = context.with_additional_fail_matcher(&recognize_bold_end);
 | ||||
|     let text_element_parser = parser_with_context!(flat_text_element)(nom_context); | ||||
|     let (remaining, captured) = recognize(tuple(( | ||||
|         bold_start, | ||||
|         many_till(text_element_parser, bold_end), | ||||
| @ -152,12 +152,12 @@ fn recognize_link_end(input: &str) -> Res<&str, &str> { | ||||
| } | ||||
| 
 | ||||
| fn flat_link<'s, 'r>(context: Context<'r>, i: &'s str) -> Res<&'s str, Link<'s>> { | ||||
|     let new_context = | ||||
|     let nom_context = | ||||
|         context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { | ||||
|             fail_matcher: ChainBehavior::AndParent(Some(&recognize_link_end)), | ||||
|         })); | ||||
|     // let new_context = context.with_additional_fail_matcher(&recognize_link_end);
 | ||||
|     let text_element_parser = parser_with_context!(flat_text_element)(new_context); | ||||
|     // let nom_context = context.with_additional_fail_matcher(&recognize_link_end);
 | ||||
|     let text_element_parser = parser_with_context!(flat_text_element)(nom_context); | ||||
|     let (remaining, captured) = recognize(tuple(( | ||||
|         link_start, | ||||
|         many_till(text_element_parser, link_end), | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander