編譯實踐學習 Part5

383494發表於2024-06-23

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。

相關文章