Start working on Bnf
This commit is contained in:
parent
907e15a624
commit
0b51aa5073
@ -1,4 +1,6 @@
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Bnf {
|
||||
Production,
|
||||
Choice(Vec<Bnf>),
|
||||
Unknown,
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::bnf::Bnf;
|
||||
use crate::parser::{ParseResult, Parser, ParserInput};
|
||||
|
||||
pub fn choice2<P1, P2, I, O, E>(parser1: P1, parser2: P2) -> impl Parser<I, O, E>
|
||||
@ -12,16 +13,19 @@ 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>, Bnf)
|
||||
where
|
||||
C: Choice<I, O, E>,
|
||||
I: ParserInput + Clone,
|
||||
{
|
||||
move |input| choices.parse(input)
|
||||
let bnf = choices.bnf();
|
||||
(move |input| choices.parse(input), bnf)
|
||||
}
|
||||
|
||||
pub trait Choice<I: Clone, O, E> {
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
||||
|
||||
fn bnf(&self) -> Bnf;
|
||||
}
|
||||
|
||||
impl<I, O, E, P1, P2> Choice<I, O, E> for (P1, P2)
|
||||
@ -34,6 +38,16 @@ where
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
|
||||
fn bnf(&self) -> Bnf {
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
||||
Bnf::Choice(
|
||||
parsers
|
||||
.into_iter()
|
||||
.map(|p| p.bnf().unwrap_or(Bnf::Unknown))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, O, E, P1, P2, P3> Choice<I, O, E> for (P1, P2, P3)
|
||||
@ -47,6 +61,16 @@ where
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
|
||||
fn bnf(&self) -> Bnf {
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
||||
Bnf::Choice(
|
||||
parsers
|
||||
.into_iter()
|
||||
.map(|p| p.bnf().unwrap_or(Bnf::Unknown))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, O, E, P1, P2, P3, P4> Choice<I, O, E> for (P1, P2, P3, P4)
|
||||
@ -61,6 +85,16 @@ where
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
|
||||
fn bnf(&self) -> Bnf {
|
||||
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
||||
Bnf::Choice(
|
||||
parsers
|
||||
.into_iter()
|
||||
.map(|p| p.bnf().unwrap_or(Bnf::Unknown))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, O, E, P1, P2, P3, P4, P5> Choice<I, O, E> for (P1, P2, P3, P4, P5)
|
||||
@ -82,6 +116,22 @@ where
|
||||
];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
|
||||
fn bnf(&self) -> Bnf {
|
||||
let parsers = vec![
|
||||
&self.0 as &dyn Parser<I, O, E>,
|
||||
&self.1,
|
||||
&self.2,
|
||||
&self.3,
|
||||
&self.4,
|
||||
];
|
||||
Bnf::Choice(
|
||||
parsers
|
||||
.into_iter()
|
||||
.map(|p| p.bnf().unwrap_or(Bnf::Unknown))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, O, E, P1, P2, P3, P4, P5, P6> Choice<I, O, E> for (P1, P2, P3, P4, P5, P6)
|
||||
@ -105,6 +155,23 @@ where
|
||||
];
|
||||
choice_loop(input, parsers)
|
||||
}
|
||||
|
||||
fn bnf(&self) -> Bnf {
|
||||
let parsers = vec![
|
||||
&self.0 as &dyn Parser<I, O, E>,
|
||||
&self.1,
|
||||
&self.2,
|
||||
&self.3,
|
||||
&self.4,
|
||||
&self.5,
|
||||
];
|
||||
Bnf::Choice(
|
||||
parsers
|
||||
.into_iter()
|
||||
.map(|p| p.bnf().unwrap_or(Bnf::Unknown))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn choice_loop<I, O, E>(input: I, parsers: Vec<&dyn Parser<I, O, E>>) -> ParseResult<I, O, E>
|
||||
|
@ -5,6 +5,8 @@ mod parser;
|
||||
pub mod primitives;
|
||||
pub mod sequence;
|
||||
|
||||
#[cfg(test)]
|
||||
use bnf::Bnf;
|
||||
pub use parser::{ParseResult, Parser, ParserInput};
|
||||
|
||||
#[cfg(test)]
|
||||
@ -221,4 +223,10 @@ mod tests {
|
||||
let parsed_json = json_object().parse(test_json);
|
||||
assert!(parsed_json.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bnf_representation() {
|
||||
let bnf = json_object().bnf().unwrap();
|
||||
assert_eq!(bnf, Bnf::Production);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ where
|
||||
inner: Box::new(inner),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'a, I: ParserInput, O, E> Parser<I, O, E> for BoxedParser<'a, I, O, E> {
|
||||
@ -32,7 +31,10 @@ impl<'a, I: ParserInput, O, E> Parser<I, O, E> for BoxedParser<'a, I, O, E> {
|
||||
self.inner.bnf()
|
||||
}
|
||||
|
||||
fn boxed<'b>(self) -> BoxedParser<'b, I, O, E> where Self: Sized + 'b {
|
||||
fn boxed<'b>(self) -> BoxedParser<'b, I, O, E>
|
||||
where
|
||||
Self: Sized + 'b,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,10 @@ where
|
||||
None
|
||||
}
|
||||
|
||||
fn boxed<'a>(self) -> BoxedParser<'a, I, O, E> where Self: Sized + 'a {
|
||||
fn boxed<'a>(self) -> BoxedParser<'a, I, O, E>
|
||||
where
|
||||
Self: Sized + 'a,
|
||||
{
|
||||
BoxedParser::new(self)
|
||||
}
|
||||
|
||||
@ -71,8 +74,7 @@ where
|
||||
E: 'a,
|
||||
P: Parser<I, O2, E> + 'a,
|
||||
{
|
||||
crate::sequence::tuple2(self, next_parser)
|
||||
.map(|(_, next_output)| next_output)
|
||||
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>
|
||||
@ -84,8 +86,7 @@ where
|
||||
E: 'a,
|
||||
P: Parser<I, O2, E> + 'a,
|
||||
{
|
||||
crate::sequence::tuple2(self, next_parser)
|
||||
.map(|(this_output, _)| this_output)
|
||||
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>
|
||||
@ -149,12 +150,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: ParserInput, O, E, F> Parser<I, O, E> for (F, Bnf)
|
||||
impl<I: ParserInput, O, E, P> Parser<I, O, E> for (P, Bnf)
|
||||
where
|
||||
F: Fn(I) -> ParseResult<I, O, E>,
|
||||
P: Parser<I, O, E>,
|
||||
{
|
||||
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
||||
self.0(input)
|
||||
self.0.parse(input)
|
||||
}
|
||||
|
||||
fn bnf(&self) -> Option<Bnf> {
|
||||
|
Loading…
Reference in New Issue
Block a user