Use ParserInput trait
This commit is contained in:
parent
a8370ad216
commit
9198fdd407
@ -1,10 +1,10 @@
|
|||||||
use crate::parser::{ParseResult, Parser};
|
use crate::parser::{ParseResult, Parser, ParserInput};
|
||||||
|
|
||||||
pub fn choice2<P1, P2, I, O, E>(parser1: P1, parser2: P2) -> impl Parser<I, O, E>
|
pub fn choice2<P1, P2, I, O, E>(parser1: P1, parser2: P2) -> impl Parser<I, O, E>
|
||||||
where
|
where
|
||||||
P1: Parser<I, O, E>,
|
P1: Parser<I, O, E>,
|
||||||
P2: Parser<I, O, E>,
|
P2: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
move |input: I| match parser1.parse(input.clone()) {
|
move |input: I| match parser1.parse(input.clone()) {
|
||||||
ok @ Ok(..) => ok,
|
ok @ Ok(..) => ok,
|
||||||
@ -15,7 +15,7 @@ where
|
|||||||
pub fn choice<C, I, O, E>(choices: C) -> impl Parser<I, O, E>
|
pub fn choice<C, I, O, E>(choices: C) -> impl Parser<I, O, E>
|
||||||
where
|
where
|
||||||
C: Choice<I, O, E>,
|
C: Choice<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
move |input| choices.parse(input)
|
move |input| choices.parse(input)
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ impl<I, O, E, P1, P2> Choice<I, O, E> for (P1, P2)
|
|||||||
where
|
where
|
||||||
P1: Parser<I, O, E>,
|
P1: Parser<I, O, E>,
|
||||||
P2: Parser<I, O, E>,
|
P2: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
||||||
@ -41,7 +41,7 @@ where
|
|||||||
P1: Parser<I, O, E>,
|
P1: Parser<I, O, E>,
|
||||||
P2: Parser<I, O, E>,
|
P2: Parser<I, O, E>,
|
||||||
P3: Parser<I, O, E>,
|
P3: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
||||||
@ -55,7 +55,7 @@ where
|
|||||||
P2: Parser<I, O, E>,
|
P2: Parser<I, O, E>,
|
||||||
P3: Parser<I, O, E>,
|
P3: Parser<I, O, E>,
|
||||||
P4: Parser<I, O, E>,
|
P4: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
||||||
@ -70,7 +70,7 @@ where
|
|||||||
P3: Parser<I, O, E>,
|
P3: Parser<I, O, E>,
|
||||||
P4: Parser<I, O, E>,
|
P4: Parser<I, O, E>,
|
||||||
P5: Parser<I, O, E>,
|
P5: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parsers = vec![
|
let parsers = vec![
|
||||||
@ -92,7 +92,7 @@ where
|
|||||||
P4: Parser<I, O, E>,
|
P4: Parser<I, O, E>,
|
||||||
P5: Parser<I, O, E>,
|
P5: Parser<I, O, E>,
|
||||||
P6: Parser<I, O, E>,
|
P6: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
let parsers = vec![
|
let parsers = vec![
|
||||||
@ -109,7 +109,7 @@ where
|
|||||||
|
|
||||||
fn choice_loop<I, O, E>(input: I, parsers: Vec<&dyn Parser<I, O, E>>) -> ParseResult<I, O, E>
|
fn choice_loop<I, O, E>(input: I, parsers: Vec<&dyn Parser<I, O, E>>) -> ParseResult<I, O, E>
|
||||||
where
|
where
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
//TODO need a more principled way to return an error when no choices work
|
//TODO need a more principled way to return an error when no choices work
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::parser::{BoxedParser, ParseResult, Parser};
|
use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput};
|
||||||
|
|
||||||
pub fn optional<P, I, O, E>(parser: P) -> impl Parser<I, Option<O>, E>
|
pub fn optional<P, I, O, E>(parser: P) -> impl Parser<I, Option<O>, E>
|
||||||
where
|
where
|
||||||
P: Parser<I, O, E>,
|
P: Parser<I, O, E>,
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
move |input: I| match parser.parse(input.clone()) {
|
move |input: I| match parser.parse(input.clone()) {
|
||||||
Ok((output, rest)) => Ok((Some(output), rest)),
|
Ok((output, rest)) => Ok((Some(output), rest)),
|
||||||
@ -13,6 +13,7 @@ where
|
|||||||
|
|
||||||
pub fn map<P, F, I, O1, O2, E>(parser: P, map_fn: F) -> impl Parser<I, O2, E>
|
pub fn map<P, F, I, O1, O2, E>(parser: P, map_fn: F) -> impl Parser<I, O2, E>
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P: Parser<I, O1, E>,
|
P: Parser<I, O1, E>,
|
||||||
F: Fn(O1) -> O2,
|
F: Fn(O1) -> O2,
|
||||||
{
|
{
|
||||||
@ -25,7 +26,7 @@ where
|
|||||||
|
|
||||||
pub struct Repeated<'a, I, O>
|
pub struct Repeated<'a, I, O>
|
||||||
where
|
where
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
inner_parser: BoxedParser<'a, I, O, I>,
|
inner_parser: BoxedParser<'a, I, O, I>,
|
||||||
at_least: Option<u16>,
|
at_least: Option<u16>,
|
||||||
@ -34,7 +35,7 @@ where
|
|||||||
|
|
||||||
impl<'a, I, O> Repeated<'a, I, O>
|
impl<'a, I, O> Repeated<'a, I, O>
|
||||||
where
|
where
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
pub fn at_least(self, n: u16) -> Self {
|
pub fn at_least(self, n: u16) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -65,7 +66,7 @@ where
|
|||||||
|
|
||||||
impl<'a, I, O> Parser<I, Vec<O>, I> for Repeated<'a, I, O>
|
impl<'a, I, O> Parser<I, Vec<O>, I> for Repeated<'a, I, O>
|
||||||
where
|
where
|
||||||
I: Clone + 'a,
|
I: ParserInput + Clone + 'a,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, Vec<O>, I> {
|
fn parse(&self, input: I) -> ParseResult<I, Vec<O>, I> {
|
||||||
let at_least = self.at_least.unwrap_or(0);
|
let at_least = self.at_least.unwrap_or(0);
|
||||||
@ -97,7 +98,7 @@ where
|
|||||||
|
|
||||||
pub struct SeparatedBy<'a, I, O>
|
pub struct SeparatedBy<'a, I, O>
|
||||||
where
|
where
|
||||||
I: Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
inner_repeated: Repeated<'a, I, O>,
|
inner_repeated: Repeated<'a, I, O>,
|
||||||
delimiter: BoxedParser<'a, I, (), I>,
|
delimiter: BoxedParser<'a, I, (), I>,
|
||||||
@ -106,7 +107,7 @@ where
|
|||||||
|
|
||||||
impl<'a, I, O> Parser<I, Vec<O>, I> for SeparatedBy<'a, I, O>
|
impl<'a, I, O> Parser<I, Vec<O>, I> for SeparatedBy<'a, I, O>
|
||||||
where
|
where
|
||||||
I: Clone + 'a,
|
I: ParserInput + Clone + 'a,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, Vec<O>, I> {
|
fn parse(&self, input: I) -> ParseResult<I, Vec<O>, I> {
|
||||||
let at_least = self.inner_repeated.at_least.unwrap_or(0);
|
let at_least = self.inner_repeated.at_least.unwrap_or(0);
|
||||||
@ -176,7 +177,7 @@ where
|
|||||||
pub fn repeated<'a, P, I, O>(parser: P) -> Repeated<'a, I, O>
|
pub fn repeated<'a, P, I, O>(parser: P) -> Repeated<'a, I, O>
|
||||||
where
|
where
|
||||||
P: Parser<I, O, I> + 'static,
|
P: Parser<I, O, I> + 'static,
|
||||||
I: Clone + 'static,
|
I: ParserInput + Clone + 'static,
|
||||||
{
|
{
|
||||||
Repeated {
|
Repeated {
|
||||||
inner_parser: BoxedParser::new(parser),
|
inner_parser: BoxedParser::new(parser),
|
||||||
|
@ -6,7 +6,7 @@ mod parser;
|
|||||||
mod primitives;
|
mod primitives;
|
||||||
mod sequence;
|
mod sequence;
|
||||||
|
|
||||||
pub use parser::{ParseResult, Parser};
|
pub use parser::{ParseResult, Parser, ParserInput};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -3,7 +3,15 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
pub type ParseResult<I, O, E> = Result<(O, I), E>;
|
pub type ParseResult<I, O, E> = Result<(O, I), E>;
|
||||||
|
|
||||||
pub trait Parser<I, O, E> {
|
pub trait ParserInput: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl ParserInput for &str {}
|
||||||
|
impl ParserInput for String {}
|
||||||
|
|
||||||
|
pub trait Parser<I, O, E>
|
||||||
|
where
|
||||||
|
I: ParserInput,
|
||||||
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
||||||
fn bnf(&self) -> Option<Bnf> {
|
fn bnf(&self) -> Option<Bnf> {
|
||||||
None
|
None
|
||||||
@ -95,11 +103,17 @@ pub trait Parser<I, O, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BoxedParser<'a, I, O, E> {
|
pub struct BoxedParser<'a, I, O, E>
|
||||||
|
where
|
||||||
|
I: ParserInput,
|
||||||
|
{
|
||||||
inner: Box<dyn Parser<I, O, E> + 'a>,
|
inner: Box<dyn Parser<I, O, E> + 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, O, E> BoxedParser<'a, I, O, E> {
|
impl<'a, I, O, E> BoxedParser<'a, I, O, E>
|
||||||
|
where
|
||||||
|
I: ParserInput,
|
||||||
|
{
|
||||||
pub(crate) fn new<P>(inner: P) -> Self
|
pub(crate) fn new<P>(inner: P) -> Self
|
||||||
where
|
where
|
||||||
P: Parser<I, O, E> + 'a,
|
P: Parser<I, O, E> + 'a,
|
||||||
@ -110,13 +124,13 @@ impl<'a, I, O, E> BoxedParser<'a, I, O, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, 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> {
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
self.inner.parse(input)
|
self.inner.parse(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, F> Parser<I, O, E> for F
|
impl<I: ParserInput, O, E, F> Parser<I, O, E> for F
|
||||||
where
|
where
|
||||||
F: Fn(I) -> ParseResult<I, O, E>,
|
F: Fn(I) -> ParseResult<I, O, E>,
|
||||||
{
|
{
|
||||||
@ -127,6 +141,7 @@ where
|
|||||||
|
|
||||||
impl<I, O, E, T> Parser<I, O, E> for Rc<T>
|
impl<I, O, E, T> Parser<I, O, E> for Rc<T>
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
T: Parser<I, O, E>,
|
T: Parser<I, O, E>,
|
||||||
{
|
{
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::parser::{ParseResult, Parser};
|
use crate::parser::{ParseResult, Parser, ParserInput};
|
||||||
|
|
||||||
pub fn literal_char(expected: char) -> impl Fn(&str) -> ParseResult<&str, char, &str> {
|
pub fn literal_char(expected: char) -> impl Fn(&str) -> ParseResult<&str, char, &str> {
|
||||||
move |input| match input.chars().next() {
|
move |input| match input.chars().next() {
|
||||||
@ -35,6 +35,7 @@ pub fn one_of<'a>(items: &'static str) -> impl Parser<&'a str, &'a str, &'a str>
|
|||||||
|
|
||||||
pub fn pred<P, F, I, O>(parser: P, pred_fn: F) -> impl Parser<I, O, I>
|
pub fn pred<P, F, I, O>(parser: P, pred_fn: F) -> impl Parser<I, O, I>
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P: Parser<I, O, I>,
|
P: Parser<I, O, I>,
|
||||||
F: Fn(&O) -> bool,
|
F: Fn(&O) -> bool,
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use crate::{ParseResult, Parser};
|
use crate::{ParseResult, Parser, ParserInput};
|
||||||
|
|
||||||
pub fn tuple2<P1, P2, I, O1, O2, E>(parser1: P1, parser2: P2) -> impl Parser<I, (O1, O2), E>
|
pub fn tuple2<P1, P2, I, O1, O2, E>(parser1: P1, parser2: P2) -> impl Parser<I, (O1, O2), E>
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P1: Parser<I, O1, E>,
|
P1: Parser<I, O1, E>,
|
||||||
P2: Parser<I, O2, E>,
|
P2: Parser<I, O2, E>,
|
||||||
{
|
{
|
||||||
@ -10,6 +11,7 @@ where
|
|||||||
|
|
||||||
pub fn seq<T, I, O, E>(sequence: T) -> impl Parser<I, O, E>
|
pub fn seq<T, I, O, E>(sequence: T) -> impl Parser<I, O, E>
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
T: Sequence<I, O, E>,
|
T: Sequence<I, O, E>,
|
||||||
{
|
{
|
||||||
move |input| sequence.parse(input)
|
move |input| sequence.parse(input)
|
||||||
@ -26,6 +28,7 @@ pub trait Sequence<I, O, E> {
|
|||||||
|
|
||||||
impl<I, O1, O2, E, P1, P2> Sequence<I, (O1, O2), E> for (P1, P2)
|
impl<I, O1, O2, E, P1, P2> Sequence<I, (O1, O2), E> for (P1, P2)
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P1: Parser<I, O1, E>,
|
P1: Parser<I, O1, E>,
|
||||||
P2: Parser<I, O2, E>,
|
P2: Parser<I, O2, E>,
|
||||||
{
|
{
|
||||||
@ -42,6 +45,7 @@ where
|
|||||||
|
|
||||||
impl<I, O1, O2, O3, E, P1, P2, P3> Sequence<I, (O1, O2, O3), E> for (P1, P2, P3)
|
impl<I, O1, O2, O3, E, P1, P2, P3> Sequence<I, (O1, O2, O3), E> for (P1, P2, P3)
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P1: Parser<I, O1, E>,
|
P1: Parser<I, O1, E>,
|
||||||
P2: Parser<I, O2, E>,
|
P2: Parser<I, O2, E>,
|
||||||
P3: Parser<I, O3, E>,
|
P3: Parser<I, O3, E>,
|
||||||
@ -61,6 +65,7 @@ where
|
|||||||
|
|
||||||
impl<I, O1, O2, O3, O4, E, P1, P2, P3, P4> Sequence<I, (O1, O2, O3, O4), E> for (P1, P2, P3, P4)
|
impl<I, O1, O2, O3, O4, E, P1, P2, P3, P4> Sequence<I, (O1, O2, O3, O4), E> for (P1, P2, P3, P4)
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P1: Parser<I, O1, E>,
|
P1: Parser<I, O1, E>,
|
||||||
P2: Parser<I, O2, E>,
|
P2: Parser<I, O2, E>,
|
||||||
P3: Parser<I, O3, E>,
|
P3: Parser<I, O3, E>,
|
||||||
@ -84,6 +89,7 @@ where
|
|||||||
impl<I, O1, O2, O3, O4, O5, E, P1, P2, P3, P4, P5> Sequence<I, (O1, O2, O3, O4, O5), E>
|
impl<I, O1, O2, O3, O4, O5, E, P1, P2, P3, P4, P5> Sequence<I, (O1, O2, O3, O4, O5), E>
|
||||||
for (P1, P2, P3, P4, P5)
|
for (P1, P2, P3, P4, P5)
|
||||||
where
|
where
|
||||||
|
I: ParserInput,
|
||||||
P1: Parser<I, O1, E>,
|
P1: Parser<I, O1, E>,
|
||||||
P2: Parser<I, O2, E>,
|
P2: Parser<I, O2, E>,
|
||||||
P3: Parser<I, O3, E>,
|
P3: Parser<I, O3, E>,
|
||||||
|
Loading…
Reference in New Issue
Block a user