1
1
use super :: tokenizer:: { TokenList , OperationKind , ParenthesesKind } ;
2
2
use super :: error:: error_exit;
3
3
4
+ pub enum PrimaryNodeKind {
5
+ Number ( i32 ) ,
6
+ Variable ( char , i32 ) , // (variablename, offset from bsp)
7
+ }
8
+
4
9
pub enum ASTNodeKind {
5
10
Operation ( OperationKind ) ,
6
- Number ( i32 ) ,
11
+ Primary ( PrimaryNodeKind ) ,
12
+ Assign ,
7
13
}
8
14
9
15
pub struct ASTNode {
@@ -13,9 +19,9 @@ pub struct ASTNode {
13
19
}
14
20
15
21
impl ASTNode {
16
- fn new_num_node ( num : i32 ) -> ASTNode {
22
+ fn new_primary_node ( primary_node : PrimaryNodeKind ) -> ASTNode {
17
23
ASTNode {
18
- node_kind : ASTNodeKind :: Number ( num ) ,
24
+ node_kind : ASTNodeKind :: Primary ( primary_node ) ,
19
25
left : None ,
20
26
right : None ,
21
27
}
@@ -29,23 +35,37 @@ impl ASTNode {
29
35
}
30
36
}
31
37
38
+ fn new_assign_node ( ) -> ASTNode {
39
+ ASTNode {
40
+ node_kind : ASTNodeKind :: Assign ,
41
+ left : None ,
42
+ right : None ,
43
+ }
44
+ }
45
+
32
46
// ASTNodeを更新
33
47
fn add_neighbor_node ( & mut self , left : Link , right : Link ) {
34
48
self . left = left;
35
49
self . right = right;
36
50
}
37
51
}
38
52
39
- // AST 生成規則
40
- // expr = equality
41
- // equality = relational ("==" relational | "!=" relational)*
42
- // relational = add ("<" add | "<=" add | ">" add | ">=" add)*
43
- // add = mul ("+" mul | "-" mul)*
44
- // mul = unary ("*" unary | "/" unary)*
45
- // unary = ("+" | "-")? primary
46
- // primary = num | "(" expr ")"
53
+ /*
54
+ AST 生成規則
55
+ program = stmt*
56
+ stmt = expr ";"
57
+ expr = assign
58
+ assign = equality ("=" assign)?
59
+ equality = relational ("==" relational | "!=" relational)*
60
+ relational = add ("<" add | "<=" add | ">" add | ">=" add)*
61
+ add = mul ("+" mul | "-" mul)*
62
+ mul = unary ("*" unary | "/" unary)*
63
+ unary = ("+" | "-")? primary
64
+ primary = num | ident | "(" expr ")"
65
+ */
47
66
48
67
type Link = Option < Box < ASTNode > > ;
68
+ // ;で区切られた領域のASTを作成する
49
69
pub struct AST {
50
70
pub root : Link ,
51
71
}
@@ -56,18 +76,27 @@ impl AST {
56
76
let ast_tree = AST {
57
77
root : AST :: expr ( token_list) ,
58
78
} ;
59
- // トークン連想配列が空でない場合、exprでNode化できていないトークンがあるのでエラーにする
60
- if !token_list. is_empty ( ) {
61
- let rem_token = token_list. head . take ( ) . unwrap ( ) ;
62
- error_exit ( "this token is invalid" , rem_token. token_pos , & token_list. raw_text ) ;
63
- }
64
79
ast_tree
65
80
}
66
81
82
+ // expr = assign
67
83
fn expr ( token_list : & mut TokenList ) -> Link {
68
- AST :: equality ( token_list)
84
+ AST :: assign ( token_list)
69
85
}
70
86
87
+ // assign = equality ("=" assign)?
88
+ fn assign ( token_list : & mut TokenList ) -> Link {
89
+ let mut assign_node = AST :: equality ( token_list) ;
90
+
91
+ if token_list. consume_assign ( ) {
92
+ let mut new_node = ASTNode :: new_assign_node ( ) ;
93
+ new_node. add_neighbor_node ( assign_node. take ( ) , AST :: assign ( token_list) ) ;
94
+ assign_node = Some ( Box :: new ( new_node) ) ;
95
+ }
96
+ assign_node
97
+ }
98
+
99
+ // equality = relational ("==" relational | "!=" relational)*
71
100
fn equality ( token_list : & mut TokenList ) -> Link {
72
101
let mut equality_node = AST :: relational ( token_list) ;
73
102
@@ -87,6 +116,7 @@ impl AST {
87
116
equality_node
88
117
}
89
118
119
+ // relational = add ("<" add | "<=" add | ">" add | ">=" add)*
90
120
fn relational ( token_list : & mut TokenList ) -> Link {
91
121
let mut relational_node = AST :: add ( token_list) ;
92
122
@@ -115,6 +145,7 @@ impl AST {
115
145
relational_node
116
146
}
117
147
148
+ // add = mul ("+" mul | "-" mul)*
118
149
fn add ( token_list : & mut TokenList ) -> Link {
119
150
let mut expr_node = AST :: mul ( token_list) ;
120
151
@@ -134,6 +165,7 @@ impl AST {
134
165
expr_node
135
166
}
136
167
168
+ // mul = unary ("*" unary | "/" unary)*
137
169
fn mul ( token_list : & mut TokenList ) -> Link {
138
170
let mut mul_node = AST :: urany ( token_list) ;
139
171
@@ -153,19 +185,21 @@ impl AST {
153
185
mul_node
154
186
}
155
187
188
+ // unary = ("+" | "-")? primary
156
189
fn urany ( token_list : & mut TokenList ) -> Link {
157
190
if token_list. consume_operation ( OperationKind :: Add ) {
158
191
return AST :: primary ( token_list) ;
159
192
}
160
193
if token_list. consume_operation ( OperationKind :: Sub ) {
161
194
let mut new_node = ASTNode :: new_operand_node ( OperationKind :: Sub ) ;
162
- let zoro_node = ASTNode :: new_num_node ( 0 ) ;
195
+ let zoro_node = ASTNode :: new_primary_node ( PrimaryNodeKind :: Number ( 0 ) ) ;
163
196
new_node. add_neighbor_node ( Some ( Box :: new ( zoro_node) ) , AST :: primary ( token_list) ) ;
164
197
return Some ( Box :: new ( new_node) ) ;
165
198
}
166
199
return AST :: primary ( token_list) ;
167
200
}
168
201
202
+ // primary = num | ident | "(" expr ")"
169
203
fn primary ( token_list : & mut TokenList ) -> Link {
170
204
if token_list. comsume_parentheses ( ParenthesesKind :: LeftParentheses ) {
171
205
let node = AST :: expr ( token_list) ;
@@ -181,7 +215,43 @@ impl AST {
181
215
}
182
216
}
183
217
}
184
- return Some ( Box :: new ( ASTNode :: new_num_node ( token_list. expect_number ( ) ) ) ) ;
218
+ return Some ( Box :: new ( ASTNode :: new_primary_node ( token_list. expect_primary ( ) ) ) ) ;
219
+ }
220
+ }
221
+
222
+ /*
223
+ AST 生成規則
224
+ program = stmt*
225
+ stmt = expr ";"
226
+ expr = assign
227
+ assign = equality ("=" assign)?
228
+ equality = relational ("==" relational | "!=" relational)*
229
+ relational = add ("<" add | "<=" add | ">" add | ">=" add)*
230
+ add = mul ("+" mul | "-" mul)*
231
+ mul = unary ("*" unary | "/" unary)*
232
+ unary = ("+" | "-")? primary
233
+ primary = num | ident | "(" expr ")"
234
+ */
235
+ // ASTはstmt単位で作成し,
236
+ // ASTのリストをASTVecとして保存する
237
+ pub struct ASTVec {
238
+ pub vec : Vec < AST > ,
239
+ }
240
+
241
+ impl ASTVec {
242
+ fn new ( ) -> ASTVec {
243
+ ASTVec {
244
+ vec : vec ! ( ) ,
245
+ }
185
246
}
186
247
248
+ pub fn make_ast_vec ( token_list : & mut TokenList ) -> ASTVec {
249
+ let mut ast_vec = ASTVec :: new ( ) ;
250
+ while !token_list. is_empty ( ) {
251
+ let ast : AST = AST :: new ( token_list) ;
252
+ token_list. consume_statement_end ( ) ;
253
+ ast_vec. vec . push ( ast) ;
254
+ }
255
+ ast_vec
256
+ }
187
257
}
0 commit comments