mod boxed_parser; mod named_parser; mod parser_input; mod representation; use std::rc::Rc; pub use boxed_parser::BoxedParser; pub use named_parser::NamedParser; pub use parser_input::ParserInput; pub use representation::Representation; pub type ParseResult = Result<(O, I), E>; pub trait Parser where I: ParserInput, { fn parse(&self, input: I) -> ParseResult; fn representation(&self) -> Representation; 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, I: 'a, E: 'a, O: 'a, O2: 'a, F: Fn(O) -> O2 + 'a, { crate::combinators::map(self, map_fn).boxed() } fn to<'a, O2>(self, item: O2) -> BoxedParser<'a, I, O2, E> where Self: Sized + 'a, I: 'a, O: 'a, O2: Clone + 'a, E: 'a, { self.map(move |_| item.clone()) } fn then<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, (O, O2), E> where Self: Sized + 'a, I: 'a, O: 'a, O2: 'a, E: 'a, P: Parser + 'a, { crate::sequence::tuple2(self, next_parser).boxed() } fn ignore_then<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, O2, E> where Self: Sized + 'a, I: 'a, O: 'a, O2: 'a, E: 'a, P: Parser + 'a, { crate::sequence::tuple2(self, next_parser).map(|(_, next_output)| next_output) } fn then_ignore<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, O, E> where Self: Sized + 'a, I: 'a, O: 'a, O2: 'a, E: 'a, P: Parser + 'a, { crate::sequence::tuple2(self, next_parser).map(|(this_output, _)| this_output) } fn delimited<'a, P1, O1, P2, O2>(self, left: P1, right: P2) -> BoxedParser<'a, I, O, E> where Self: Sized + 'a, I: 'a, O1: 'a, O2: 'a, O: 'a, E: 'a, P1: Parser + 'a, P2: Parser + 'a, { crate::sequence::seq((left, self, right)).map(|(_, output, _)| output) } fn surrounded_by<'a, P, O1>(self, surrounding: P) -> BoxedParser<'a, I, O, E> where Self: Sized + 'a, I: 'a, O1: 'a, O: 'a, E: 'a, P: Parser + 'a, { BoxedParser::new(move |input| { let p1 = |i| surrounding.parse(i); let p2 = |i| surrounding.parse(i); let main = |i| self.parse(i); crate::sequence::seq((p1, main, p2)) .map(|(_, output, _)| output) .parse(input) }) } fn optional<'a>(self) -> BoxedParser<'a, I, Option, E> where I: Clone + 'a, O: 'a, E: 'a, Self: Sized + 'a, { 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()) } } impl Parser for F where F: Fn(I) -> ParseResult, { fn parse(&self, input: I) -> ParseResult { self(input) } fn representation(&self) -> Representation { Representation::new("NOT IMPL'D") } } impl Parser for (F, Representation) where F: Fn(I) -> ParseResult, { fn parse(&self, input: I) -> ParseResult { self.0(input) } fn representation(&self) -> Representation { self.1.clone() } } impl Parser for Rc where I: ParserInput, T: Parser, { fn parse(&self, input: I) -> ParseResult { self.as_ref().parse(input) } fn representation(&self) -> Representation { self.as_ref().representation() } }