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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#[macro_use]
extern crate pest_derive;
use pest::Parser;
pub use pest::iterators::Pair;
#[cfg(debug_assertions)]
const _GRAMMAR: &str = include_str!("r7rs.pest");
#[derive(Parser)]
#[grammar = "r7rs.pest"]
pub struct R7Parser;
pub fn parse(content: &str) -> Result<Pair<Rule>, String> {
let parsed = R7Parser::parse(Rule::r7rs, content)
.map_err(|err| err.to_string())?
.next();
if let Some(ast) = parsed {
Ok(ast)
} else {
Err("Empty AST".into())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
fn print_tree(ast: Pair<Rule>, level: u8) {
let padding = String::from_utf8(vec![b' '; 2 * level as usize]).unwrap();
eprintln!("{}{:?} : {:?}", padding, ast.as_rule(), ast.as_str());
for pair in ast.into_inner() {
print_tree(pair, level + 1);
}
}
#[test]
fn parse_bool() {
let parsed = R7Parser::parse(Rule::r7rs, "#t").unwrap().next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
let _ = parse("#t").unwrap();
}
#[test]
fn parse_symbol() {
let parsed = R7Parser::parse(Rule::r7rs, "'hello").unwrap().next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
#[test]
fn parse_symbol_2() {
let parsed = R7Parser::parse(Rule::r7rs, "(quote hello)").unwrap().next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
#[test]
fn parse_symbol_3() {
let parsed = R7Parser::parse(Rule::r7rs, "(quote\nhello)")
.unwrap()
.next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
#[test]
fn parse_ambiguous_funcall() {
let parsed = R7Parser::parse(Rule::r7rs, "(quote\n hello)")
.unwrap()
.next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
#[test]
fn parse_base() {
let base = fs::read_to_string("../lib/scheme/base.sld").expect("cannot read file");
let parsed = R7Parser::parse(Rule::r7rs, &base).unwrap().next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
#[test]
fn parse_comment_only() {
let parsed = R7Parser::parse(Rule::r7rs, ";;hello");
assert!(parsed.is_err());
}
#[test]
fn parse_nested_comment() {
let parsed = R7Parser::parse(Rule::r7rs, "(list #|Not in the list|# stuff)")
.unwrap()
.next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
#[test]
fn parse_bytevector() {
let parsed = R7Parser::parse(Rule::r7rs, "#u8(12 43 98 01 #xDEADBEEF)")
.unwrap()
.next();
eprintln!("Start");
if let Some(pairs) = parsed {
print_tree(pairs, 0);
}
}
}