编译实践学习 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。