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.
164 lines
4.8 KiB
164 lines
4.8 KiB
#include "../../include/sem/SymbolTable.h"
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
// 进入新作用域
|
|
void SymbolTable::EnterScope() {
|
|
scopes_.push(ScopeEntry());
|
|
}
|
|
|
|
// 离开当前作用域
|
|
void SymbolTable::LeaveScope() {
|
|
if (scopes_.empty()) {
|
|
throw std::runtime_error("SymbolTable Error: 作用域栈为空,无法退出");
|
|
}
|
|
scopes_.pop();
|
|
}
|
|
|
|
// 绑定变量到当前作用域
|
|
void SymbolTable::BindVar(const std::string& name, const VarInfo& info, void* decl_ctx) {
|
|
if (CurrentScopeHasVar(name)) {
|
|
throw std::runtime_error("变量'" + name + "'在当前作用域重复定义");
|
|
}
|
|
scopes_.top().var_symbols[name] = {info, decl_ctx};
|
|
}
|
|
|
|
// 绑定函数到当前作用域
|
|
void SymbolTable::BindFunc(const std::string& name, const FuncInfo& info, void* decl_ctx) {
|
|
if (CurrentScopeHasFunc(name)) {
|
|
throw std::runtime_error("函数'" + name + "'在当前作用域重复定义");
|
|
}
|
|
scopes_.top().func_symbols[name] = {info, decl_ctx};
|
|
}
|
|
|
|
// 查找变量(从当前作用域向上遍历)
|
|
bool SymbolTable::LookupVar(const std::string& name, VarInfo& out_info, void*& out_decl_ctx) const {
|
|
if (scopes_.empty()) {
|
|
return false;
|
|
}
|
|
auto temp_stack = scopes_;
|
|
while (!temp_stack.empty()) {
|
|
auto& scope = temp_stack.top();
|
|
auto it = scope.var_symbols.find(name);
|
|
if (it != scope.var_symbols.end()) {
|
|
out_info = it->second.first;
|
|
out_decl_ctx = it->second.second;
|
|
return true;
|
|
}
|
|
temp_stack.pop();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 查找函数(从当前作用域向上遍历,通常函数在全局作用域)
|
|
bool SymbolTable::LookupFunc(const std::string& name, FuncInfo& out_info, void*& out_decl_ctx) const {
|
|
if (scopes_.empty()) {
|
|
return false;
|
|
}
|
|
auto temp_stack = scopes_;
|
|
while (!temp_stack.empty()) {
|
|
auto& scope = temp_stack.top();
|
|
auto it = scope.func_symbols.find(name);
|
|
if (it != scope.func_symbols.end()) {
|
|
out_info = it->second.first;
|
|
out_decl_ctx = it->second.second;
|
|
return true;
|
|
}
|
|
temp_stack.pop();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 检查当前作用域是否包含指定变量
|
|
bool SymbolTable::CurrentScopeHasVar(const std::string& name) const {
|
|
if (scopes_.empty()) {
|
|
return false;
|
|
}
|
|
return scopes_.top().var_symbols.count(name) > 0;
|
|
}
|
|
|
|
// 检查当前作用域是否包含指定函数
|
|
bool SymbolTable::CurrentScopeHasFunc(const std::string& name) const {
|
|
if (scopes_.empty()) {
|
|
return false;
|
|
}
|
|
return scopes_.top().func_symbols.count(name) > 0;
|
|
}
|
|
|
|
// 进入循环
|
|
void SymbolTable::EnterLoop() {
|
|
loop_depth_++;
|
|
}
|
|
|
|
// 离开循环
|
|
void SymbolTable::ExitLoop() {
|
|
if (loop_depth_ > 0) loop_depth_--;
|
|
}
|
|
|
|
// 检查是否在循环内
|
|
bool SymbolTable::InLoop() const {
|
|
return loop_depth_ > 0;
|
|
}
|
|
|
|
// 清空所有作用域和状态
|
|
void SymbolTable::Clear() {
|
|
while (!scopes_.empty()) {
|
|
scopes_.pop();
|
|
}
|
|
loop_depth_ = 0;
|
|
}
|
|
|
|
// 获取当前作用域中所有变量名
|
|
std::vector<std::string> SymbolTable::GetCurrentScopeVarNames() const {
|
|
std::vector<std::string> names;
|
|
if (!scopes_.empty()) {
|
|
for (const auto& pair : scopes_.top().var_symbols) {
|
|
names.push_back(pair.first);
|
|
}
|
|
}
|
|
return names;
|
|
}
|
|
|
|
// 获取当前作用域中所有函数名
|
|
std::vector<std::string> SymbolTable::GetCurrentScopeFuncNames() const {
|
|
std::vector<std::string> names;
|
|
if (!scopes_.empty()) {
|
|
for (const auto& pair : scopes_.top().func_symbols) {
|
|
names.push_back(pair.first);
|
|
}
|
|
}
|
|
return names;
|
|
}
|
|
|
|
// 调试:打印符号表内容
|
|
void SymbolTable::Dump() const {
|
|
std::cout << "符号表内容 (作用域深度: " << scopes_.size() << "):\n";
|
|
int scope_idx = 0;
|
|
auto temp_stack = scopes_;
|
|
|
|
while (!temp_stack.empty()) {
|
|
std::cout << "\n作用域 " << scope_idx++ << ":\n";
|
|
auto& scope = temp_stack.top();
|
|
|
|
std::cout << " 变量:\n";
|
|
for (const auto& var_pair : scope.var_symbols) {
|
|
const VarInfo& info = var_pair.second.first;
|
|
std::cout << " " << var_pair.first << ": "
|
|
<< SymbolTypeToString(info.type)
|
|
<< (info.is_const ? " (const)" : "")
|
|
<< (info.IsArray() ? " [数组]" : "")
|
|
<< "\n";
|
|
}
|
|
|
|
std::cout << " 函数:\n";
|
|
for (const auto& func_pair : scope.func_symbols) {
|
|
const FuncInfo& info = func_pair.second.first;
|
|
std::cout << " " << func_pair.first << ": "
|
|
<< SymbolTypeToString(info.ret_type) << " ("
|
|
<< info.param_types.size() << " 个参数)\n";
|
|
}
|
|
|
|
temp_stack.pop();
|
|
}
|
|
} |