编译实践学习 Part5

License: CC BY-NC-SA 4.0

5.1

本节的 EBNF 中出现了一种新的表示: [ ... ], 这代表方括号内包含的项可被重复 0 次或 1 次. 也就是说, 单个分号在 SysY 程序中也是一个合法的语句. 在 AST 中, 你可以使用空指针或 Option 来表示这种结构.

但是,我拒绝。

class OptionalExpAST : public BaseAST {
public:
	std::optional<std::unique_ptr<ExpAST>> exp;
	void output(Ost &outstr, std::string prefix) const override;
};

将原来的 @a 改为 @a_1@a_2 什么的只要稍作修改:

void Koopa_val_named_symbol::set_id(std::string str) {
	id = str + "_" + std::to_string(named_var_cnt);
	named_var_cnt++;
}

由于之前将符号表定义成 unordered_map,现在改的时候将其改成一个类:

template<typename T>
class Symbol_table_stack {
	std::list<std::unordered_map<std::string, T>> symbols;

public:
	auto empty_iter() const {
		return symbols.front().end();
	}
	auto find(const std::string& key) {
		for(auto i = symbols.rbegin(); i != symbols.rend(); i++) {
			auto val_iter = i->find(key);
			if(val_iter != i->end()) {
				return val_iter;
			}
		}
		return symbols.front().end();
	}
	bool contains(const std::string& key) { return find(key) != empty_iter(); }
	T& operator[](const std::string& key) {
		if(contains(key)) {
			return find(key)->second;
		} else {
			return symbols.back()[key];
		}
	}
	void add_table() { symbols.emplace_back(); }
	void del_table() { symbols.pop_back(); }
};

Symbol_table_stack<Koopa_val> symbol_table;

意料之中的 WA 了。小样例过了,但第一个数据就没过.

int main(){
    {}
    return 0;
}

参考了 github 上 BerkinChen/pku-compiler 的实现。发现加个特判就完事了。

然后就是一些之前遗留的(没改干净的)代码。改了改成功 AC。

posted @ 2024-06-23 10:28  383494  阅读(2)  评论(0编辑  收藏  举报