-
Notifications
You must be signed in to change notification settings - Fork 86
/
calc-ast.rs.g
114 lines (81 loc) · 1.71 KB
/
calc-ast.rs.g
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
/**
* Generated parser in Rust.
*
* ./bin/syntax -g examples/calc-ast.rs.g -m lalr1 -o lib.rs
*
* use syntax::Parser;
*
* let parser = Parser::new();
*
* let ast = parser.parse("2 + 2 * 2");
*/
%lex
%%
\s+ /* skip whitespace */ return "";
\d+ return "NUMBER";
"+" return "+";
"*" return "*";
"(" return "(";
")" return ")";
/lex
%left +
%left *
%{
/**
* Recursive generic `Node` enum structure.
*/
#[derive(Debug)]
pub enum Node {
Literal(i32),
Binary {
op: &'static str,
left: Box<Node>,
right: Box<Node>,
},
}
/**
* Final result type returned from `parse` method call.
*/
pub type TResult = Node;
/**
* Hook executed on parse begin.
*/
fn on_parse_begin(_parser: &mut Parser, string: &'static str) {
println!("Parsing: {:?}", string);
}
/**
* Hook executed on parse end.
*/
fn on_parse_end(_parser: &mut Parser, result: &TResult) {
println!("Parsed: {:?}", result);
}
%}
%%
Expr
: Expr + Expr {
// Types of used args ($1, $2, ...), and return type:
|$1: Node; $3: Node| -> Node;
$$ = Node::Binary {
op: "+",
left: Box::new($1),
right: Box::new($3),
}
}
| Expr * Expr {
|$1: Node; $3: Node| -> Node;
$$ = Node::Binary {
op: "*",
left: Box::new($1),
right: Box::new($3),
}
}
| ( Expr ) {
// No need to define argument types, since we don't do any
// operations here, and just propagate $2 further.
$$ = $2;
}
| NUMBER {
|| -> Node;
let n = yytext.parse::<i32>().unwrap();
$$ = Node::Literal(n);
};