编译实践学习 Part4
License: CC BY-NC-SA 4.0
Lv 4.1
常量
本节的 EBNF 中出现了一种新的表示:
{ ... }, 这代表花括号内包含的项可被重复 0 次或多次. 在 AST 中, 你可以使用std::vector/Vec来表示这种结构.
你说的对,但是感觉不如 std::list
然后就是花括号的处理。参考了 这篇文章,用递归的结构表示了某些东西。
然后是符号表。
std::map<std::string, Koopa_val> symbol_table;
Koopa_val 是上一节提到过的那个。
求值
现在开始感谢我之前不是用 BaseAST 的指针而是具体化每个类型了。
(要不然还要一大堆强转类型……)
接着运行,怎么段错误了?原来是我在 lv 3 里写的 Parser 出了问题。然而它还是通过了 lv3 的所有样例,我也不知道为什么。
然后发现 const int x=1, y=2; 这样的声明会编译错误,鉴定为 Parser 写挂了。
Lv 4.2
变量
这节写了好久……每次写完都感觉很烂然后想重构……
下面就只写最新一版的细节。
其实是我之前只顾着重构忘了写博客(
首先是原先的 Koopa_val 拆成了几个小类,Koopa_val 里是 Koopa_val_base,其定义如下:
class Koopa_val_base {
public:
virtual std::string get_str() const = 0;
virtual void prepare(Ost& outstr, std::string prefix) { return; }
virtual Koopa_value_type val_type() const = 0;
};
class Koopa_val {
private:
std::shared_ptr<Koopa_val_base> val;
public:
Koopa_val() {}
Koopa_val(Koopa_val_base* obj) {
val = std::shared_ptr<Koopa_val_base>(obj);
}
int get_im_val() const {
if(val_type() == KOOPA_VALUE_TYPE_IMMEDIATE){
return std::static_pointer_cast<Koopa_val_im>(val)->get_im_val();
} else {
assert(0);
}
}
Koopa_value_type val_type() const { return val->val_type(); }
std::string get_str() const {
return val->get_str();
}
void prepare(Ost& outstr, std::string prefix) {
return val->prepare(outstr, prefix);
}
template<typename T>
friend T& operator<<(T& outstr, Koopa_val const & me) {
outstr << me.get_str();
}
};
get_im_val() 在常量求值里要用。
然后是生成汇编。

浙公网安备 33010602011771号