From 2fd8b1be164d653c7e85704a662b1d0d0be50357 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sun, 22 Jan 2023 14:25:10 -0800 Subject: [PATCH] Representation work --- src/combinators/repeated.rs | 6 +++++- src/combinators/separated_by.rs | 6 +++++- src/parser/boxed_parser.rs | 5 ++++- src/parser/mod.rs | 25 +++++++++++++++++++++++++ src/parser/named_parser.rs | 6 +++++- src/parser/representation.rs | 12 ++++++++++++ src/primitives/mod.rs | 25 ++++++++++++++++++------- tests/json_parser.rs | 2 +- 8 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 src/parser/representation.rs diff --git a/src/combinators/repeated.rs b/src/combinators/repeated.rs index 4dac5b1..295d3fd 100644 --- a/src/combinators/repeated.rs +++ b/src/combinators/repeated.rs @@ -1,5 +1,5 @@ use crate::combinators::separated_by::SeparatedBy; -use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput}; +use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput, Representation}; pub fn repeated<'a, P, I, O>(parser: P) -> Repeated<'a, I, O> where @@ -83,4 +83,8 @@ where Ok((results, further_input)) } + + fn representation(&self) -> Representation { + Representation::new("NOT IMPL'D") + } } diff --git a/src/combinators/separated_by.rs b/src/combinators/separated_by.rs index 3c2350b..7cb2ba1 100644 --- a/src/combinators/separated_by.rs +++ b/src/combinators/separated_by.rs @@ -1,5 +1,5 @@ use crate::combinators::repeated::Repeated; -use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput}; +use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput, Representation}; pub struct SeparatedBy<'a, I, O> where @@ -14,6 +14,10 @@ impl<'a, I, O> Parser, I> for SeparatedBy<'a, I, O> where I: ParserInput + Clone + 'a, { + fn representation(&self) -> Representation { + Representation::new("NOT IMPL'D") + } + fn parse(&self, input: I) -> ParseResult, I> { let at_least = self.inner_repeated.at_least.unwrap_or(0); let at_most = self.inner_repeated.at_most.unwrap_or(u16::MAX); diff --git a/src/parser/boxed_parser.rs b/src/parser/boxed_parser.rs index e59da3f..a2b9712 100644 --- a/src/parser/boxed_parser.rs +++ b/src/parser/boxed_parser.rs @@ -1,4 +1,4 @@ -use crate::parser::{ParseResult, Parser, ParserInput}; +use crate::parser::{ParseResult, Parser, ParserInput, Representation}; pub struct BoxedParser<'a, I, O, E> where @@ -22,6 +22,9 @@ where } impl<'a, I: ParserInput, O, E> Parser for BoxedParser<'a, I, O, E> { + fn representation(&self) -> Representation { + Representation::new("NOT IMPL'D") + } fn parse(&self, input: I) -> ParseResult { self.inner.parse(input) } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index e0c8eb3..cb540e9 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,12 +1,14 @@ 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>; @@ -16,6 +18,8 @@ where { fn parse(&self, input: I) -> ParseResult; + fn representation(&self) -> Representation; + fn boxed<'a>(self) -> BoxedParser<'a, I, O, E> where Self: Sized + 'a, @@ -141,6 +145,23 @@ where 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 @@ -151,4 +172,8 @@ where fn parse(&self, input: I) -> ParseResult { self.as_ref().parse(input) } + + fn representation(&self) -> Representation { + self.as_ref().representation() + } } diff --git a/src/parser/named_parser.rs b/src/parser/named_parser.rs index d035412..94a651d 100644 --- a/src/parser/named_parser.rs +++ b/src/parser/named_parser.rs @@ -1,5 +1,5 @@ use super::boxed_parser::BoxedParser; -use crate::parser::{ParseResult, Parser, ParserInput}; +use crate::parser::{ParseResult, Parser, ParserInput, Representation}; pub struct NamedParser<'a, I, O, E> where @@ -26,6 +26,10 @@ where } impl<'a, I: ParserInput, O, E> Parser for NamedParser<'a, I, O, E> { + fn representation(&self) -> Representation { + Representation::new("NOT IMPL'D") + } + fn parse(&self, input: I) -> ParseResult { self.inner_parser.parse(input) } diff --git a/src/parser/representation.rs b/src/parser/representation.rs new file mode 100644 index 0000000..7f0e10d --- /dev/null +++ b/src/parser/representation.rs @@ -0,0 +1,12 @@ + + +#[derive(Debug, Clone)] +pub struct Representation { + val: String +} + +impl Representation { + pub fn new(from: &str) -> Self { + Self { val: from.to_string() } + } +} diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs index 13bd273..f8ed2fc 100644 --- a/src/primitives/mod.rs +++ b/src/primitives/mod.rs @@ -1,4 +1,4 @@ -use crate::parser::{ParseResult, Parser, ParserInput}; +use crate::parser::{ParseResult, Parser, ParserInput, Representation}; pub fn literal_char(expected: char) -> impl Fn(&str) -> ParseResult<&str, char, &str> { move |input| match input.chars().next() { @@ -7,11 +7,13 @@ pub fn literal_char(expected: char) -> impl Fn(&str) -> ParseResult<&str, char, } } -pub fn literal(expected: &'static str) -> impl Fn(&str) -> ParseResult<&str, &str, &str> { - move |input| match input.get(0..expected.len()) { +pub fn literal<'a>(expected: &'static str) -> impl Parser<&'a str, &'a str, &'a str> { + println!("literal call expected: {}", expected); + let p = move |input: &'a str| match input.get(0..expected.len()) { Some(next) if next == expected => Ok((expected, &input[expected.len()..])), _ => Err(input), - } + }; + (p, Representation::new("yolo")) } pub fn any_char(input: &str) -> ParseResult<&str, char, &str> { @@ -22,7 +24,7 @@ pub fn any_char(input: &str) -> ParseResult<&str, char, &str> { } pub fn one_of<'a>(items: &'static str) -> impl Parser<&'a str, &'a str, &'a str> { - move |input: &'a str| { + let p = move |input: &'a str| { if let Some(ch) = input.chars().next() { if items.contains(ch) { let (first, rest) = input.split_at(1); @@ -30,7 +32,15 @@ pub fn one_of<'a>(items: &'static str) -> impl Parser<&'a str, &'a str, &'a str> } } Err(input) + }; + + let mut s = String::new(); + for ch in items.chars() { + s.push(ch); + s.push_str(" | "); } + let rep = Representation::new(&s); + (p, rep) } pub fn pred(parser: P, pred_fn: F) -> impl Parser @@ -39,7 +49,8 @@ where P: Parser, F: Fn(&O) -> bool, { - move |input| { + let orig_rep = parser.representation(); + (move |input| { parser.parse(input).and_then(|(result, rest)| { if pred_fn(&result) { Ok((result, rest)) @@ -47,7 +58,7 @@ where Err(rest) } }) - } + }, Representation::new(&format!("{:?} if ", orig_rep))) } /// Parses a standard identifier in a programming language diff --git a/tests/json_parser.rs b/tests/json_parser.rs index 647f8a1..fc20614 100644 --- a/tests/json_parser.rs +++ b/tests/json_parser.rs @@ -25,7 +25,7 @@ proptest! { #[test] fn test_parsing() { - let output = literal("a")("a yolo"); + let output = literal("a").parse("a yolo"); assert_eq!(output.unwrap(), ("a", " yolo")); }