-
Notifications
You must be signed in to change notification settings - Fork 14
/
peg-list.rs
57 lines (49 loc) · 1.36 KB
/
peg-list.rs
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
use imstr::ImString;
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
Number(u32),
String(ImString),
}
peg::parser! {
grammar list_parser() for ImString {
rule number() -> u32
= n:$(['0'..='9']+) {? n.parse().or(Err("u32")) }
rule string() -> ImString
= "\"" s:$(['a'..='z']+) "\"" { s }
rule value() -> Value
= n:number() { Value::Number(n) } / s:string() { Value::String(s) }
pub rule list() -> Vec<Value>
= "[" l:(value() ** ",") "]" { l }
}
}
#[test]
fn test_list_parser() {
assert_eq!(
list_parser::list(&ImString::from("[1,1,2,3,5,8]")).unwrap(),
vec![
Value::Number(1),
Value::Number(1),
Value::Number(2),
Value::Number(3),
Value::Number(5),
Value::Number(8)
]
);
assert_eq!(
list_parser::list(&ImString::from("[\"hello\",\"world\",1,2,3]")).unwrap(),
vec![
Value::String("hello".into()),
Value::String("world".into()),
Value::Number(1),
Value::Number(2),
Value::Number(3),
]
);
}
fn main() {
let mut input = std::io::stdin();
let mut data = Vec::new();
std::io::copy(&mut input, &mut data).unwrap();
let string = ImString::from_utf8_lossy(&data).trim();
println!("{:?}", list_parser::list(&string));
}