|
|
// 基于语法树的语义检查与名称绑定。
|
|
|
#pragma once
|
|
|
|
|
|
#include <unordered_map>
|
|
|
#include <vector>
|
|
|
#include <memory>
|
|
|
|
|
|
#include "SysYParser.h"
|
|
|
#include "ir/IR.h"
|
|
|
|
|
|
#define Sema_DEBUG 0
|
|
|
|
|
|
// 表达式信息结构
|
|
|
struct ExprInfo {
|
|
|
std::shared_ptr<ir::Type> type = nullptr;
|
|
|
bool is_lvalue = false;
|
|
|
bool is_const = false;
|
|
|
bool is_const_int = false; // 是否是整型常量
|
|
|
int const_int_value = 0;
|
|
|
float const_float_value = 0.0f;
|
|
|
antlr4::ParserRuleContext* node = nullptr; // 对应的语法树节点
|
|
|
};
|
|
|
|
|
|
// 语义分析上下文:存储分析过程中产生的信息
|
|
|
class SemanticContext {
|
|
|
public:
|
|
|
// ----- 变量使用绑定(使用 LValContext 而不是 VarContext)-----
|
|
|
void BindVarUse(SysYParser::LValContext* use,
|
|
|
SysYParser::VarDefContext* decl) {
|
|
|
var_uses_[use] = decl;
|
|
|
}
|
|
|
|
|
|
SysYParser::VarDefContext* ResolveVarUse(
|
|
|
const SysYParser::LValContext* use) const {
|
|
|
auto it = var_uses_.find(use);
|
|
|
return it == var_uses_.end() ? nullptr : it->second;
|
|
|
}
|
|
|
|
|
|
void BindConstUse(SysYParser::LValContext* use, SysYParser::ConstDefContext* decl) {
|
|
|
const_uses_[use] = decl;
|
|
|
}
|
|
|
SysYParser::ConstDefContext* ResolveConstUse(const SysYParser::LValContext* use) const {
|
|
|
auto it = const_uses_.find(use);
|
|
|
return it == const_uses_.end() ? nullptr : it->second;
|
|
|
}
|
|
|
|
|
|
// ----- 表达式类型信息存储 -----
|
|
|
void SetExprType(antlr4::ParserRuleContext* node, const ExprInfo& info) {
|
|
|
ExprInfo copy = info;
|
|
|
copy.node = node;
|
|
|
expr_types_[node] = copy;
|
|
|
}
|
|
|
|
|
|
ExprInfo* GetExprType(antlr4::ParserRuleContext* node) {
|
|
|
auto it = expr_types_.find(node);
|
|
|
return it == expr_types_.end() ? nullptr : &it->second;
|
|
|
}
|
|
|
|
|
|
const ExprInfo* GetExprType(antlr4::ParserRuleContext* node) const {
|
|
|
auto it = expr_types_.find(node);
|
|
|
return it == expr_types_.end() ? nullptr : &it->second;
|
|
|
}
|
|
|
|
|
|
// ----- 隐式转换标记(供 IR 生成使用)-----
|
|
|
struct ConversionInfo {
|
|
|
antlr4::ParserRuleContext* node;
|
|
|
std::shared_ptr<ir::Type> from_type;
|
|
|
std::shared_ptr<ir::Type> to_type;
|
|
|
};
|
|
|
|
|
|
void AddConversion(antlr4::ParserRuleContext* node,
|
|
|
std::shared_ptr<ir::Type> from,
|
|
|
std::shared_ptr<ir::Type> to) {
|
|
|
conversions_.push_back({node, from, to});
|
|
|
}
|
|
|
|
|
|
const std::vector<ConversionInfo>& GetConversions() const { return conversions_; }
|
|
|
|
|
|
private:
|
|
|
// 变量使用映射 - 使用 LValContext 作为键
|
|
|
std::unordered_map<const SysYParser::LValContext*,
|
|
|
SysYParser::VarDefContext*> var_uses_;
|
|
|
|
|
|
// 表达式类型映射
|
|
|
std::unordered_map<antlr4::ParserRuleContext*, ExprInfo> expr_types_;
|
|
|
|
|
|
// 隐式转换列表
|
|
|
std::vector<ConversionInfo> conversions_;
|
|
|
|
|
|
std::unordered_map<const SysYParser::LValContext*, SysYParser::ConstDefContext*> const_uses_;
|
|
|
};
|
|
|
|
|
|
// 目前仅检查:
|
|
|
// - 变量先声明后使用
|
|
|
// - 局部变量不允许重复定义
|
|
|
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit); |