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
use pest::Parser;
use pest::iterators::Pair;
use pest::inputs::StrInput;
use ast::Expression;
use std::f64;
const _GRAMMAR: &'static 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();
panic!("Nth(0): {:?}, Nth(1): {:?}, Nth(2): {:?}", pairs.nth(0), pairs.nth(1), pairs.nth(2));
Expression::FuncLiteral(
format!("{}", pairs.nth(0).unwrap().into_span().as_str()),
Box::new(parse_expression(pairs.nth(1).unwrap())),
Box::new(parse_expression(pairs.nth(2).unwrap()))
)
}
Rule::function_call_literal => {
let mut pairs = input.into_inner();
println!("{:?}", pairs);
Expression::FuncCall(
format!("{}", pairs.nth(0).unwrap().into_span().as_str()),
Some(Box::new(parse_expression(pairs.nth(2).unwrap())))
)
}
Rule::boolean_literal =>
Expression::Boolean(
input.into_span().as_str().parse::<bool>().unwrap()
),
Rule::string_literal =>
Expression::String(format!("{}", input.into_span().as_str())
),
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())
),
Rule::list_literal =>
Expression::List(input
.into_inner()
.into_iter()
.map(|r| Box::new(parse_expression(r)))
.collect()),
_ => unreachable!()
}
}
pub fn parse(input: String) -> 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))
}
}