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/SymbolTable.h

112 lines
4.2 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.

// 极简符号表:记录局部变量定义点。
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>
#include "SysYParser.h"
#include "ir/IR.h"
// 符号种类
enum class SymbolKind {
Variable,
Function,
Parameter,
Constant
};
// 符号条目
struct Symbol {
std::string name;
SymbolKind kind;
std::shared_ptr<ir::Type> type; // 指向 Type 对象的智能指针
int scope_level = 0; // 定义时的作用域深度
int stack_offset = -1; // 局部变量/参数栈偏移(全局变量为 -1
bool is_initialized = false; // 是否已初始化
bool is_builtin = false; // 是否为库函数
// 对于数组参数,存储维度信息
std::vector<int> array_dims; // 数组各维长度参数数组的第一维可能为0表示省略
bool is_array_param = false; // 是否是数组参数
// 对于函数,额外存储参数列表(类型已包含在函数类型中,这里仅用于快速访问)
std::vector<std::shared_ptr<ir::Type>> param_types;
// 对于常量,存储常量值(这里支持 int32 和 float
union ConstantValue {
int i32;
float f32;
} const_value;
bool is_int_const = true; // 标记常量类型,用于区分 int 和 float
// 关联的语法树节点(用于报错位置或进一步分析)
SysYParser::VarDefContext* var_def_ctx = nullptr;
SysYParser::FuncDefContext* func_def_ctx = nullptr;
};
class SymbolTable {
public:
SymbolTable();
~SymbolTable() = default;
// ----- 作用域管理 -----
void enterScope(); // 进入新作用域
void exitScope(); // 退出当前作用域
int currentScopeLevel() const { return static_cast<int>(scopes_.size()) - 1; }
// ----- 符号操作(推荐使用)-----
bool addSymbol(const Symbol& sym); // 添加符号到当前作用域
Symbol* lookup(const std::string& name); // 从当前作用域向外查找
Symbol* lookupCurrent(const std::string& name); // 仅在当前作用域查找
const Symbol* lookup(const std::string& name) const;
const Symbol* lookupCurrent(const std::string& name) const;
// ----- 与原接口兼容(保留原有功能)-----
void Add(const std::string& name, SysYParser::VarDefContext* decl);
bool Contains(const std::string& name) const;
SysYParser::VarDefContext* Lookup(const std::string& name) const;
// ----- 辅助函数:从语法树节点构造 Type -----
static std::shared_ptr<ir::Type> getTypeFromFuncDef(SysYParser::FuncDefContext* ctx);
void registerBuiltinFunctions();
// 对常量表达式求值(返回整数值,用于数组维度等)
int EvaluateConstExp(SysYParser::ConstExpContext* ctx) const;
// 对常量表达式求值(返回浮点值,用于全局初始化)
float EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const;
// 对常量初始化列表求值,返回一系列常量值(扁平化)
struct ConstValue {
enum Kind { INT, FLOAT };
Kind kind;
union {
int int_val;
float float_val;
};
};
void flattenInit(SysYParser::ConstInitValContext* ctx,
std::vector<ConstValue>& out,
std::shared_ptr<ir::Type> base_type) const;
std::vector<ConstValue> EvaluateConstInitVal(
SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) const;
private:
// 作用域栈:每个元素是一个从名字到符号的映射
std::vector<std::unordered_map<std::string, Symbol>> scopes_;
static constexpr int GLOBAL_SCOPE = 0; // 全局作用域索引
ConstValue EvaluateAddExp(SysYParser::AddExpContext* ctx) const;
ConstValue EvaluateMulExp(SysYParser::MulExpContext* ctx) const;
ConstValue EvaluateUnaryExp(SysYParser::UnaryExpContext* ctx) const;
ConstValue EvaluatePrimaryExp(SysYParser::PrimaryExpContext* ctx) const;
std::shared_ptr<ir::Type> getTypeFromVarDef(SysYParser::VarDefContext* ctx) const;
};