You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/include/sem/Sema.h

221 lines
7.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef SEMANTIC_ANALYSIS_H
#define SEMANTIC_ANALYSIS_H
#include "SymbolTable.h"
#include "SysYBaseVisitor.h"
<<<<<<< HEAD
#include "SysYParser.h"
=======
>>>>>>> master
#include <vector>
#include <string>
#include <sstream>
#include <unordered_map>
#include <any>
#include <memory>
// 错误信息结构体
struct ErrorMsg {
std::string msg;
int line;
int column;
ErrorMsg(std::string m, int l, int c) : msg(std::move(m)), line(l), column(c) {}
};
// 前向声明
namespace antlr4 {
class ParserRuleContext;
namespace tree {
class ParseTree;
}
}
// 语义/IR生成上下文核心类
class IRGenContext {
public:
// 错误管理
void RecordError(const ErrorMsg& err) { errors_.push_back(err); }
const std::vector<ErrorMsg>& GetErrors() const { return errors_; }
bool HasError() const { return !errors_.empty(); }
void ClearErrors() { errors_.clear(); }
// 类型绑定/查询 - 使用 void* 以兼容测试代码
void SetType(void* ctx, SymbolType type) {
node_type_map_[ctx] = type;
}
SymbolType GetType(void* ctx) const {
auto it = node_type_map_.find(ctx);
return it == node_type_map_.end() ? SymbolType::TYPE_UNKNOWN : it->second;
}
// 常量值绑定/查询 - 使用 void* 以兼容测试代码
void SetConstVal(void* ctx, const std::any& val) {
const_val_map_[ctx] = val;
}
std::any GetConstVal(void* ctx) const {
auto it = const_val_map_.find(ctx);
return it == const_val_map_.end() ? std::any() : it->second;
}
// 循环状态管理
void EnterLoop() { sym_table_.EnterLoop(); }
void ExitLoop() { sym_table_.ExitLoop(); }
bool InLoop() const { return sym_table_.InLoop(); }
// 类型判断工具函数
bool IsIntType(const std::any& val) const {
return val.type() == typeid(long) || val.type() == typeid(int);
}
bool IsFloatType(const std::any& val) const {
return val.type() == typeid(double) || val.type() == typeid(float);
}
// 当前函数返回类型
SymbolType GetCurrentFuncReturnType() const {
return current_func_ret_type_;
}
void SetCurrentFuncReturnType(SymbolType type) {
current_func_ret_type_ = type;
}
// 符号表访问
SymbolTable& GetSymbolTable() { return sym_table_; }
const SymbolTable& GetSymbolTable() const { return sym_table_; }
// 作用域管理
void EnterScope() { sym_table_.EnterScope(); }
void LeaveScope() { sym_table_.LeaveScope(); }
size_t GetScopeDepth() const { return sym_table_.GetScopeDepth(); }
private:
SymbolTable sym_table_;
std::unordered_map<void*, SymbolType> node_type_map_;
std::unordered_map<void*, std::any> const_val_map_;
std::vector<ErrorMsg> errors_;
SymbolType current_func_ret_type_ = SymbolType::TYPE_UNKNOWN;
};
// 与现有 IRGen/主流程保持兼容的语义上下文占位。
class SemanticContext {
public:
void BindVarUse(const SysYParser::LValueContext* use,
SysYParser::VarDefContext* decl) {
var_uses_[use] = decl;
}
SysYParser::VarDefContext* ResolveVarUse(
const SysYParser::LValueContext* use) const {
auto it = var_uses_.find(use);
return it == var_uses_.end() ? nullptr : it->second;
}
private:
std::unordered_map<const SysYParser::LValueContext*,
SysYParser::VarDefContext*>
var_uses_;
};
// 错误信息格式化工具函数
inline std::string FormatErrMsg(const std::string& msg, int line, int col) {
std::ostringstream oss;
oss << "[行:" << line << ",列:" << col << "] " << msg;
return oss.str();
}
// 语义分析访问器 - 继承自生成的基类
class SemaVisitor : public SysYBaseVisitor {
public:
explicit SemaVisitor(IRGenContext& ctx) : ir_ctx_(ctx) {}
// 必须实现的 ANTLR4 接口
std::any visit(antlr4::tree::ParseTree* tree) override {
if (tree) {
return tree->accept(this);
}
return std::any();
}
std::any visitTerminal(antlr4::tree::TerminalNode* node) override {
return std::any();
}
std::any visitErrorNode(antlr4::tree::ErrorNode* node) override {
if (node) {
int line = node->getSymbol()->getLine();
int col = node->getSymbol()->getCharPositionInLine() + 1;
ir_ctx_.RecordError(ErrorMsg("语法错误节点", line, col));
}
return std::any();
}
// 核心访问方法
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
std::any visitBtype(SysYParser::BtypeContext* ctx) override;
std::any visitConstDef(SysYParser::ConstDefContext* ctx) override;
std::any visitConstInitValue(SysYParser::ConstInitValueContext* ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitInitValue(SysYParser::InitValueContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
std::any visitFuncFParams(SysYParser::FuncFParamsContext* ctx) override;
std::any visitFuncFParam(SysYParser::FuncFParamContext* ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
std::any visitStmt(SysYParser::StmtContext* ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext* ctx) override;
std::any visitExp(SysYParser::ExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
std::any visitLValue(SysYParser::LValueContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitNumber(SysYParser::NumberContext* ctx) override;
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;
std::any visitUnaryOp(SysYParser::UnaryOpContext* ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext* ctx) override;
// 通用子节点访问
std::any visitChildren(antlr4::tree::ParseTree* node) override {
std::any result;
if (node) {
for (auto* child : node->children) {
if (child) {
result = child->accept(this);
}
}
}
return result;
}
// 获取上下文引用
IRGenContext& GetContext() { return ir_ctx_; }
const IRGenContext& GetContext() const { return ir_ctx_; }
private:
IRGenContext& ir_ctx_;
};
// 语义分析入口函数
void RunSemanticAnalysis(SysYParser::CompUnitContext* ctx, IRGenContext& ir_ctx);
<<<<<<< HEAD
// 兼容旧流程入口。
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);
=======
// 兼容主程序的简单包装:返回构造好的 IRGenContext按值
IRGenContext RunSema(SysYParser::CompUnitContext& ctx);
>>>>>>> master
#endif // SEMANTIC_ANALYSIS_H