diff --git a/src/combinators/optional.rs b/src/combinators/optional.rs index c630268..cd6e636 100644 --- a/src/combinators/optional.rs +++ b/src/combinators/optional.rs @@ -1,12 +1,17 @@ -use crate::parser::{Parser, ParserInput}; +use crate::parser::{Parser, ParserInput, Representation}; pub fn optional(parser: P) -> impl Parser, E> where P: Parser, I: ParserInput + Clone, { - move |input: I| match parser.parse(input.clone()) { + let rep = Representation::from_choice( + &mut [parser.representation(), Representation::new("ε")].into_iter(), + ); + let p = move |input: I| match parser.parse(input.clone()) { Ok((output, rest)) => Ok((Some(output), rest)), Err(_e) => Ok((None, input)), - } + }; + + (p, rep) } diff --git a/src/combinators/repeated.rs b/src/combinators/repeated.rs index 295d3fd..c25f3c3 100644 --- a/src/combinators/repeated.rs +++ b/src/combinators/repeated.rs @@ -85,6 +85,10 @@ where } fn representation(&self) -> Representation { - Representation::new("NOT IMPL'D") + Representation::repeated( + self.inner_parser.representation(), + self.at_least.unwrap_or(0), + self.at_most.unwrap_or(u16::MAX), + ) } } diff --git a/src/combinators/separated_by.rs b/src/combinators/separated_by.rs index 7cb2ba1..d60cd23 100644 --- a/src/combinators/separated_by.rs +++ b/src/combinators/separated_by.rs @@ -15,7 +15,7 @@ where I: ParserInput + Clone + 'a, { fn representation(&self) -> Representation { - Representation::new("NOT IMPL'D") + Representation::new("sepby") } fn parse(&self, input: I) -> ParseResult, I> { diff --git a/src/parser/named_parser.rs b/src/parser/named_parser.rs index 94a651d..7c5f9c5 100644 --- a/src/parser/named_parser.rs +++ b/src/parser/named_parser.rs @@ -27,7 +27,7 @@ where impl<'a, I: ParserInput, O, E> Parser for NamedParser<'a, I, O, E> { fn representation(&self) -> Representation { - Representation::new("NOT IMPL'D") + self.inner_parser.representation() } fn parse(&self, input: I) -> ParseResult { diff --git a/src/parser/representation.rs b/src/parser/representation.rs index cc88680..bc5ecc2 100644 --- a/src/parser/representation.rs +++ b/src/parser/representation.rs @@ -10,7 +10,9 @@ impl Representation { } } - pub fn from_choice(choice_parser_reps: &mut impl Iterator) -> Self { + pub(crate) fn from_choice( + choice_parser_reps: &mut impl Iterator, + ) -> Self { let mut buf = String::new(); let mut iter = choice_parser_reps.peekable(); loop { @@ -31,4 +33,34 @@ impl Representation { Representation::new(&buf) } + + pub(crate) fn from_sequence( + sequence_representations: &mut impl Iterator, + ) -> Self { + let mut buf = String::new(); + let mut iter = sequence_representations.peekable(); + loop { + let rep = match iter.next() { + Some(r) => r, + None => break, + }; + buf.push_str(&rep.val); + match iter.peek() { + Some(_) => { + buf.push_str(" "); + } + None => { + break; + } + } + } + + Representation::new(&buf) + } + + // TODO use at_least, at_most + pub(crate) fn repeated(underlying: Representation, at_least: u16, _at_most: u16) -> Self { + let sigil = if at_least == 0 { "*" } else { "+" }; + Representation::new(&format!("({}){}", underlying.val, sigil)) + } } diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs index a982a51..cab1ad9 100644 --- a/src/sequence/mod.rs +++ b/src/sequence/mod.rs @@ -26,9 +26,7 @@ where pub trait Sequence { fn parse(&self, input: I) -> ParseResult; - fn representation(&self) -> Representation { - Representation::new("SEQ NOT DONE YET") - } + fn representation(&self) -> Representation; } impl Sequence for (P1, P2) @@ -46,6 +44,11 @@ where .map(|(result2, rest2)| ((result1, result2), rest2)) }) } + + fn representation(&self) -> Representation { + let mut iter = [self.0.representation(), self.1.representation()].into_iter(); + Representation::from_sequence(&mut iter) + } } impl Sequence for (P1, P2, P3) @@ -66,6 +69,16 @@ where Ok(((result1, result2, result3), rest3)) } + + fn representation(&self) -> Representation { + let mut iter = [ + self.0.representation(), + self.1.representation(), + self.2.representation(), + ] + .into_iter(); + Representation::from_sequence(&mut iter) + } } impl Sequence for (P1, P2, P3, P4) @@ -89,6 +102,17 @@ where Ok(((result1, result2, result3, result4), rest4)) } + + fn representation(&self) -> Representation { + let mut iter = [ + self.0.representation(), + self.1.representation(), + self.2.representation(), + self.3.representation(), + ] + .into_iter(); + Representation::from_sequence(&mut iter) + } } impl Sequence @@ -116,6 +140,18 @@ where Ok(((result1, result2, result3, result4, result5), rest5)) } + + fn representation(&self) -> Representation { + let mut iter = [ + self.0.representation(), + self.1.representation(), + self.2.representation(), + self.3.representation(), + self.4.representation(), + ] + .into_iter(); + Representation::from_sequence(&mut iter) + } } #[cfg(test)] diff --git a/tests/json_parser.rs b/tests/json_parser.rs index d7b4971..95d4972 100644 --- a/tests/json_parser.rs +++ b/tests/json_parser.rs @@ -244,5 +244,5 @@ fn test_representations() { json_bool().representation(), Representation::new("true | false") ); - assert_eq!(json_number().representation(), Representation::new("null")); + assert_eq!(json_number().representation(), Representation::new("- | ε (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | )+ . (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | )+ | ε | . (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | )+")); }