Files
nudt-compiler-cpp/src/sem/Sema.cpp
2026-03-09 12:42:12 +08:00

59 lines
1.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 极简语义分析:只检查变量是否先声明再使用。
// 如需扩展,可在此基础上加入:
// - 常量折叠/类型检查
// - 函数签名/参数数量校验
// - 控制流相关检查return 覆盖、break/continue 合法性等)
#include "sem/Sema.h"
#include <stdexcept>
#include <string>
#include <unordered_set>
#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& item : block.items) {
if (auto decl = dynamic_cast<ast::VarDecl*>(item.get())) {
table_.Add(decl->name);
if (decl->init) CheckExpr(*decl->init);
continue;
}
if (auto ret = dynamic_cast<ast::ReturnStmt*>(item.get())) {
CheckExpr(*ret->value);
}
}
}
void CheckExpr(const ast::Expr& expr) {
if (auto var = dynamic_cast<const ast::VarExpr*>(&expr)) {
if (!table_.Contains(var->name)) {
throw std::runtime_error("[sema] 使用了未定义的变量: " + var->name);
}
} else if (auto bin = dynamic_cast<const ast::BinaryExpr*>(&expr)) {
CheckExpr(*bin->lhs);
CheckExpr(*bin->rhs);
}
}
private:
SymbolTable& table_;
};
} // namespace
std::shared_ptr<ast::CompUnit> RunSema(std::shared_ptr<ast::CompUnit> ast) {
if (!ast || !ast->func || !ast->func->body) return ast;
SymbolTable table;
SemaVisitor visitor(table);
visitor.CheckBlock(*ast->func->body);
return ast;
}