Compare commits
5 Commits
116e2fc361
...
dfb151e2a3
Author | SHA1 | Date | |
---|---|---|---|
|
dfb151e2a3 | ||
|
9a3745d25c | ||
|
5aca3912fc | ||
|
377d515d40 | ||
|
f15488194c |
@ -1,4 +1,4 @@
|
|||||||
use crate::parser::{ParseResult, Parser, ParserInput};
|
use crate::parser::{ParseResult, Parser, ParserInput, Representation};
|
||||||
|
|
||||||
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
|
||||||
@ -14,11 +14,13 @@ where
|
|||||||
C: Choice<I, O, E>,
|
C: Choice<I, O, E>,
|
||||||
I: ParserInput + Clone,
|
I: ParserInput + Clone,
|
||||||
{
|
{
|
||||||
move |input| choices.parse(input)
|
let rep = choices.representation();
|
||||||
|
(move |input| choices.parse(input), rep)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Choice<I: Clone, O, E> {
|
pub trait Choice<I: Clone, O, E> {
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
||||||
|
fn representation(&self) -> Representation;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, P1, P2> Choice<I, O, E> for (P1, P2)
|
impl<I, O, E, P1, P2> Choice<I, O, E> for (P1, P2)
|
||||||
@ -31,6 +33,11 @@ where
|
|||||||
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];
|
||||||
choice_loop(input, parsers)
|
choice_loop(input, parsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn representation(&self) -> Representation {
|
||||||
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1];
|
||||||
|
repr_loop(parsers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, P1, P2, P3> Choice<I, O, E> for (P1, P2, P3)
|
impl<I, O, E, P1, P2, P3> Choice<I, O, E> for (P1, P2, P3)
|
||||||
@ -44,6 +51,11 @@ where
|
|||||||
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];
|
||||||
choice_loop(input, parsers)
|
choice_loop(input, parsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn representation(&self) -> Representation {
|
||||||
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2];
|
||||||
|
repr_loop(parsers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, P1, P2, P3, P4> Choice<I, O, E> for (P1, P2, P3, P4)
|
impl<I, O, E, P1, P2, P3, P4> Choice<I, O, E> for (P1, P2, P3, P4)
|
||||||
@ -58,6 +70,11 @@ where
|
|||||||
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];
|
||||||
choice_loop(input, parsers)
|
choice_loop(input, parsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn representation(&self) -> Representation {
|
||||||
|
let parsers = vec![&self.0 as &dyn Parser<I, O, E>, &self.1, &self.2, &self.3];
|
||||||
|
repr_loop(parsers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, P1, P2, P3, P4, P5> Choice<I, O, E> for (P1, P2, P3, P4, P5)
|
impl<I, O, E, P1, P2, P3, P4, P5> Choice<I, O, E> for (P1, P2, P3, P4, P5)
|
||||||
@ -79,6 +96,17 @@ where
|
|||||||
];
|
];
|
||||||
choice_loop(input, parsers)
|
choice_loop(input, parsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn representation(&self) -> Representation {
|
||||||
|
let parsers = vec![
|
||||||
|
&self.0 as &dyn Parser<I, O, E>,
|
||||||
|
&self.1,
|
||||||
|
&self.2,
|
||||||
|
&self.3,
|
||||||
|
&self.4,
|
||||||
|
];
|
||||||
|
repr_loop(parsers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, O, E, P1, P2, P3, P4, P5, P6> Choice<I, O, E> for (P1, P2, P3, P4, P5, P6)
|
impl<I, O, E, P1, P2, P3, P4, P5, P6> Choice<I, O, E> for (P1, P2, P3, P4, P5, P6)
|
||||||
@ -102,6 +130,17 @@ where
|
|||||||
];
|
];
|
||||||
choice_loop(input, parsers)
|
choice_loop(input, parsers)
|
||||||
}
|
}
|
||||||
|
fn representation(&self) -> Representation {
|
||||||
|
let parsers = vec![
|
||||||
|
&self.0 as &dyn Parser<I, O, E>,
|
||||||
|
&self.1,
|
||||||
|
&self.2,
|
||||||
|
&self.3,
|
||||||
|
&self.4,
|
||||||
|
&self.5,
|
||||||
|
];
|
||||||
|
repr_loop(parsers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
||||||
@ -122,6 +161,14 @@ where
|
|||||||
Err(err.unwrap())
|
Err(err.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn repr_loop<I, O, E>(parsers: Vec<&dyn Parser<I, O, E>>) -> Representation
|
||||||
|
where
|
||||||
|
I: ParserInput + Clone,
|
||||||
|
{
|
||||||
|
let mut iter = parsers.iter().map(|p| p.representation());
|
||||||
|
Representation::from_choice(&mut iter)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -6,9 +6,11 @@ where
|
|||||||
P: Parser<I, O1, E>,
|
P: Parser<I, O1, E>,
|
||||||
F: Fn(O1) -> O2,
|
F: Fn(O1) -> O2,
|
||||||
{
|
{
|
||||||
move |input| {
|
let rep = parser.representation();
|
||||||
|
let p = move |input| {
|
||||||
parser
|
parser
|
||||||
.parse(input)
|
.parse(input)
|
||||||
.map(|(result, rest)| (map_fn(result), rest))
|
.map(|(result, rest)| (map_fn(result), rest))
|
||||||
}
|
};
|
||||||
|
(p, rep)
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,4 @@ mod parser;
|
|||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
pub mod sequence;
|
pub mod sequence;
|
||||||
|
|
||||||
pub use parser::{ParseResult, Parser, ParserInput};
|
pub use parser::{ParseResult, Parser, ParserInput, Representation};
|
||||||
|
@ -23,7 +23,7 @@ where
|
|||||||
|
|
||||||
impl<'a, I: ParserInput, 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 representation(&self) -> Representation {
|
fn representation(&self) -> Representation {
|
||||||
Representation::new("NOT IMPL'D")
|
self.inner.representation()
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
@ -1,12 +1,34 @@
|
|||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Representation {
|
pub struct Representation {
|
||||||
val: String
|
val: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Representation {
|
impl Representation {
|
||||||
pub fn new(from: &str) -> Self {
|
pub fn new(from: &str) -> Self {
|
||||||
Self { val: from.to_string() }
|
Self {
|
||||||
|
val: from.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_choice(choice_parser_reps: &mut impl Iterator<Item = Representation>) -> Self {
|
||||||
|
let mut buf = String::new();
|
||||||
|
let mut iter = choice_parser_reps.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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,12 @@ pub fn literal_char(expected: char) -> impl Fn(&str) -> ParseResult<&str, char,
|
|||||||
|
|
||||||
pub fn literal<'a>(expected: &'static str) -> impl Parser<&'a str, &'a str, &'a str> {
|
pub fn literal<'a>(expected: &'static str) -> impl Parser<&'a str, &'a str, &'a str> {
|
||||||
println!("literal call expected: {}", expected);
|
println!("literal call expected: {}", expected);
|
||||||
|
let rep = Representation::new(expected);
|
||||||
let p = move |input: &'a str| match input.get(0..expected.len()) {
|
let p = move |input: &'a str| match input.get(0..expected.len()) {
|
||||||
Some(next) if next == expected => Ok((expected, &input[expected.len()..])),
|
Some(next) if next == expected => Ok((expected, &input[expected.len()..])),
|
||||||
_ => Err(input),
|
_ => Err(input),
|
||||||
};
|
};
|
||||||
(p, Representation::new("yolo"))
|
(p, rep)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn any_char(input: &str) -> ParseResult<&str, char, &str> {
|
pub fn any_char(input: &str) -> ParseResult<&str, char, &str> {
|
||||||
@ -50,15 +51,18 @@ where
|
|||||||
F: Fn(&O) -> bool,
|
F: Fn(&O) -> bool,
|
||||||
{
|
{
|
||||||
let orig_rep = parser.representation();
|
let orig_rep = parser.representation();
|
||||||
(move |input| {
|
(
|
||||||
parser.parse(input).and_then(|(result, rest)| {
|
move |input| {
|
||||||
if pred_fn(&result) {
|
parser.parse(input).and_then(|(result, rest)| {
|
||||||
Ok((result, rest))
|
if pred_fn(&result) {
|
||||||
} else {
|
Ok((result, rest))
|
||||||
Err(rest)
|
} else {
|
||||||
}
|
Err(rest)
|
||||||
})
|
}
|
||||||
}, Representation::new(&format!("{:?} if <PREDICATE>", orig_rep)))
|
})
|
||||||
|
},
|
||||||
|
Representation::new(&format!("{:?} if <PREDICATE>", orig_rep)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a standard identifier in a programming language
|
/// Parses a standard identifier in a programming language
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::parser::{ParseResult, Parser, ParserInput};
|
use crate::parser::{ParseResult, Parser, ParserInput, Representation};
|
||||||
|
|
||||||
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
|
||||||
@ -14,7 +14,9 @@ where
|
|||||||
I: ParserInput,
|
I: ParserInput,
|
||||||
T: Sequence<I, O, E>,
|
T: Sequence<I, O, E>,
|
||||||
{
|
{
|
||||||
move |input| sequence.parse(input)
|
let rep = sequence.representation();
|
||||||
|
let p = move |input| sequence.parse(input);
|
||||||
|
(p, rep)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO - eventually rewrite this parser combinator in Schala. Seeing what this
|
/* TODO - eventually rewrite this parser combinator in Schala. Seeing what this
|
||||||
@ -24,6 +26,9 @@ where
|
|||||||
|
|
||||||
pub trait Sequence<I, O, E> {
|
pub trait Sequence<I, O, E> {
|
||||||
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
||||||
|
fn representation(&self) -> Representation {
|
||||||
|
Representation::new("SEQ NOT DONE YET")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -3,6 +3,7 @@ use parser_combinator::combinators::repeated;
|
|||||||
use parser_combinator::primitives::{any_char, literal, literal_char, one_of, pred};
|
use parser_combinator::primitives::{any_char, literal, literal_char, one_of, pred};
|
||||||
use parser_combinator::sequence::seq;
|
use parser_combinator::sequence::seq;
|
||||||
use parser_combinator::Parser;
|
use parser_combinator::Parser;
|
||||||
|
use parser_combinator::Representation;
|
||||||
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ impl<'a, T, P> JsonParser<'a, T> for P where P: Parser<&'a str, T, &'a str> {}
|
|||||||
fn json_null<'a>() -> impl JsonParser<'a, JsonValue> {
|
fn json_null<'a>() -> impl JsonParser<'a, JsonValue> {
|
||||||
literal("null").to(JsonValue::Null)
|
literal("null").to(JsonValue::Null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn json_bool<'a>() -> impl JsonParser<'a, JsonValue> {
|
fn json_bool<'a>() -> impl JsonParser<'a, JsonValue> {
|
||||||
choice((
|
choice((
|
||||||
literal("true").to(JsonValue::Bool(true)),
|
literal("true").to(JsonValue::Bool(true)),
|
||||||
@ -61,8 +63,13 @@ fn json_bool<'a>() -> impl JsonParser<'a, JsonValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn json_number<'a>() -> impl JsonParser<'a, JsonValue> {
|
fn json_number<'a>() -> impl JsonParser<'a, JsonValue> {
|
||||||
let digit = || one_of("1234567890");
|
fn digit<'a>() -> impl JsonParser<'a, &'a str> {
|
||||||
let digits = || repeated(digit()).at_least(1);
|
one_of("1234567890")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn digits<'a>() -> impl JsonParser<'a, Vec<&'a str>> {
|
||||||
|
repeated(digit()).at_least(1)
|
||||||
|
}
|
||||||
|
|
||||||
let json_number_inner = choice((
|
let json_number_inner = choice((
|
||||||
seq((digits(), literal(".").ignore_then(digits()).optional())).map(
|
seq((digits(), literal(".").ignore_then(digits()).optional())).map(
|
||||||
@ -229,3 +236,13 @@ fn parse_json_document() {
|
|||||||
let parsed_json = json_object().parse(test_json);
|
let parsed_json = json_object().parse(test_json);
|
||||||
assert!(parsed_json.is_ok());
|
assert!(parsed_json.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_representations() {
|
||||||
|
assert_eq!(json_null().representation(), Representation::new("null"));
|
||||||
|
assert_eq!(
|
||||||
|
json_bool().representation(),
|
||||||
|
Representation::new("true | false")
|
||||||
|
);
|
||||||
|
assert_eq!(json_number().representation(), Representation::new("null"));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user