1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#![allow(dead_code)]
use mon::{
Parser, ParserIter, alpha1, alphanumeric, alphanumeric1, input::InputIter, numeric1, tag,
whitespace,
};
#[derive(Debug)]
enum Sexpr {
List(Vec<Sexpr>),
Atom(String),
String(String),
Int(i64),
}
fn atom<'a>() -> impl Parser<&'a str, Output = Sexpr> {
alpha1()
.and(alphanumeric())
.recognize()
.map(|output: &str| Sexpr::Atom(output.to_string()))
}
fn string<'a>() -> impl Parser<&'a str, Output = Sexpr> {
alphanumeric1()
.delimited_by(tag("\""), tag("\""))
.map(|output: &str| Sexpr::String(output.to_string()))
}
fn int<'a>() -> impl Parser<&'a str, Output = Sexpr> {
numeric1().map(|output: &str| Sexpr::Int(output.parse().unwrap()))
}
// Recursive parsers must avoid an infinite loop, you can do this
// by returning a closure that accepts an InputIter and returns ParserResult.
fn sexpr<'a>() -> impl Parser<&'a str, Output = Sexpr> {
|it| {
sexpr()
.separated_by(whitespace())
.many()
.delimited_by(tag("("), tag(")"))
.map(|output| Sexpr::List(output))
.or(atom())
.or(string())
.or(int())
.parse(it)
}
}
#[test]
fn test_atom() {
let input = "atom";
let it = InputIter::new(input);
atom().check_finished(it).unwrap();
}
#[test]
fn test_string() {
let input = r#""string""#;
let it = InputIter::new(input);
string().check_finished(it).unwrap()
}
#[test]
fn test_sexpr() {
let input = r#"(let ((a "hello") (b 2)))"#;
let it = InputIter::new(input);
dbg!(sexpr().parse_finished(it).unwrap());
}
|