rust-parser-combinator/src/parser.rs

77 lines
2.2 KiB
Rust

use crate::{annotated::AnnotatedParser, map, representation::Representation, seq2, surrounded_by};
pub type ParseResult<I, O, E> = Result<(O, I), (E, I)>;
pub trait Parser<I, O, E> {
fn parse(&self, input: I) -> ParseResult<I, O, E>;
fn name(&self) -> Option<String> {
None
}
fn representation(&self) -> Representation {
Representation::new()
}
}
impl<I, O, E, F> Parser<I, O, E> for F
where
F: Fn(I) -> ParseResult<I, O, E>,
{
fn parse(&self, input: I) -> ParseResult<I, O, E> {
self(input)
}
}
pub trait ParserExtension<I, O, E>: Parser<I, O, E> {
fn map<F, O2>(self, map_fn: F) -> impl Parser<I, O2, E>
where
F: Fn(O) -> O2;
fn to<O2: Clone>(self, item: O2) -> impl Parser<I, O2, E>;
fn then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, (O, O2), 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_anno(self) -> AnnotatedParser<Self, I, O, E>
where
Self: Sized,
{
AnnotatedParser::new(self)
}
fn to_named(self, name: &str) -> AnnotatedParser<Self, I, O, E>
where
Self: Sized,
{
AnnotatedParser::new(self).with_name(name)
}
}
impl<T, I, O, E> ParserExtension<I, O, E> for T
where
T: Parser<I, O, E>,
{
fn map<F, O2>(self, map_fn: F) -> impl Parser<I, O2, E>
where
F: Fn(O) -> O2,
{
map(self, map_fn)
}
fn to<O2: Clone>(self, item: O2) -> impl Parser<I, O2, E> {
self.map(move |_| item.clone())
}
fn then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, (O, O2), E> {
seq2(self, next)
}
fn then_ignore<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O, E> {
seq2(self, next).map(|(this, _)| this)
}
fn ignore_then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O2, E> {
seq2(self, next).map(|(_, next)| next)
}
fn surrounded_by<O2>(self, surrounding: impl Parser<I, O2, E>) -> impl Parser<I, O, E> {
surrounded_by(self, surrounding)
}
}