2022-10-15 23:36:04 -07:00
|
|
|
#![allow(dead_code)] //TODO eventually turn this off
|
2024-01-26 00:07:52 -08:00
|
|
|
mod choice;
|
2024-01-26 00:20:57 -08:00
|
|
|
mod combinators;
|
2024-01-26 00:13:05 -08:00
|
|
|
mod map;
|
2024-01-26 00:07:52 -08:00
|
|
|
mod primitives;
|
|
|
|
mod sequence;
|
|
|
|
|
|
|
|
pub use choice::*;
|
2024-01-26 00:20:57 -08:00
|
|
|
pub use combinators::*;
|
2024-01-26 00:13:05 -08:00
|
|
|
pub use map::*;
|
2024-01-26 00:07:52 -08:00
|
|
|
pub use primitives::*;
|
|
|
|
pub use sequence::*;
|
2022-10-15 23:36:04 -07:00
|
|
|
|
|
|
|
type ParseResult<I, O, E> = Result<(O, I), E>;
|
|
|
|
|
2024-01-26 00:07:52 -08:00
|
|
|
pub trait Parser<I, O, E> {
|
2022-10-15 23:36:04 -07:00
|
|
|
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
|
|
|
}
|
|
|
|
|
2024-01-25 15:38:29 -08:00
|
|
|
impl<I, O, E, F> Parser<I, O, E> for F
|
|
|
|
where
|
|
|
|
F: Fn(I) -> ParseResult<I, O, E>,
|
|
|
|
{
|
2022-10-15 23:36:04 -07:00
|
|
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
|
|
|
self(input)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-10 00:13:39 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
2022-10-15 23:36:04 -07:00
|
|
|
fn parsing() {
|
2024-01-25 15:38:29 -08:00
|
|
|
let (parsed, rest) = literal("a")("a yolo").unwrap();
|
|
|
|
assert_eq!(parsed, "a");
|
|
|
|
assert_eq!(rest, " yolo");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_sequence() {
|
|
|
|
let parser = sequence(literal("bongo"), sequence(literal(" "), literal("jonzzz")));
|
|
|
|
let output = parser.parse("bongo jonzzz").unwrap();
|
|
|
|
assert_eq!(output.0 .0, "bongo");
|
|
|
|
assert_eq!(output.0 .1, (" ", "jonzzz"));
|
|
|
|
assert_eq!(output.1, "");
|
2022-10-10 00:13:39 -07:00
|
|
|
}
|
2024-01-26 00:07:52 -08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_choice() {
|
|
|
|
let a = literal("bongo");
|
|
|
|
let b = literal("sucy");
|
|
|
|
let c = literal("ara");
|
|
|
|
let inputs = [&a as &dyn Parser<&str, &str, &str>, &b, &c];
|
|
|
|
let parser = choice(&inputs);
|
|
|
|
|
|
|
|
let output = parser.parse("ara hajimete").unwrap();
|
|
|
|
assert_eq!(("ara", " hajimete"), output);
|
|
|
|
}
|
2024-01-26 00:13:05 -08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_map() {
|
|
|
|
let parser = map(
|
|
|
|
sequence(literal("a"), literal("b")),
|
|
|
|
|(_a, _b): (&str, &str)| 59,
|
|
|
|
);
|
|
|
|
let output = parser.parse("abcd").unwrap();
|
|
|
|
assert_eq!((59, "cd"), output);
|
|
|
|
}
|
2022-10-10 00:13:39 -07:00
|
|
|
}
|