Skip to content

Commit b595f65

Browse files
committed
ASTを複数文に対応
1 parent 02df4a7 commit b595f65

File tree

6 files changed

+196
-43
lines changed

6 files changed

+196
-43
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
/target
22
*.s
3-
testset.txt
3+
/test

Makefile.toml

+5
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ args = ["-r", "a.out", "tmp.s"]
1010
dependencies = [
1111
"test",
1212
"clean",
13+
]
14+
15+
[tasks.arm]
16+
dependencies = [
17+
"test",
1318
]

src/ast.rs

+89-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
use super::tokenizer::{TokenList, OperationKind, ParenthesesKind};
22
use super::error::error_exit;
33

4+
pub enum PrimaryNodeKind {
5+
Number(i32),
6+
Variable(char, i32), // (variablename, offset from bsp)
7+
}
8+
49
pub enum ASTNodeKind {
510
Operation(OperationKind),
6-
Number(i32),
11+
Primary(PrimaryNodeKind),
12+
Assign,
713
}
814

915
pub struct ASTNode {
@@ -13,9 +19,9 @@ pub struct ASTNode {
1319
}
1420

1521
impl ASTNode {
16-
fn new_num_node(num: i32) -> ASTNode {
22+
fn new_primary_node(primary_node: PrimaryNodeKind) -> ASTNode {
1723
ASTNode {
18-
node_kind: ASTNodeKind::Number(num),
24+
node_kind: ASTNodeKind::Primary(primary_node),
1925
left: None,
2026
right: None,
2127
}
@@ -29,23 +35,37 @@ impl ASTNode {
2935
}
3036
}
3137

38+
fn new_assign_node() -> ASTNode {
39+
ASTNode {
40+
node_kind: ASTNodeKind::Assign,
41+
left: None,
42+
right: None,
43+
}
44+
}
45+
3246
// ASTNodeを更新
3347
fn add_neighbor_node(&mut self, left: Link, right: Link) {
3448
self.left = left;
3549
self.right = right;
3650
}
3751
}
3852

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+
*/
4766

4867
type Link = Option<Box<ASTNode>>;
68+
// ;で区切られた領域のASTを作成する
4969
pub struct AST {
5070
pub root: Link,
5171
}
@@ -56,18 +76,27 @@ impl AST {
5676
let ast_tree = AST {
5777
root: AST::expr(token_list),
5878
};
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-
}
6479
ast_tree
6580
}
6681

82+
// expr = assign
6783
fn expr(token_list: &mut TokenList) -> Link {
68-
AST::equality(token_list)
84+
AST::assign(token_list)
6985
}
7086

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)*
71100
fn equality(token_list: &mut TokenList) -> Link {
72101
let mut equality_node = AST::relational(token_list);
73102

@@ -87,6 +116,7 @@ impl AST {
87116
equality_node
88117
}
89118

119+
// relational = add ("<" add | "<=" add | ">" add | ">=" add)*
90120
fn relational(token_list: &mut TokenList) -> Link {
91121
let mut relational_node = AST::add(token_list);
92122

@@ -115,6 +145,7 @@ impl AST {
115145
relational_node
116146
}
117147

148+
// add = mul ("+" mul | "-" mul)*
118149
fn add(token_list: &mut TokenList) -> Link {
119150
let mut expr_node = AST::mul(token_list);
120151

@@ -134,6 +165,7 @@ impl AST {
134165
expr_node
135166
}
136167

168+
// mul = unary ("*" unary | "/" unary)*
137169
fn mul(token_list: &mut TokenList) -> Link {
138170
let mut mul_node = AST::urany(token_list);
139171

@@ -153,19 +185,21 @@ impl AST {
153185
mul_node
154186
}
155187

188+
// unary = ("+" | "-")? primary
156189
fn urany(token_list: &mut TokenList) -> Link {
157190
if token_list.consume_operation(OperationKind::Add) {
158191
return AST::primary(token_list);
159192
}
160193
if token_list.consume_operation(OperationKind::Sub) {
161194
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));
163196
new_node.add_neighbor_node(Some(Box::new(zoro_node)), AST::primary(token_list));
164197
return Some(Box::new(new_node));
165198
}
166199
return AST::primary(token_list);
167200
}
168201

202+
// primary = num | ident | "(" expr ")"
169203
fn primary(token_list: &mut TokenList) -> Link {
170204
if token_list.comsume_parentheses(ParenthesesKind::LeftParentheses) {
171205
let node = AST::expr(token_list);
@@ -181,7 +215,43 @@ impl AST {
181215
}
182216
}
183217
}
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+
}
185246
}
186247

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+
}
187257
}

src/compiler.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use crate::ast::{AST, ASTNode, ASTNodeKind};
1+
use crate::ast::{AST, ASTNode, ASTNodeKind, PrimaryNodeKind};
22
use super::tokenizer::OperationKind;
33

44
fn compile_node(mut node: ASTNode, instruction_vec: &mut Vec<String>) {
5-
if let ASTNodeKind::Number(num) = node.node_kind {
5+
if let ASTNodeKind::Primary(PrimaryNodeKind::Number(num)) = node.node_kind {
66
let instruction = format!(" push {}", num);
77
instruction_vec.push(instruction);
88
return;

src/tests.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
mod tests {
33
use std::fs::File;
44
use std::io::{BufRead, BufReader};
5+
#[cfg(target_arch = "x86")]
56
use std::process::Command;
6-
use crate::output_asembly;
77

8+
use crate::tokenizer;
9+
use crate::ast;
10+
11+
#[cfg(target_arch = "x86")]
812
fn make_binary_from_asm() {
913
Command::new("cc")
1014
.arg("-o")
@@ -14,6 +18,7 @@ mod tests {
1418
.expect("failed to asemble binary");
1519
}
1620

21+
#[cfg(target_arch = "x86")]
1722
fn compare_output() -> i32{
1823
let status = Command::new("sh")
1924
.arg("-c")
@@ -26,8 +31,10 @@ mod tests {
2631
}
2732

2833
#[test]
34+
#[cfg(target_arch = "x86")]
2935
fn compiler_test() {
30-
let f = File::open("testset.txt").unwrap();
36+
use crate::output_asembly;
37+
let f = File::open("./test/binary_test.txt").unwrap();
3138
for line_result in BufReader::new(f).lines() {
3239
let test_set = line_result.unwrap();
3340
let test_vec: Vec<&str> = test_set.split(",").collect();
@@ -45,4 +52,16 @@ mod tests {
4552
}
4653
}
4754
}
55+
56+
#[test]
57+
fn ast_test() {
58+
let f = File::open("./test/ast_test.txt").unwrap();
59+
for line_result in BufReader::new(f).lines() {
60+
let ast_text = line_result.unwrap();
61+
println!("try making ast of {}", ast_text);
62+
let mut token_list = tokenizer::text_tokenizer(&ast_text);
63+
ast::ASTVec::make_ast_vec(&mut token_list);
64+
println!("suceeded!");
65+
}
66+
}
4867
}

0 commit comments

Comments
 (0)