编译实践学习 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() 在常量求值里要用。

然后是生成汇编。

posted @ 2024-06-16 21:35  383494  阅读(70)  评论(0)    收藏  举报