|
|
|
|
@ -69,7 +69,7 @@ public:
|
|
|
|
|
} else {
|
|
|
|
|
return_type = ir::Type::GetInt32Type();
|
|
|
|
|
}
|
|
|
|
|
std::cout << "[DEBUG] 进入函数: " << name
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 进入函数: " << name
|
|
|
|
|
<< " 返回类型: " << (return_type->IsInt32() ? "int" :
|
|
|
|
|
return_type->IsFloat() ? "float" : "void")
|
|
|
|
|
<< std::endl;
|
|
|
|
|
@ -85,7 +85,7 @@ public:
|
|
|
|
|
if (ctx->block()) { // 处理函数体
|
|
|
|
|
ctx->block()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
std::cout << "[DEBUG] 函数 " << name
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 函数 " << name
|
|
|
|
|
<< " has_return: " << current_func_has_return_
|
|
|
|
|
<< " return_type_is_void: " << return_type->IsVoid()
|
|
|
|
|
<< std::endl;
|
|
|
|
|
@ -172,7 +172,7 @@ public:
|
|
|
|
|
std::vector<int> dims;
|
|
|
|
|
bool is_array = !ctx->constExp().empty();
|
|
|
|
|
// 调试输出
|
|
|
|
|
std::cout << "[DEBUG] CheckVarDef: " << name
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] CheckVarDef: " << name
|
|
|
|
|
<< " base_type: " << (base_type->IsInt32() ? "int" : base_type->IsFloat() ? "float" : "unknown")
|
|
|
|
|
<< " is_array: " << is_array
|
|
|
|
|
<< " dim_count: " << ctx->constExp().size() << std::endl;
|
|
|
|
|
@ -187,23 +187,23 @@ public:
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "数组维度必须为正整数"));
|
|
|
|
|
}
|
|
|
|
|
dims.push_back(dim);
|
|
|
|
|
std::cout << "[DEBUG] dim[" << dims.size() - 1 << "] = " << dim << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] dim[" << dims.size() - 1 << "] = " << dim << std::endl;
|
|
|
|
|
}
|
|
|
|
|
// 创建数组类型
|
|
|
|
|
type = ir::Type::GetArrayType(base_type, dims);
|
|
|
|
|
std::cout << "[DEBUG] 创建数组类型完成" << std::endl;
|
|
|
|
|
std::cout << "[DEBUG] type->IsArray(): " << type->IsArray() << std::endl;
|
|
|
|
|
std::cout << "[DEBUG] type->GetKind(): " << (int)type->GetKind() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 创建数组类型完成" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] type->IsArray(): " << type->IsArray() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] type->GetKind(): " << (int)type->GetKind() << std::endl;
|
|
|
|
|
// 验证数组类型
|
|
|
|
|
if (type->IsArray()) {
|
|
|
|
|
auto* arr_type = dynamic_cast<ir::ArrayType*>(type.get());
|
|
|
|
|
if (arr_type) {
|
|
|
|
|
std::cout << "[DEBUG] ArrayType dimensions: ";
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] ArrayType dimensions: ";
|
|
|
|
|
for (int d : arr_type->GetDimensions()) {
|
|
|
|
|
std::cout << d << " ";
|
|
|
|
|
if (Sema_DEBUG) std::cout << d << " ";
|
|
|
|
|
}
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
std::cout << "[DEBUG] Element type: "
|
|
|
|
|
if (Sema_DEBUG) std::cout << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] Element type: "
|
|
|
|
|
<< (arr_type->GetElementType()->IsInt32() ? "int" :
|
|
|
|
|
arr_type->GetElementType()->IsFloat() ? "float" : "unknown")
|
|
|
|
|
<< std::endl;
|
|
|
|
|
@ -232,7 +232,7 @@ public:
|
|
|
|
|
sym.param_types.clear(); // 确保不混淆
|
|
|
|
|
}
|
|
|
|
|
table_.addSymbol(sym); // 添加到符号表
|
|
|
|
|
std::cout << "[DEBUG] 符号添加完成: " << name
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 符号添加完成: " << name
|
|
|
|
|
<< " type_kind: " << (int)sym.type->GetKind()
|
|
|
|
|
<< " is_array: " << sym.type->IsArray()
|
|
|
|
|
<< std::endl;
|
|
|
|
|
@ -265,7 +265,7 @@ public:
|
|
|
|
|
std::shared_ptr<ir::Type> type = base_type;
|
|
|
|
|
std::vector<int> dims;
|
|
|
|
|
bool is_array = !ctx->constExp().empty();
|
|
|
|
|
std::cout << "[DEBUG] CheckConstDef: " << name
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] CheckConstDef: " << name
|
|
|
|
|
<< " base_type: " << (base_type->IsInt32() ? "int" : base_type->IsFloat() ? "float" : "unknown")
|
|
|
|
|
<< " is_array: " << is_array
|
|
|
|
|
<< " dim_count: " << ctx->constExp().size() << std::endl;
|
|
|
|
|
@ -276,10 +276,10 @@ public:
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "数组维度必须为正整数"));
|
|
|
|
|
}
|
|
|
|
|
dims.push_back(dim);
|
|
|
|
|
std::cout << "[DEBUG] dim[" << dims.size() - 1 << "] = " << dim << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] dim[" << dims.size() - 1 << "] = " << dim << std::endl;
|
|
|
|
|
}
|
|
|
|
|
type = ir::Type::GetArrayType(base_type, dims);
|
|
|
|
|
std::cout << "[DEBUG] 创建数组类型完成,IsArray: " << type->IsArray() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 创建数组类型完成,IsArray: " << type->IsArray() << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ========== 绑定维度表达式 ==========
|
|
|
|
|
@ -294,14 +294,14 @@ public:
|
|
|
|
|
BindConstInitVal(ctx->constInitVal());
|
|
|
|
|
|
|
|
|
|
init_values = table_.EvaluateConstInitVal(ctx->constInitVal(), dims, base_type);
|
|
|
|
|
std::cout << "[DEBUG] 初始化值数量: " << init_values.size() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 初始化值数量: " << init_values.size() << std::endl;
|
|
|
|
|
}
|
|
|
|
|
// 检查初始化值数量
|
|
|
|
|
size_t expected_count = 1;
|
|
|
|
|
if (is_array) {
|
|
|
|
|
expected_count = 1;
|
|
|
|
|
for (int d : dims) expected_count *= d;
|
|
|
|
|
std::cout << "[DEBUG] 期望元素数量: " << expected_count << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 期望元素数量: " << expected_count << std::endl;
|
|
|
|
|
}
|
|
|
|
|
if (init_values.size() > expected_count) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "初始化值过多"));
|
|
|
|
|
@ -309,14 +309,14 @@ public:
|
|
|
|
|
Symbol sym;
|
|
|
|
|
sym.name = name;
|
|
|
|
|
sym.kind = SymbolKind::Constant;
|
|
|
|
|
std::cout << "CheckConstDef: before addSymbol, sym.kind = " << (int)sym.kind << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "CheckConstDef: before addSymbol, sym.kind = " << (int)sym.kind << std::endl;
|
|
|
|
|
sym.type = type;
|
|
|
|
|
sym.scope_level = table_.currentScopeLevel();
|
|
|
|
|
sym.is_initialized = true;
|
|
|
|
|
sym.var_def_ctx = nullptr;
|
|
|
|
|
sym.const_def_ctx = ctx;
|
|
|
|
|
sym.const_def_ctx = ctx;
|
|
|
|
|
std::cout << "保存常量定义上下文: " << name << ", ctx: " << ctx << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "保存常量定义上下文: " << name << ", ctx: " << ctx << std::endl;
|
|
|
|
|
// 存储常量值(仅对非数组有效)
|
|
|
|
|
if (!is_array && !init_values.empty()) {
|
|
|
|
|
if (base_type->IsInt32() && init_values[0].kind == SymbolTable::ConstValue::INT) {
|
|
|
|
|
@ -327,14 +327,14 @@ public:
|
|
|
|
|
sym.const_value.f32 = init_values[0].float_val;
|
|
|
|
|
}
|
|
|
|
|
} else if (is_array) {
|
|
|
|
|
std::cout << "[DEBUG] 数组常量,不存储单个常量值" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 数组常量,不存储单个常量值" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
table_.addSymbol(sym);
|
|
|
|
|
std::cout << "CheckConstDef: after addSymbol, sym.kind = " << (int)sym.kind << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "CheckConstDef: after addSymbol, sym.kind = " << (int)sym.kind << std::endl;
|
|
|
|
|
auto* stored = table_.lookup(name);
|
|
|
|
|
std::cout << "CheckConstDef: after addSymbol, stored const_def_ctx = " << stored->const_def_ctx << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "CheckConstDef: after addSymbol, stored const_def_ctx = " << stored->const_def_ctx << std::endl;
|
|
|
|
|
|
|
|
|
|
std::cout << "[DEBUG] 常量符号添加完成" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 常量符号添加完成" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 语句语义检查 ====================
|
|
|
|
|
@ -343,20 +343,20 @@ public:
|
|
|
|
|
std::any visitStmt(SysYParser::StmtContext* ctx) override {
|
|
|
|
|
if (!ctx) return {};
|
|
|
|
|
// 调试输出
|
|
|
|
|
std::cout << "[DEBUG] visitStmt: ";
|
|
|
|
|
if (ctx->Return()) std::cout << "Return ";
|
|
|
|
|
if (ctx->If()) std::cout << "If ";
|
|
|
|
|
if (ctx->While()) std::cout << "While ";
|
|
|
|
|
if (ctx->Break()) std::cout << "Break ";
|
|
|
|
|
if (ctx->Continue()) std::cout << "Continue ";
|
|
|
|
|
if (ctx->lVal() && ctx->Assign()) std::cout << "Assign ";
|
|
|
|
|
if (ctx->exp() && ctx->Semi()) std::cout << "ExpStmt ";
|
|
|
|
|
if (ctx->block()) std::cout << "Block ";
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] visitStmt: ";
|
|
|
|
|
if (ctx->Return()) if (Sema_DEBUG) std::cout << "Return ";
|
|
|
|
|
if (ctx->If()) if (Sema_DEBUG) std::cout << "If ";
|
|
|
|
|
if (ctx->While()) if (Sema_DEBUG) std::cout << "While ";
|
|
|
|
|
if (ctx->Break()) if (Sema_DEBUG) std::cout << "Break ";
|
|
|
|
|
if (ctx->Continue()) if (Sema_DEBUG) std::cout << "Continue ";
|
|
|
|
|
if (ctx->lVal() && ctx->Assign()) if (Sema_DEBUG) std::cout << "Assign ";
|
|
|
|
|
if (ctx->exp() && ctx->Semi()) if (Sema_DEBUG) std::cout << "ExpStmt ";
|
|
|
|
|
if (ctx->block()) if (Sema_DEBUG) std::cout << "Block ";
|
|
|
|
|
if (Sema_DEBUG) std::cout << std::endl;
|
|
|
|
|
// 判断语句类型 - 注意:Return() 返回的是 TerminalNode*
|
|
|
|
|
if (ctx->Return() != nullptr) {
|
|
|
|
|
// return 语句
|
|
|
|
|
std::cout << "[DEBUG] 检测到 return 语句" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 检测到 return 语句" << std::endl;
|
|
|
|
|
return visitReturnStmtInternal(ctx);
|
|
|
|
|
} else if (ctx->lVal() != nullptr && ctx->Assign() != nullptr) {
|
|
|
|
|
// 赋值语句
|
|
|
|
|
@ -385,14 +385,14 @@ public:
|
|
|
|
|
|
|
|
|
|
// return 语句内部实现
|
|
|
|
|
std::any visitReturnStmtInternal(SysYParser::StmtContext* ctx) {
|
|
|
|
|
std::cout << "[DEBUG] visitReturnStmtInternal 被调用" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] visitReturnStmtInternal 被调用" << std::endl;
|
|
|
|
|
std::shared_ptr<ir::Type> expected = current_func_return_type_;
|
|
|
|
|
if (!expected) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "return 语句不在函数体内"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->exp() != nullptr) {
|
|
|
|
|
// 有返回值的 return
|
|
|
|
|
std::cout << "[DEBUG] 有返回值的 return" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 有返回值的 return" << std::endl;
|
|
|
|
|
ExprInfo ret_val = CheckExp(ctx->exp());
|
|
|
|
|
if (expected->IsVoid()) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "void 函数不能返回值"));
|
|
|
|
|
@ -405,23 +405,23 @@ public:
|
|
|
|
|
}
|
|
|
|
|
// 设置 has_return 标志
|
|
|
|
|
current_func_has_return_ = true;
|
|
|
|
|
std::cout << "[DEBUG] 设置 current_func_has_return_ = true" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 设置 current_func_has_return_ = true" << std::endl;
|
|
|
|
|
} else {
|
|
|
|
|
// 无返回值的 return
|
|
|
|
|
std::cout << "[DEBUG] 无返回值的 return" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 无返回值的 return" << std::endl;
|
|
|
|
|
if (!expected->IsVoid()) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "非 void 函数必须返回值"));
|
|
|
|
|
}
|
|
|
|
|
// 设置 has_return 标志
|
|
|
|
|
current_func_has_return_ = true;
|
|
|
|
|
std::cout << "[DEBUG] 设置 current_func_has_return_ = true" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 设置 current_func_has_return_ = true" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 左值表达式(变量引用)
|
|
|
|
|
std::any visitLVal(SysYParser::LValContext* ctx) override {
|
|
|
|
|
std::cout << "[DEBUG] visitLVal: " << ctx->getText() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] visitLVal: " << ctx->getText() << std::endl;
|
|
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "非法变量引用"));
|
|
|
|
|
}
|
|
|
|
|
@ -432,7 +432,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
// 检查数组访问
|
|
|
|
|
bool is_array_access = !ctx->exp().empty();
|
|
|
|
|
std::cout << "[DEBUG] name: " << name
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] name: " << name
|
|
|
|
|
<< ", is_array_access: " << is_array_access
|
|
|
|
|
<< ", subscript_count: " << ctx->exp().size() << std::endl;
|
|
|
|
|
ExprInfo result;
|
|
|
|
|
@ -440,7 +440,7 @@ public:
|
|
|
|
|
bool is_array_or_ptr = false;
|
|
|
|
|
if (sym->type) {
|
|
|
|
|
is_array_or_ptr = sym->type->IsArray() || sym->type->IsPtrInt32() || sym->type->IsPtrFloat();
|
|
|
|
|
std::cout << "[DEBUG] type_kind: " << (int)sym->type->GetKind()
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] type_kind: " << (int)sym->type->GetKind()
|
|
|
|
|
<< ", is_array: " << sym->type->IsArray()
|
|
|
|
|
<< ", is_ptr: " << (sym->type->IsPtrInt32() || sym->type->IsPtrFloat()) << std::endl;
|
|
|
|
|
}
|
|
|
|
|
@ -453,7 +453,7 @@ public:
|
|
|
|
|
if (auto* arr_type = dynamic_cast<ir::ArrayType*>(sym->type.get())) {
|
|
|
|
|
dim_count = arr_type->GetDimensions().size();
|
|
|
|
|
elem_type = arr_type->GetElementType();
|
|
|
|
|
std::cout << "[DEBUG] 数组维度: " << dim_count << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 数组维度: " << dim_count << std::endl;
|
|
|
|
|
}
|
|
|
|
|
} else if (sym->type->IsPtrInt32() || sym->type->IsPtrFloat()) {
|
|
|
|
|
dim_count = 1;
|
|
|
|
|
@ -462,11 +462,11 @@ public:
|
|
|
|
|
} else if (sym->type->IsPtrFloat()) {
|
|
|
|
|
elem_type = ir::Type::GetFloatType();
|
|
|
|
|
}
|
|
|
|
|
std::cout << "[DEBUG] 指针类型, dim_count: 1" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 指针类型, dim_count: 1" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_array_access) {
|
|
|
|
|
std::cout << "[DEBUG] 有下标访问,期望维度: " << dim_count
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 有下标访问,期望维度: " << dim_count
|
|
|
|
|
<< ", 实际下标数: " << ctx->exp().size() << std::endl;
|
|
|
|
|
if (ctx->exp().size() != dim_count) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "数组下标个数不匹配"));
|
|
|
|
|
@ -481,9 +481,9 @@ public:
|
|
|
|
|
result.is_lvalue = true;
|
|
|
|
|
result.is_const = false;
|
|
|
|
|
} else {
|
|
|
|
|
std::cout << "[DEBUG] 无下标访问" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 无下标访问" << std::endl;
|
|
|
|
|
if (sym->type->IsArray()) {
|
|
|
|
|
std::cout << "[DEBUG] 数组名作为地址,转换为指针" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 数组名作为地址,转换为指针" << std::endl;
|
|
|
|
|
if (auto* arr_type = dynamic_cast<ir::ArrayType*>(sym->type.get())) {
|
|
|
|
|
if (arr_type->GetElementType()->IsInt32()) {
|
|
|
|
|
result.type = ir::Type::GetPtrInt32Type();
|
|
|
|
|
@ -605,7 +605,7 @@ public:
|
|
|
|
|
|
|
|
|
|
// 主表达式
|
|
|
|
|
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override {
|
|
|
|
|
std::cout << "[DEBUG] visitPrimaryExp: " << ctx->getText() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] visitPrimaryExp: " << ctx->getText() << std::endl;
|
|
|
|
|
ExprInfo result;
|
|
|
|
|
if (ctx->lVal()) { // 左值表达式
|
|
|
|
|
result = CheckLValue(ctx->lVal());
|
|
|
|
|
@ -637,14 +637,14 @@ public:
|
|
|
|
|
|
|
|
|
|
// 一元表达式
|
|
|
|
|
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override {
|
|
|
|
|
std::cout << "[DEBUG] visitUnaryExp: " << ctx->getText() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] visitUnaryExp: " << ctx->getText() << std::endl;
|
|
|
|
|
ExprInfo result;
|
|
|
|
|
if (ctx->primaryExp()) {
|
|
|
|
|
ctx->primaryExp()->accept(this);
|
|
|
|
|
auto* info = sema_.GetExprType(ctx->primaryExp());
|
|
|
|
|
if (info) result = *info;
|
|
|
|
|
} else if (ctx->Ident() && ctx->L_PAREN()) { // 函数调用
|
|
|
|
|
std::cout << "[DEBUG] 函数调用: " << ctx->Ident()->getText() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 函数调用: " << ctx->Ident()->getText() << std::endl;
|
|
|
|
|
result = CheckFuncCall(ctx);
|
|
|
|
|
} else if (ctx->unaryOp()) { // 一元运算
|
|
|
|
|
ctx->unaryExp()->accept(this);
|
|
|
|
|
@ -1025,7 +1025,7 @@ private:
|
|
|
|
|
if (!ctx || !ctx->addExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "无效表达式"));
|
|
|
|
|
}
|
|
|
|
|
std::cout << "[DEBUG] CheckExp: " << ctx->getText() << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] CheckExp: " << ctx->getText() << std::endl;
|
|
|
|
|
ctx->addExp()->accept(this);
|
|
|
|
|
auto* info = sema_.GetExprType(ctx->addExp());
|
|
|
|
|
if (!info) {
|
|
|
|
|
@ -1076,18 +1076,18 @@ private:
|
|
|
|
|
if (!sym) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "未定义的变量: " + name));
|
|
|
|
|
}
|
|
|
|
|
std::cout << "CheckLValue: found sym->name = " << sym->name
|
|
|
|
|
if (Sema_DEBUG) std::cout << "CheckLValue: found sym->name = " << sym->name
|
|
|
|
|
<< ", sym->kind = " << (int)sym->kind << std::endl;
|
|
|
|
|
|
|
|
|
|
if (sym->kind == SymbolKind::Variable && sym->var_def_ctx) {
|
|
|
|
|
sema_.BindVarUse(ctx, sym->var_def_ctx);
|
|
|
|
|
std::cout << "绑定变量: " << name << " -> VarDefContext" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "绑定变量: " << name << " -> VarDefContext" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
else if (sym->kind == SymbolKind::Constant && sym->const_def_ctx) {
|
|
|
|
|
sema_.BindConstUse(ctx, sym->const_def_ctx);
|
|
|
|
|
std::cout << "绑定常量: " << name << " -> ConstDefContext" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "绑定常量: " << name << " -> ConstDefContext" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
std::cout << "CheckLValue 绑定变量: " << name
|
|
|
|
|
if (Sema_DEBUG) std::cout << "CheckLValue 绑定变量: " << name
|
|
|
|
|
<< ", sym->kind: " << (int)sym->kind
|
|
|
|
|
<< ", sym->var_def_ctx: " << sym->var_def_ctx
|
|
|
|
|
<< ", sym->const_def_ctx: " << sym->const_def_ctx << std::endl;
|
|
|
|
|
@ -1122,9 +1122,9 @@ private:
|
|
|
|
|
} else if (sym->type->IsPtrFloat()) {
|
|
|
|
|
elem_type = ir::Type::GetFloatType();
|
|
|
|
|
}
|
|
|
|
|
std::cout << "数组参数维度: " << dim_count << " 维, dims: ";
|
|
|
|
|
for (int d : dims) std::cout << d << " ";
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "数组参数维度: " << dim_count << " 维, dims: ";
|
|
|
|
|
for (int d : dims) if (Sema_DEBUG) std::cout << d << " ";
|
|
|
|
|
if (Sema_DEBUG) std::cout << std::endl;
|
|
|
|
|
} else if (sym->type && (sym->type->IsPtrInt32() || sym->type->IsPtrFloat())) {
|
|
|
|
|
// 普通指针,只能有一个下标
|
|
|
|
|
dim_count = 1;
|
|
|
|
|
@ -1137,7 +1137,7 @@ private:
|
|
|
|
|
|
|
|
|
|
size_t subscript_count = ctx->exp().size();
|
|
|
|
|
|
|
|
|
|
std::cout << "dim_count: " << dim_count << ", subscript_count: " << subscript_count << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "dim_count: " << dim_count << ", subscript_count: " << subscript_count << std::endl;
|
|
|
|
|
|
|
|
|
|
if (dim_count > 0 || sym->is_array_param || sym->type->IsArray() ||
|
|
|
|
|
sym->type->IsPtrInt32() || sym->type->IsPtrFloat()) {
|
|
|
|
|
@ -1158,11 +1158,11 @@ private:
|
|
|
|
|
|
|
|
|
|
if (subscript_count == dim_count) {
|
|
|
|
|
// 完全索引,返回元素类型
|
|
|
|
|
std::cout << "完全索引,返回元素类型" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "完全索引,返回元素类型" << std::endl;
|
|
|
|
|
return {elem_type, true, false};
|
|
|
|
|
} else {
|
|
|
|
|
// 部分索引,返回子数组的指针类型
|
|
|
|
|
std::cout << "部分索引,返回指针类型" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "部分索引,返回指针类型" << std::endl;
|
|
|
|
|
// 计算剩余维度的指针类型
|
|
|
|
|
if (elem_type->IsInt32()) {
|
|
|
|
|
return {ir::Type::GetPtrInt32Type(), false, false};
|
|
|
|
|
@ -1176,7 +1176,7 @@ private:
|
|
|
|
|
// 没有下标访问
|
|
|
|
|
if (sym->type && sym->type->IsArray()) {
|
|
|
|
|
// 数组名作为地址
|
|
|
|
|
std::cout << "数组名作为地址" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "数组名作为地址" << std::endl;
|
|
|
|
|
if (auto* arr_type = dynamic_cast<ir::ArrayType*>(sym->type.get())) {
|
|
|
|
|
if (arr_type->GetElementType()->IsInt32()) {
|
|
|
|
|
return {ir::Type::GetPtrInt32Type(), false, true};
|
|
|
|
|
@ -1187,7 +1187,7 @@ private:
|
|
|
|
|
return {ir::Type::GetPtrInt32Type(), false, true};
|
|
|
|
|
} else if (sym->is_array_param) {
|
|
|
|
|
// 数组参数名作为地址
|
|
|
|
|
std::cout << "数组参数名作为地址" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) std::cout << "数组参数名作为地址" << std::endl;
|
|
|
|
|
if (sym->type->IsPtrInt32()) {
|
|
|
|
|
return {ir::Type::GetPtrInt32Type(), false, true};
|
|
|
|
|
} else {
|
|
|
|
|
@ -1211,14 +1211,14 @@ private:
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "非法函数调用"));
|
|
|
|
|
}
|
|
|
|
|
std::string func_name = ctx->Ident()->getText();
|
|
|
|
|
std::cout << "[DEBUG] CheckFuncCall: " << func_name << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] CheckFuncCall: " << func_name << std::endl;
|
|
|
|
|
auto* func_sym = table_.lookup(func_name);
|
|
|
|
|
if (!func_sym || func_sym->kind != SymbolKind::Function) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "未定义的函数: " + func_name));
|
|
|
|
|
}
|
|
|
|
|
std::vector<ExprInfo> args;
|
|
|
|
|
if (ctx->funcRParams()) {
|
|
|
|
|
std::cout << "[DEBUG] 处理函数调用参数:" << std::endl;
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 处理函数调用参数:" << std::endl;
|
|
|
|
|
for (auto* exp : ctx->funcRParams()->exp()) {
|
|
|
|
|
if (exp) {
|
|
|
|
|
args.push_back(CheckExp(exp));
|
|
|
|
|
@ -1229,7 +1229,7 @@ private:
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "参数个数不匹配"));
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0; i < std::min(args.size(), func_sym->param_types.size()); ++i) {
|
|
|
|
|
std::cout << "[DEBUG] 检查参数 " << i << ": 实参类型 " << (int)args[i].type->GetKind()
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 检查参数 " << i << ": 实参类型 " << (int)args[i].type->GetKind()
|
|
|
|
|
<< " 形参类型 " << (int)func_sym->param_types[i]->GetKind() << std::endl;
|
|
|
|
|
if (!IsTypeCompatible(args[i].type, func_sym->param_types[i])) {
|
|
|
|
|
throw std::runtime_error(FormatError("sema", "参数类型不匹配"));
|
|
|
|
|
@ -1430,10 +1430,10 @@ private:
|
|
|
|
|
sym.array_dims = dims;
|
|
|
|
|
table_.addSymbol(sym);
|
|
|
|
|
|
|
|
|
|
std::cout << "[DEBUG] 添加参数: " << name << " type_kind: " << (int)param_type->GetKind()
|
|
|
|
|
if (Sema_DEBUG) if (Sema_DEBUG) std::cout << "[DEBUG] 添加参数: " << name << " type_kind: " << (int)param_type->GetKind()
|
|
|
|
|
<< " is_array: " << is_array << " dims: ";
|
|
|
|
|
for (int d : dims) std::cout << d << " ";
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
for (int d : dims) if (Sema_DEBUG) std::cout << d << " ";
|
|
|
|
|
if (Sema_DEBUG) std::cout << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|