// 极简语义分析:只检查变量是否先声明再使用。 #include "sem/Sema.h" #include #include #include #include "ast/AstNodes.h" #include "sem/SymbolTable.h" namespace { class SemaVisitor { public: explicit SemaVisitor(SymbolTable& table) : table_(table) {} void CheckBlock(const ast::Block& block) { for (const auto& decl : block.varDecls) { table_.Add(decl->name); if (decl->init) CheckExpr(*decl->init); } for (const auto& stmt : block.stmts) { if (auto ret = dynamic_cast(stmt.get())) { CheckExpr(*ret->value); } } } void CheckExpr(const ast::Expr& expr) { if (auto var = dynamic_cast(&expr)) { if (!table_.Contains(var->name)) { throw std::runtime_error("使用了未定义的变量: " + var->name); } } else if (auto bin = dynamic_cast(&expr)) { CheckExpr(*bin->lhs); CheckExpr(*bin->rhs); } } private: SymbolTable& table_; }; } // namespace std::shared_ptr RunSema(std::shared_ptr ast) { if (!ast || !ast->func || !ast->func->body) return ast; SymbolTable table; SemaVisitor visitor(table); visitor.CheckBlock(*ast->func->body); return ast; }