diff --git a/src/parser/boxed_parser.rs b/src/parser/boxed_parser.rs index 8883910..a3b3e68 100644 --- a/src/parser/boxed_parser.rs +++ b/src/parser/boxed_parser.rs @@ -20,6 +20,7 @@ where inner: Box::new(inner), } } + } impl<'a, I: ParserInput, O, E> Parser for BoxedParser<'a, I, O, E> { @@ -30,4 +31,8 @@ impl<'a, I: ParserInput, O, E> Parser for BoxedParser<'a, I, O, E> { fn bnf(&self) -> Option { self.inner.bnf() } + + fn boxed<'b>(self) -> BoxedParser<'b, I, O, E> where Self: Sized + 'b { + self + } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 244aed8..dea519b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,9 +1,11 @@ mod boxed_parser; +mod named_parser; use crate::bnf::Bnf; use std::rc::Rc; pub use boxed_parser::BoxedParser; +pub use named_parser::NamedParser; pub type ParseResult = Result<(O, I), E>; @@ -21,6 +23,10 @@ where None } + fn boxed<'a>(self) -> BoxedParser<'a, I, O, E> where Self: Sized + 'a { + BoxedParser::new(self) + } + fn map<'a, F, O2>(self, map_fn: F) -> BoxedParser<'a, I, O2, E> where Self: Sized + 'a, @@ -30,7 +36,7 @@ where O2: 'a, F: Fn(O) -> O2 + 'a, { - BoxedParser::new(crate::combinators::map(self, map_fn)) + crate::combinators::map(self, map_fn).boxed() } fn to<'a, O2>(self, item: O2) -> BoxedParser<'a, I, O2, E> @@ -53,7 +59,7 @@ where E: 'a, P: Parser + 'a, { - BoxedParser::new(crate::sequence::tuple2(self, next_parser)) + crate::sequence::tuple2(self, next_parser).boxed() } fn ignore_then<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, O2, E> @@ -65,7 +71,7 @@ where E: 'a, P: Parser + 'a, { - BoxedParser::new(crate::sequence::tuple2(self, next_parser)) + crate::sequence::tuple2(self, next_parser) .map(|(_, next_output)| next_output) } @@ -78,7 +84,7 @@ where E: 'a, P: Parser + 'a, { - BoxedParser::new(crate::sequence::tuple2(self, next_parser)) + crate::sequence::tuple2(self, next_parser) .map(|(this_output, _)| this_output) } @@ -122,7 +128,15 @@ where E: 'a, Self: Sized + 'a, { - BoxedParser::new(crate::combinators::optional(self)) + crate::combinators::optional(self).boxed() + } + + fn named<'a>(self, parser_name: &str) -> NamedParser<'a, I, O, E> + where + Self: Sized + 'a, + I: 'a, + { + NamedParser::new(self.boxed(), parser_name.to_string()) } } diff --git a/src/parser/named_parser.rs b/src/parser/named_parser.rs new file mode 100644 index 0000000..a85be49 --- /dev/null +++ b/src/parser/named_parser.rs @@ -0,0 +1,33 @@ +use crate::parser::{ParseResult, Parser, ParserInput}; +//use crate::bnf::Bnf; +use super::boxed_parser::BoxedParser; + +pub struct NamedParser<'a, I, O, E> +where + I: ParserInput, +{ + inner_parser: BoxedParser<'a, I, O, E>, + name: String, +} + +impl<'a, I, O, E> NamedParser<'a, I, O, E> +where + I: ParserInput, +{ + pub(super) fn new(inner_parser: BoxedParser<'a, I, O, E>, name: String) -> Self + where + I: 'a, + { + NamedParser { inner_parser, name } + } + + pub fn get_name(&'a self) -> &'a str { + self.name.as_ref() + } +} + +impl<'a, I: ParserInput, O, E> Parser for NamedParser<'a, I, O, E> { + fn parse(&self, input: I) -> ParseResult { + self.inner_parser.parse(input) + } +}