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
use pest::Parser;
use pest::iterators::Pair;
use pest::inputs::StrInput;
use ast::Expression;
use std::f64;
const _GRAMMAR: &str = include_str!("grammar/grammar.pest");
#[derive(Parser)]
#[grammar = "grammar/grammar.pest"]
pub struct ExpressionParser;
fn parse_expression(input: Pair<Rule, StrInput>) -> Expression {
match input.as_rule() {
Rule::function_literal => {
let mut pairs = input.into_inner();
let name = pairs
.next()
.unwrap()
.into_span()
.as_str()
.to_string();
let args_list = pairs
.next()
.unwrap()
.into_inner()
.into_iter()
.map(|r| r.into_span().as_str().to_string())
.collect();
let body = Box::new(
parse_expression(pairs.next().unwrap()));
Expression::FuncLiteral(name, args_list, body)
}
Rule::function_call_literal => {
let mut pairs = input.into_inner();
let name = pairs
.next()
.unwrap()
.into_span()
.as_str()
.to_string();
let args = pairs
.into_iter()
.map(|r| Box::new(parse_expression(r)))
.collect();
Expression::FuncCall(name, args)
}
Rule::list_literal =>
Expression::List(input
.into_inner()
.into_iter()
.map(|r| Box::new(parse_expression(r)))
.collect()),
Rule::boolean_literal =>
Expression::Boolean(
input.into_span().as_str().parse::<bool>().unwrap()
),
Rule::string_literal =>
Expression::String(input.into_span().as_str().to_string()),
Rule::identifier_literal =>
Expression::Identifier(input.into_span().as_str().to_string()),
Rule::decimal_digits_literal =>
Expression::Number(
input.into_span().as_str().parse::<f64>().unwrap()
),
Rule::binary_digits_literal =>
Expression::Number(
f64::from(i32::from_str_radix(&input.into_span().as_str()[2..], 2).unwrap())
),
Rule::oct_digits_literal =>
Expression::Number(
f64::from(i32::from_str_radix(&input.into_span().as_str()[2..], 8).unwrap())
),
Rule::hex_digits_literal =>
Expression::Number(
f64::from(i32::from_str_radix(&input.into_span().as_str()[2..], 16).unwrap())
),
_ => unreachable!()
}
}
pub fn parse(input: &str) -> Result<Expression, String> {
match ExpressionParser::parse_str(Rule::main, input) {
Ok(mut pair) => Ok(parse_expression(
pair.nth(0).unwrap().into_inner().nth(0).unwrap(),
)),
Err(e) => Err(format!("{}", e)),
}
}