Generalized to AnnotatedParser

This commit is contained in:
Greg Shuflin 2024-01-30 00:03:02 -08:00
parent 2909cdf296
commit 5141cdadd9
3 changed files with 49 additions and 31 deletions

45
src/annotated.rs Normal file
View File

@ -0,0 +1,45 @@
use std::marker::PhantomData;
use crate::{ParseResult, Parser};
pub struct AnnotatedParser<P, I, O, E>
where
P: Parser<I, O, E>,
{
inner: P,
name: Option<String>,
phantom: PhantomData<(I, O, E)>,
}
impl<P, I, O, E> Parser<I, O, E> for AnnotatedParser<P, I, O, E>
where
P: Parser<I, O, E>,
{
fn parse(&self, input: I) -> ParseResult<I, O, E> {
self.inner.parse(input)
}
fn name(&self) -> Option<String> {
self.name.clone()
}
}
impl<P, I, O, E> AnnotatedParser<P, I, O, E>
where
P: Parser<I, O, E>,
{
pub fn new(inner: P) -> Self {
Self {
inner,
name: None,
phantom: PhantomData,
}
}
pub fn with_name(self, name: &str) -> Self {
Self {
name: Some(name.to_string()),
..self
}
}
}

View File

@ -1,4 +1,5 @@
#![allow(dead_code)] //TODO eventually turn this off
mod annotated;
mod choice;
mod combinators;
mod map;

View File

@ -1,6 +1,4 @@
use std::marker::PhantomData;
use crate::{map, seq2, surrounded_by};
use crate::{annotated::AnnotatedParser, map, seq2, surrounded_by};
pub type ParseResult<I, O, E> = Result<(O, I), (E, I)>;
@ -20,28 +18,6 @@ where
}
}
pub struct NamedParser<P, I, O, E>
where
P: Parser<I, O, E>,
{
inner: P,
name: String,
phantom: PhantomData<(I, O, E)>,
}
impl<P, I, O, E> Parser<I, O, E> for NamedParser<P, I, O, E>
where
P: Parser<I, O, E>,
{
fn parse(&self, input: I) -> ParseResult<I, O, E> {
self.inner.parse(input)
}
fn name(&self) -> Option<String> {
Some(self.name.clone())
}
}
pub trait ParserExtension<I, O, E>: Parser<I, O, E> {
fn map<F, O2>(self, map_fn: F) -> impl Parser<I, O2, E>
where
@ -52,15 +28,11 @@ pub trait ParserExtension<I, O, E>: Parser<I, O, E> {
fn then_ignore<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O, E>;
fn ignore_then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O2, E>;
fn surrounded_by<O2>(self, surrounding: impl Parser<I, O2, E>) -> impl Parser<I, O, E>;
fn to_named(self, name: &str) -> NamedParser<Self, I, O, E>
fn to_named(self, name: &str) -> AnnotatedParser<Self, I, O, E>
where
Self: Sized,
{
NamedParser {
inner: self,
name: name.to_string(),
phantom: PhantomData,
}
AnnotatedParser::new(self).with_name(name)
}
}