Commit d7dae728 authored by 李晓奇's avatar 李晓奇

backup on halfway

parent 2dd8c34b
......@@ -15,8 +15,8 @@ IncludeCategories:
Priority: 2
- Regex: '.*'
Priority: 1
IndentCaseLabels: false
AllowShortCaseLabelsOnASingleLine: true
IndentCaseLabels: true
AllowShortCaseLabelsOnASingleLine: false
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
PenaltyReturnTypeOnItsOwnLine: 200
......
# lab3 实验报告
学号 姓名
PB20111654 李晓奇
## 实验要求
## 实验难点
实验中遇到哪些挑战
1. syntax_tree和ast的区别、为什需要ast?
阅读AST的构造函数,`AST(syntax_tree *)`
实际上这部分在上个实验就有看calc_ast的代码,但是印象不深刻。。
2. 访问者模式究竟有什么用?
比如这样一系列函数调用:
```cpp
ASTPrinter::visit(ASTProgram &)
{
//...
for (auto decl : node.declarations) {
decl->accept(*this);
}
//...
}
ASTVarDeclaration::accept(ASTVisitor &)
{
//...
auto var_decl = dynamic_cast<ASTVarDeclaration *>(this);
if (var_decl) {
var_decl->accept(visitor);
return;
}
//...
}
void ASTVarDeclaration::accept(ASTVisitor &visitor)
{ visitor.visit(*this); }
```
假设就是vardeclaration,直接调用(在`ASTPrinter::visit`内)`visit(dynamic_cast<ASTVarDeclaration *>(this))`不是一样的吗?
参考[攻略](https://www.jianshu.com/p/1f1049d0a0f4),接受一点,感觉还是不太明白,但是不影响写实验。因为经过反复的阅读,我已经知道了我们要实现的`CminusfBuilder`是一个访问者类!
3. 无从下手!
从变量开始!
自底向上做自然多了,不然像在摸黑拧魔方。
4. 如何获得返回值?
加入一个全局变量保存语句的返回值。
5. 数组or指针?这个关乎地址的计算、类型转换……
答案在于:中间代码是如何生成的?
按我的理解,
- 在翻译为中间代码时,函数内部声明的只能是数组,计算地址时会得到指针。
- 在传递给函数时,只能传递数组,但是传递为指针。
## 实验设计
......
......@@ -2,17 +2,13 @@
#define _SYNTAX_TREE_HPP_
extern "C" {
#include "syntax_tree.h"
extern syntax_tree *parse(const char *input);
extern syntax_tree *parse(const char *input);
}
#include <vector>
#include <memory>
#include <string>
#include <vector>
enum CminusType {
TYPE_INT,
TYPE_FLOAT,
TYPE_VOID
};
enum CminusType { TYPE_INT, TYPE_FLOAT, TYPE_VOID };
enum RelOp {
// <=
......@@ -64,23 +60,24 @@ struct ASTVar;
struct ASTAssignExpression;
struct ASTSimpleExpression;
struct ASTAdditiveExpression;
struct ASTTerm ;
struct ASTTerm;
struct ASTCall;
class ASTVisitor;
class AST {
public:
public:
AST() = delete;
AST(syntax_tree *);
AST(AST &&tree) {
root = tree.root;
tree.root = nullptr;
};
ASTProgram* get_root() { return root.get(); }
void run_visitor(ASTVisitor& visitor);
private:
ASTNode* transform_node_iter(syntax_tree_node *);
ASTProgram *get_root() { return root.get(); }
void run_visitor(ASTVisitor &visitor);
private:
ASTNode *transform_node_iter(syntax_tree_node *);
std::shared_ptr<ASTProgram> root = nullptr;
};
......@@ -90,21 +87,20 @@ struct ASTNode {
struct ASTProgram : ASTNode {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTDeclaration>>
declarations;
std::vector<std::shared_ptr<ASTDeclaration>> declarations;
};
struct ASTDeclaration: ASTNode {
struct ASTDeclaration : ASTNode {
virtual void accept(ASTVisitor &) override;
CminusType type;
std::string id;
};
struct ASTFactor: ASTNode {
struct ASTFactor : ASTNode {
virtual void accept(ASTVisitor &) override;
};
struct ASTNum: ASTFactor {
struct ASTNum : ASTFactor {
virtual void accept(ASTVisitor &) override final;
CminusType type;
union {
......@@ -113,19 +109,19 @@ struct ASTNum: ASTFactor {
};
};
struct ASTVarDeclaration: ASTDeclaration {
struct ASTVarDeclaration : ASTDeclaration {
virtual void accept(ASTVisitor &) override final;
CminusType type;
std::shared_ptr<ASTNum> num;
};
struct ASTFunDeclaration: ASTDeclaration {
struct ASTFunDeclaration : ASTDeclaration {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTParam>> params;
std::shared_ptr<ASTCompoundStmt> compound_stmt;
};
struct ASTParam: ASTNode {
struct ASTParam : ASTNode {
virtual void accept(ASTVisitor &) override final;
CminusType type;
std::string id;
......@@ -137,62 +133,62 @@ struct ASTStatement : ASTNode {
virtual void accept(ASTVisitor &) override;
};
struct ASTCompoundStmt: ASTStatement {
virtual void accept(ASTVisitor&) override final;
struct ASTCompoundStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations;
std::vector<std::shared_ptr<ASTStatement>> statement_list;
};
struct ASTExpressionStmt: ASTStatement {
struct ASTExpressionStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTExpression> expression;
};
struct ASTSelectionStmt: ASTStatement {
struct ASTSelectionStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> if_statement;
// should be nullptr if no else structure exists
std::shared_ptr<ASTStatement> else_statement;
};
struct ASTIterationStmt: ASTStatement {
struct ASTIterationStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> statement;
};
struct ASTReturnStmt: ASTStatement {
struct ASTReturnStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
// should be nullptr if return void
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTExpression> expression;
};
struct ASTExpression: ASTFactor {
struct ASTExpression : ASTFactor {
virtual void accept(ASTVisitor &) override;
};
struct ASTAssignExpression: ASTExpression {
struct ASTAssignExpression : ASTExpression {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTVar> var;
std::shared_ptr<ASTExpression> expression;
};
struct ASTSimpleExpression: ASTExpression {
struct ASTSimpleExpression : ASTExpression {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression_l;
std::shared_ptr<ASTAdditiveExpression> additive_expression_r;
RelOp op;
};
struct ASTVar: ASTFactor {
struct ASTVar : ASTFactor {
virtual void accept(ASTVisitor &) override final;
std::string id;
// nullptr if var is of int type
std::shared_ptr<ASTExpression> expression;
};
struct ASTAdditiveExpression: ASTNode {
struct ASTAdditiveExpression : ASTNode {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression;
AddOp op;
......@@ -206,14 +202,14 @@ struct ASTTerm : ASTNode {
std::shared_ptr<ASTFactor> factor;
};
struct ASTCall: ASTFactor {
struct ASTCall : ASTFactor {
virtual void accept(ASTVisitor &) override final;
std::string id;
std::vector<std::shared_ptr<ASTExpression>> args;
};
class ASTVisitor {
public:
public:
virtual void visit(ASTProgram &) = 0;
virtual void visit(ASTNum &) = 0;
virtual void visit(ASTVarDeclaration &) = 0;
......@@ -233,7 +229,7 @@ public:
};
class ASTPrinter : public ASTVisitor {
public:
public:
virtual void visit(ASTProgram &) override final;
virtual void visit(ASTNum &) override final;
virtual void visit(ASTVarDeclaration &) override final;
......@@ -252,8 +248,8 @@ public:
virtual void visit(ASTCall &) override final;
void add_depth() { depth += 2; }
void remove_depth() { depth -= 2; }
private:
private:
int depth = 0;
};
#endif
......@@ -96,6 +96,8 @@ class CminusfBuilder : public ASTVisitor {
virtual void visit(ASTTerm &) override final;
virtual void visit(ASTCall &) override final;
bool type_cast(Value *&, Value *&, std::string = "computation");
std::unique_ptr<IRBuilder> builder;
Scope scope;
std::unique_ptr<Module> module;
......
This diff is collapsed.
#include "cminusf_builder.hpp"
#include <fstream>
#include <iostream>
#include <memory>
......@@ -6,11 +7,10 @@
using namespace std::literals::string_literals;
void print_help(std::string exe_name) {
std::cout << "Usage: " << exe_name <<
" [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] <input-file>" << std::endl;
std::cout << "Usage: " << exe_name << " [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] <input-file>"
<< std::endl;
}
int main(int argc, char **argv) {
std::string target_path;
std::string input_path;
......
This diff is collapsed.
#include "syntax_tree.h"
#include <stdlib.h>
#include <string.h>
#include "syntax_tree.h"
syntax_tree_node * new_syntax_tree_node(const char * name)
{
syntax_tree_node * new_node = (syntax_tree_node *)malloc(sizeof(syntax_tree_node));
if (name)
strncpy(new_node->name, name, SYNTAX_TREE_NODE_NAME_MAX);
else
new_node->name[0] = '\0';
new_node->children_num = 0;
return new_node;
syntax_tree_node *new_syntax_tree_node(const char *name) {
syntax_tree_node *new_node = (syntax_tree_node *)malloc(sizeof(syntax_tree_node));
if (name)
strncpy(new_node->name, name, SYNTAX_TREE_NODE_NAME_MAX);
else
new_node->name[0] = '\0';
new_node->children_num = 0;
return new_node;
}
int syntax_tree_add_child(syntax_tree_node * parent, syntax_tree_node * child)
{
if (!parent || !child) return -1;
parent->children[parent->children_num++] = child;
return parent->children_num;
int syntax_tree_add_child(syntax_tree_node *parent, syntax_tree_node *child) {
if (!parent || !child)
return -1;
parent->children[parent->children_num++] = child;
return parent->children_num;
}
void del_syntax_tree_node(syntax_tree_node * node, int recursive)
{
if (!node) return;
void del_syntax_tree_node(syntax_tree_node *node, int recursive) {
if (!node)
return;
int i;
if (recursive) {
for (i = 0; i < node->children_num; i++) {
del_syntax_tree_node(node->children[i], 1);
}
}
free(node);
int i;
if (recursive) {
for (i = 0; i < node->children_num; i++) {
del_syntax_tree_node(node->children[i], 1);
}
}
free(node);
}
syntax_tree * new_syntax_tree()
{
return (syntax_tree *)malloc(sizeof(syntax_tree));
}
syntax_tree *new_syntax_tree() { return (syntax_tree *)malloc(sizeof(syntax_tree)); }
void del_syntax_tree(syntax_tree * tree)
{
if (!tree) return;
void del_syntax_tree(syntax_tree *tree) {
if (!tree)
return;
if (tree->root) {
del_syntax_tree_node(tree->root, 1);
}
free(tree);
if (tree->root) {
del_syntax_tree_node(tree->root, 1);
}
free(tree);
}
void print_syntax_tree_node(FILE * fout, syntax_tree_node * node, int level)
{
// assume fout valid now
// check if "node" empty pointer
if (!node) return;
// print myself
int i;
for (i = 0; i < level; i++) {
fprintf(fout, "| ");
}
fprintf(fout, ">--%s %s\n", (node->children_num ? "+" : "*"), node->name);
void print_syntax_tree_node(FILE *fout, syntax_tree_node *node, int level) {
// assume fout valid now
for (i = 0; i < node->children_num; i++) {
print_syntax_tree_node(fout, node->children[i], level + 1);
}
}
// check if "node" empty pointer
if (!node)
return;
// print myself
int i;
for (i = 0; i < level; i++) {
fprintf(fout, "| ");
}
fprintf(fout, ">--%s %s\n", (node->children_num ? "+" : "*"), node->name);
void print_syntax_tree(FILE * fout, syntax_tree * tree)
{
if (!fout) return;
print_syntax_tree_node(fout, tree->root, 0);
for (i = 0; i < node->children_num; i++) {
print_syntax_tree_node(fout, node->children[i], level + 1);
}
}
void print_syntax_tree(FILE *fout, syntax_tree *tree) {
if (!fout)
return;
print_syntax_tree_node(fout, tree->root, 0);
}
*.ll
clean.sh
decl_float_array
decl_float
decl_int_array
decl_int
input
output_float
output_int
return
*.ll
clean.sh
num_add_float
num_add_int
num_add_mixed
num_comp1
num_comp2
num_div_float
num_div_int
num_div_mixed
num_eq_float
num_eq_int
num_eq_mixed
num_ge_float
num_ge_int
num_ge_mixed
num_gt_float
num_gt_int
num_gt_mixed
num_le_float
num_le_int
num_le_mixed
num_lt_float
num_lt_int
num_lt_mixed
num_mul_float
num_mul_int
num_mul_mixed
num_neq_float
num_neq_int
num_neq_mixed
num_sub_float
num_sub_int
num_sub_mixed
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment