Add named parser

This commit is contained in:
Greg Shuflin 2022-10-21 22:45:42 -07:00
parent 035afbf22f
commit 907e15a624
3 changed files with 57 additions and 5 deletions

View File

@ -20,6 +20,7 @@ where
inner: Box::new(inner), inner: Box::new(inner),
} }
} }
} }
impl<'a, I: ParserInput, O, E> Parser<I, O, E> for BoxedParser<'a, I, O, E> { impl<'a, I: ParserInput, O, E> Parser<I, O, E> for BoxedParser<'a, I, O, E> {
@ -30,4 +31,8 @@ impl<'a, I: ParserInput, O, E> Parser<I, O, E> for BoxedParser<'a, I, O, E> {
fn bnf(&self) -> Option<Bnf> { fn bnf(&self) -> Option<Bnf> {
self.inner.bnf() self.inner.bnf()
} }
fn boxed<'b>(self) -> BoxedParser<'b, I, O, E> where Self: Sized + 'b {
self
}
} }

View File

@ -1,9 +1,11 @@
mod boxed_parser; mod boxed_parser;
mod named_parser;
use crate::bnf::Bnf; use crate::bnf::Bnf;
use std::rc::Rc; use std::rc::Rc;
pub use boxed_parser::BoxedParser; pub use boxed_parser::BoxedParser;
pub use named_parser::NamedParser;
pub type ParseResult<I, O, E> = Result<(O, I), E>; pub type ParseResult<I, O, E> = Result<(O, I), E>;
@ -21,6 +23,10 @@ where
None 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> fn map<'a, F, O2>(self, map_fn: F) -> BoxedParser<'a, I, O2, E>
where where
Self: Sized + 'a, Self: Sized + 'a,
@ -30,7 +36,7 @@ where
O2: 'a, O2: 'a,
F: Fn(O) -> 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> fn to<'a, O2>(self, item: O2) -> BoxedParser<'a, I, O2, E>
@ -53,7 +59,7 @@ where
E: 'a, E: 'a,
P: Parser<I, O2, E> + 'a, P: Parser<I, O2, E> + '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> fn ignore_then<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, O2, E>
@ -65,7 +71,7 @@ where
E: 'a, E: 'a,
P: Parser<I, O2, E> + 'a, P: Parser<I, O2, E> + 'a,
{ {
BoxedParser::new(crate::sequence::tuple2(self, next_parser)) crate::sequence::tuple2(self, next_parser)
.map(|(_, next_output)| next_output) .map(|(_, next_output)| next_output)
} }
@ -78,7 +84,7 @@ where
E: 'a, E: 'a,
P: Parser<I, O2, E> + 'a, P: Parser<I, O2, E> + 'a,
{ {
BoxedParser::new(crate::sequence::tuple2(self, next_parser)) crate::sequence::tuple2(self, next_parser)
.map(|(this_output, _)| this_output) .map(|(this_output, _)| this_output)
} }
@ -122,7 +128,15 @@ where
E: 'a, E: 'a,
Self: Sized + '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())
} }
} }

View File

@ -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<I, O, E> for NamedParser<'a, I, O, E> {
fn parse(&self, input: I) -> ParseResult<I, O, E> {
self.inner_parser.parse(input)
}
}