forked from NUDT-compiler/nudt-compiler-cpp
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.
201 lines
5.6 KiB
201 lines
5.6 KiB
#ifndef SYMBOL_TABLE_H
|
|
#define SYMBOL_TABLE_H
|
|
|
|
#include <any>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <stack>
|
|
#include <utility>
|
|
|
|
// 核心类型枚举
|
|
enum class SymbolType {
|
|
TYPE_UNKNOWN, // 未知类型
|
|
TYPE_INT, // 整型
|
|
TYPE_FLOAT, // 浮点型
|
|
TYPE_VOID, // 空类型
|
|
TYPE_ARRAY, // 数组类型
|
|
TYPE_FUNCTION // 函数类型
|
|
};
|
|
|
|
// 获取类型名称字符串
|
|
inline const char* SymbolTypeToString(SymbolType type) {
|
|
switch (type) {
|
|
case SymbolType::TYPE_INT: return "int";
|
|
case SymbolType::TYPE_FLOAT: return "float";
|
|
case SymbolType::TYPE_VOID: return "void";
|
|
case SymbolType::TYPE_ARRAY: return "array";
|
|
case SymbolType::TYPE_FUNCTION: return "function";
|
|
default: return "unknown";
|
|
}
|
|
}
|
|
|
|
// 变量信息结构体
|
|
struct VarInfo {
|
|
SymbolType type = SymbolType::TYPE_UNKNOWN;
|
|
bool is_const = false;
|
|
std::any const_val;
|
|
std::vector<int> array_dims; // 数组维度,空表示非数组
|
|
void* decl_ctx = nullptr; // 关联的语法节点
|
|
|
|
// 检查是否为数组类型
|
|
bool IsArray() const { return !array_dims.empty(); }
|
|
|
|
// 获取数组元素总数
|
|
int GetArrayElementCount() const {
|
|
int count = 1;
|
|
for (int dim : array_dims) {
|
|
count *= dim;
|
|
}
|
|
return count;
|
|
}
|
|
};
|
|
|
|
// 函数信息结构体
|
|
struct FuncInfo {
|
|
SymbolType ret_type = SymbolType::TYPE_UNKNOWN;
|
|
std::string name;
|
|
std::vector<SymbolType> param_types; // 参数类型列表
|
|
void* decl_ctx = nullptr; // 关联的语法节点
|
|
|
|
// 检查参数匹配
|
|
bool CheckParams(const std::vector<SymbolType>& actual_params) const {
|
|
if (actual_params.size() != param_types.size()) {
|
|
return false;
|
|
}
|
|
|
|
for (size_t i = 0; i < param_types.size(); ++i) {
|
|
if (param_types[i] != actual_params[i] &&
|
|
param_types[i] != SymbolType::TYPE_UNKNOWN &&
|
|
actual_params[i] != SymbolType::TYPE_UNKNOWN) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// 作用域条目结构体
|
|
struct ScopeEntry {
|
|
// 变量符号表:符号名 -> (符号信息, 声明节点)
|
|
std::unordered_map<std::string, std::pair<VarInfo, void*>> var_symbols;
|
|
|
|
// 函数符号表:符号名 -> (函数信息, 声明节点)
|
|
std::unordered_map<std::string, std::pair<FuncInfo, void*>> func_symbols;
|
|
|
|
// 清空作用域
|
|
void Clear() {
|
|
var_symbols.clear();
|
|
func_symbols.clear();
|
|
}
|
|
};
|
|
|
|
// 符号表核心类
|
|
class SymbolTable {
|
|
public:
|
|
// ========== 作用域管理 ==========
|
|
|
|
// 进入新作用域
|
|
void EnterScope();
|
|
|
|
// 离开当前作用域
|
|
void LeaveScope();
|
|
|
|
// 获取当前作用域深度
|
|
size_t GetScopeDepth() const { return scopes_.size(); }
|
|
|
|
// 检查作用域栈是否为空
|
|
bool IsEmpty() const { return scopes_.empty(); }
|
|
|
|
// ========== 变量符号管理 ==========
|
|
|
|
// 检查当前作用域是否包含指定变量
|
|
bool CurrentScopeHasVar(const std::string& name) const;
|
|
|
|
// 绑定变量到当前作用域
|
|
void BindVar(const std::string& name, const VarInfo& info, void* decl_ctx);
|
|
|
|
// 查找变量(从当前作用域向上遍历)
|
|
bool LookupVar(const std::string& name, VarInfo& out_info, void*& out_decl_ctx) const;
|
|
|
|
// 快速查找变量(不获取详细信息)
|
|
bool HasVar(const std::string& name) const {
|
|
VarInfo info;
|
|
void* ctx;
|
|
return LookupVar(name, info, ctx);
|
|
}
|
|
|
|
// ========== 函数符号管理 ==========
|
|
|
|
// 检查当前作用域是否包含指定函数
|
|
bool CurrentScopeHasFunc(const std::string& name) const;
|
|
|
|
// 绑定函数到当前作用域
|
|
void BindFunc(const std::string& name, const FuncInfo& info, void* decl_ctx);
|
|
|
|
// 查找函数(从当前作用域向上遍历)
|
|
bool LookupFunc(const std::string& name, FuncInfo& out_info, void*& out_decl_ctx) const;
|
|
|
|
// 快速查找函数(不获取详细信息)
|
|
bool HasFunc(const std::string& name) const {
|
|
FuncInfo info;
|
|
void* ctx;
|
|
return LookupFunc(name, info, ctx);
|
|
}
|
|
|
|
// ========== 循环状态管理 ==========
|
|
|
|
// 进入循环
|
|
void EnterLoop();
|
|
|
|
// 离开循环
|
|
void ExitLoop();
|
|
|
|
// 检查是否在循环内
|
|
bool InLoop() const;
|
|
|
|
// 获取循环嵌套深度
|
|
int GetLoopDepth() const { return loop_depth_; }
|
|
|
|
// ========== 辅助功能 ==========
|
|
|
|
// 清空所有作用域和状态
|
|
void Clear();
|
|
|
|
// 获取当前作用域中所有变量名
|
|
std::vector<std::string> GetCurrentScopeVarNames() const;
|
|
|
|
// 获取当前作用域中所有函数名
|
|
std::vector<std::string> GetCurrentScopeFuncNames() const;
|
|
|
|
// 调试:打印符号表内容
|
|
void Dump() const;
|
|
|
|
private:
|
|
// 作用域栈
|
|
std::stack<ScopeEntry> scopes_;
|
|
|
|
// 循环嵌套深度
|
|
int loop_depth_ = 0;
|
|
};
|
|
|
|
// 类型兼容性检查函数
|
|
inline bool IsTypeCompatible(SymbolType expected, SymbolType actual) {
|
|
if (expected == SymbolType::TYPE_UNKNOWN || actual == SymbolType::TYPE_UNKNOWN) {
|
|
return true; // 未知类型视为兼容
|
|
}
|
|
|
|
// 基本类型兼容规则
|
|
if (expected == actual) {
|
|
return true;
|
|
}
|
|
|
|
// int 可以隐式转换为 float
|
|
if (expected == SymbolType::TYPE_FLOAT && actual == SymbolType::TYPE_INT) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endif // SYMBOL_TABLE_H
|