chore(sem)合并ir分支到sem

feature/sem
mxr 2 weeks ago
commit 6cc1908515

@ -0,0 +1,86 @@
// 将语法树翻译为 IR。
// 实现拆分在 IRGenFunc/IRGenStmt/IRGenExp/IRGenDecl。
#pragma once
#include <any>
#include <memory>
#include <string>
#include <unordered_map>
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "ir/IR.h"
#include "sem/Sema.h"
namespace ir {
class Module;
class Function;
class IRBuilder;
class Value;
}
class IRGenImpl final : public SysYBaseVisitor {
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
// 顶层
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
// 块
std::any visitBlock(SysYParser::BlockContext* ctx) override;
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
// 声明
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
// 语句
std::any visitStmt(SysYParser::StmtContext* ctx) override;
// 表达式
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
private:
enum class BlockFlow {
Continue,
Terminated,
};
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
ir::Value* EvalCond(SysYParser::CondContext& cond);
// 辅助函数
BlockFlow HandleReturnStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleIfStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleWhileStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleBreakStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleContinueStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleAssignStmt(SysYParser::StmtContext* ctx);
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
// 循环栈,用于 break/continue
struct LoopContext {
ir::BasicBlock* condBlock;
ir::BasicBlock* bodyBlock;
ir::BasicBlock* exitBlock;
};
std::vector<LoopContext> loopStack_;
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema);

@ -5,6 +5,7 @@ add_subdirectory(ir)
add_subdirectory(frontend)
if(NOT COMPILER_PARSE_ONLY)
add_subdirectory(sem)
add_subdirectory(irgen)
add_subdirectory(mir)
endif()
@ -19,6 +20,7 @@ target_link_libraries(compiler PRIVATE
if(NOT COMPILER_PARSE_ONLY)
target_link_libraries(compiler PRIVATE
sem
irgen
mir
)
target_compile_definitions(compiler PRIVATE COMPILER_PARSE_ONLY=0)

@ -1,3 +1,13 @@
add_library(irgen STATIC
IRGenDriver.cpp
IRGenFunc.cpp
IRGenStmt.cpp
IRGenExp.cpp
IRGenDecl.cpp
)
target_link_libraries(irgen PUBLIC
build_options
${ANTLR4_RUNTIME_TARGET}
ir
)

@ -0,0 +1,83 @@
#include "irgen/IRGen.h"
#include <stdexcept>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
namespace {
// 使用 LValContext 而不是 LValueContext
std::string GetLValueName(SysYParser::LValContext& lvalue) {
if (!lvalue.Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
return lvalue.Ident()->getText();
}
} // namespace
// 注意visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
}
// 处理 varDecl
if (auto* varDecl = ctx->varDecl()) {
// 检查类型
if (varDecl->bType() && varDecl->bType()->Int()) {
for (auto* varDef : varDecl->varDef()) {
varDef->accept(this);
}
} else {
throw std::runtime_error(FormatError("irgen", "当前仅支持 int 类型变量"));
}
}
// 处理 constDecl暂不支持
if (ctx->constDecl()) {
throw std::runtime_error(FormatError("irgen", "常量声明暂未实现"));
}
return {};
}
std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
}
// 使用 Ident() 而不是 lValue()
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
std::string varName = ctx->Ident()->getText();
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
}
// 分配存储
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
// 使用 initVal() 而不是 initValue()
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
} else {
// 数组初始化暂不支持
init = builder_.CreateConstInt(0);
}
} else {
init = builder_.CreateConstInt(0);
}
builder_.CreateStore(init, slot);
return {};
}

@ -0,0 +1,15 @@
#include "irgen/IRGen.h"
#include <memory>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema) {
auto module = std::make_unique<ir::Module>();
IRGenImpl gen(*module, sema);
tree.accept(&gen);
return module;
}

@ -0,0 +1,202 @@
#include "irgen/IRGen.h"
#include <stdexcept>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
// 表达式生成当前也只实现了很小的一个子集。
// 目前支持:
// - 整数字面量
// - 普通局部变量读取
// - 括号表达式
// - 二元加法
//
// 还未支持:
// - 减乘除与一元运算
// - 赋值表达式
// - 函数调用
// - 数组、指针、下标访问
// - 条件与比较表达式
// - ...
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
return std::any_cast<ir::Value*>(expr.accept(this));
}
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
return std::any_cast<ir::Value*>(cond.accept(this));
}
// 基本表达式:数字、变量、括号表达式
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
}
// 处理数字字面量
if (ctx->DECIMAL_INT()) {
int value = std::stoi(ctx->DECIMAL_INT()->getText());
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
}
if (ctx->HEX_INT()) {
std::string hex = ctx->HEX_INT()->getText();
int value = std::stoi(hex, nullptr, 16);
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
}
if (ctx->OCTAL_INT()) {
std::string oct = ctx->OCTAL_INT()->getText();
int value = std::stoi(oct, nullptr, 8);
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
}
if (ctx->ZERO()) {
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
// 处理变量
if (ctx->lVal()) {
return ctx->lVal()->accept(this);
}
// 处理括号表达式
if (ctx->L_PAREN() && ctx->exp()) {
return EvalExpr(*ctx->exp());
}
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
}
// 左值(变量)处理
// 1. 先通过语义分析结果把变量使用绑定回声明;
// 2. 再通过 storage_map_ 找到该声明对应的栈槽位;
// 3. 最后生成 load把内存中的值读出来。
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
std::string varName = ctx->Ident()->getText();
// 从语义分析获取变量定义
auto* decl = sema_.ResolveVarUse(ctx);
if (!decl) {
throw std::runtime_error(
FormatError("irgen",
"变量使用缺少语义绑定: " + varName));
}
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen",
"变量声明缺少存储槽位: " + varName));
}
return static_cast<ir::Value*>(
builder_.CreateLoad(it->second, module_.GetContext().NextTemp()));
}
// 加法表达式
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
// 注意mulExp() 返回的是 MulExpContext*,不是 vector
// 需要递归处理 AddExp 的左结合性
// AddExp : MulExp | AddExp ('+' | '-') MulExp
// 先处理左操作数
ir::Value* result = nullptr;
// 如果有左子节点AddExp递归处理
if (ctx->addExp()) {
result = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
} else {
// 否则是 MulExp
result = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
}
// 如果有运算符和右操作数
if (ctx->AddOp() || ctx->SubOp()) {
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
if (ctx->AddOp()) {
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
} else if (ctx->SubOp()) {
// 减法a - b = a + (-b)
// 暂时用加法,后续需要实现真正的减法
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
}
}
return static_cast<ir::Value*>(result);
}
// 在 IRGenExp.cpp 中添加
// 简化版 visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 暂时只返回 unaryExp 的值
if (ctx->unaryExp()) {
return ctx->unaryExp()->accept(this);
}
// 如果有 mulExp 子节点,递归处理
if (ctx->mulExp()) {
return ctx->mulExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
}
// 关系表达式(暂未完整实现)
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
// 简化:返回 addExp 的值
if (ctx->addExp()) {
return ctx->addExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现"));
}
// 相等表达式(暂未完整实现)
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
}
// 简化:返回 relExp 的值
if (ctx->relExp()) {
return ctx->relExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
// 条件表达式
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
}
// 简化:返回 lOrExp 的值
if (ctx->lOrExp()) {
return ctx->lOrExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现"));
}

@ -0,0 +1,132 @@
#include "irgen/IRGen.h"
#include <memory>
#include <stdexcept>
#include <vector>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
namespace {
void VerifyFunctionStructure(const ir::Function& func) {
for (const auto& bb : func.GetBlocks()) {
if (!bb || !bb->HasTerminator()) {
throw std::runtime_error(
FormatError("irgen", "基本块未正确终结: " +
(bb ? bb->GetName() : std::string("<null>"))));
}
}
}
} // namespace
IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
: module_(module),
sema_(sema),
func_(nullptr),
builder_(module.GetContext(), nullptr) {}
// 修正:没有 mainFuncDef通过函数名找到 main
std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少编译单元"));
}
// 获取所有函数定义
auto funcDefs = ctx->funcDef();
// 找到 main 函数
SysYParser::FuncDefContext* mainFunc = nullptr;
for (auto* funcDef : funcDefs) {
if (funcDef->Ident() && funcDef->Ident()->getText() == "main") {
mainFunc = funcDef;
break;
}
}
if (!mainFunc) {
throw std::runtime_error(FormatError("irgen", "缺少main函数"));
}
// 生成 main 函数
mainFunc->accept(this);
return {};
}
std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
}
// 使用 Ident() 而不是 ID()
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "缺少函数名"));
}
std::string funcName = ctx->Ident()->getText();
// 检查函数体 - 使用 block() 而不是 blockStmt()
if (!ctx->block()) {
throw std::runtime_error(FormatError("irgen", "函数体为空"));
}
// 检查返回类型 - 使用 Int() 而不是 INT()
if (!ctx->funcType() || !ctx->funcType()->Int()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持int函数"));
}
// 创建函数
func_ = module_.CreateFunction(funcName, ir::Type::GetInt32Type());
builder_.SetInsertPoint(func_->GetEntry());
storage_map_.clear();
// 生成函数体 - 使用 block() 而不是 blockStmt()
ctx->block()->accept(this);
// 确保函数有返回值
if (!func_->GetEntry()->HasTerminator()) {
auto retVal = builder_.CreateConstInt(0);
builder_.CreateRet(retVal);
}
VerifyFunctionStructure(*func_);
return {};
}
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
break;
}
}
}
return {};
}
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
return std::any_cast<BlockFlow>(item.accept(this));
}
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
}
if (ctx->stmt()) {
return ctx->stmt()->accept(this);
}
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的块内项"));
}

@ -0,0 +1,88 @@
#include "irgen/IRGen.h"
#include <stdexcept>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
// 语句生成当前只实现了最小子集。
// 目前支持:
// - return <exp>;
//
// 还未支持:
// - 赋值语句
// - if / while 等控制流
// - 空语句、块语句嵌套分发之外的更多语句形态
std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句"));
}
// return 语句 - 通过 Return() 关键字判断
if (ctx->Return()) {
return HandleReturnStmt(ctx);
}
// 块语句
if (ctx->block()) {
return ctx->block()->accept(this);
}
// 空语句或表达式语句(先计算表达式)
if (ctx->exp()) {
EvalExpr(*ctx->exp());
return BlockFlow::Continue;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
IRGenImpl::BlockFlow IRGenImpl::HandleReturnStmt(SysYParser::StmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
}
ir::Value* retValue = nullptr;
if (ctx->exp()) {
retValue = EvalExpr(*ctx->exp());
}
// 如果没有表达式返回0对于int main
if (!retValue) {
retValue = builder_.CreateConstInt(0);
}
builder_.CreateRet(retValue);
return BlockFlow::Terminated;
}
// if语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleIfStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现if语句
throw std::runtime_error(FormatError("irgen", "if语句暂未实现"));
}
// while语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleWhileStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现while语句
throw std::runtime_error(FormatError("irgen", "while语句暂未实现"));
}
// break语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleBreakStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现break
throw std::runtime_error(FormatError("irgen", "break语句暂未实现"));
}
// continue语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleContinueStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现continue
throw std::runtime_error(FormatError("irgen", "continue语句暂未实现"));
}
// 赋值语句(待实现)
IRGenImpl::BlockFlow IRGenImpl::HandleAssignStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现赋值
throw std::runtime_error(FormatError("irgen", "赋值语句暂未实现"));
}

@ -6,7 +6,7 @@
#include "frontend/SyntaxTreePrinter.h"
#if !COMPILER_PARSE_ONLY
#include "ir/IR.h"
//#include "irgen/IRGen.h"
#include "irgen/IRGen.h"
#include "mir/MIR.h"
#include "sem/Sema.h"
#endif
@ -35,7 +35,7 @@ int main(int argc, char** argv) {
}
auto sema = RunSema(*comp_unit);
/*auto module = GenerateIR(*comp_unit, sema);
auto module = GenerateIR(*comp_unit, sema);
if (opts.emit_ir) {
ir::IRPrinter printer;
if (need_blank_line) {
@ -53,7 +53,7 @@ int main(int argc, char** argv) {
std::cout << "\n";
}
mir::PrintAsm(*machine_func, std::cout);
}*/
}
#else
if (opts.emit_ir || opts.emit_asm) {
throw std::runtime_error(

@ -398,7 +398,122 @@ public:
// 左值表达式(变量引用)
std::any visitLVal(SysYParser::LValContext* ctx) override {
ExprInfo result = CheckLValue(ctx);
std::cout << "[DEBUG] visitLVal: " << ctx->getText() << std::endl;
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("sema", "非法变量引用"));
}
std::string name = ctx->Ident()->getText();
auto* sym = table_.lookup(name);
if (!sym) {
throw std::runtime_error(FormatError("sema", "使用了未定义的变量: " + name));
}
// ========== 关键修复:绑定变量使用到定义 ==========
if (sym) {
std::cerr << "[DEBUG] 找到符号: " << sym->name
<< ", kind: " << (int)sym->kind
<< ", var_def_ctx: " << sym->var_def_ctx << std::endl;
if (sym->var_def_ctx) {
std::cout << "[DEBUG] 绑定变量使用" << std::endl;
sema_.BindVarUse(ctx, sym->var_def_ctx);
}
}
else if (sym->kind == SymbolKind::Parameter) {
// 对于函数参数,需要特殊处理
// 参数可能没有对应的 VarDefContext需要创建一个
// 或者通过其他方式标识
std::cout << "[DEBUG] 参数变量: " << name << " (无法绑定到 VarDefContext)" << std::endl;
// 可以创建一个临时标识,但这里先不处理
}
// ============================================
// 检查数组访问
bool is_array_access = !ctx->exp().empty();
std::cout << "[DEBUG] name: " << name
<< ", is_array_access: " << is_array_access
<< ", subscript_count: " << ctx->exp().size() << std::endl;
ExprInfo result;
// 判断是否为数组类型或指针类型(数组参数)
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()
<< ", is_array: " << sym->type->IsArray()
<< ", is_ptr: " << (sym->type->IsPtrInt32() || sym->type->IsPtrFloat()) << std::endl;
}
if (is_array_or_ptr) {
// 获取维度信息
size_t dim_count = 0;
std::shared_ptr<ir::Type> elem_type = sym->type;
if (sym->type->IsArray()) {
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;
}
} else if (sym->type->IsPtrInt32() || sym->type->IsPtrFloat()) {
dim_count = 1;
if (sym->type->IsPtrInt32()) {
elem_type = ir::Type::GetInt32Type();
} else if (sym->type->IsPtrFloat()) {
elem_type = ir::Type::GetFloatType();
}
std::cout << "[DEBUG] 指针类型, dim_count: 1" << std::endl;
}
if (is_array_access) {
std::cout << "[DEBUG] 有下标访问,期望维度: " << dim_count
<< ", 实际下标数: " << ctx->exp().size() << std::endl;
if (ctx->exp().size() != dim_count) {
throw std::runtime_error(FormatError("sema", "数组下标个数不匹配"));
}
for (auto* idx_exp : ctx->exp()) {
ExprInfo idx = CheckExp(idx_exp);
if (!idx.type->IsInt32()) {
throw std::runtime_error(FormatError("sema", "数组下标必须是 int 类型"));
}
}
result.type = elem_type;
result.is_lvalue = true;
result.is_const = false;
} else {
std::cout << "[DEBUG] 无下标访问" << std::endl;
if (sym->type->IsArray()) {
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();
} else if (arr_type->GetElementType()->IsFloat()) {
result.type = ir::Type::GetPtrFloatType();
} else {
result.type = ir::Type::GetPtrInt32Type();
}
} else {
result.type = ir::Type::GetPtrInt32Type();
}
result.is_lvalue = false;
result.is_const = true;
} else {
result.type = sym->type;
result.is_lvalue = true;
result.is_const = (sym->kind == SymbolKind::Constant);
}
}
} else {
if (is_array_access) {
throw std::runtime_error(FormatError("sema", "非数组变量不能使用下标: " + name));
}
result.type = sym->type;
result.is_lvalue = true;
result.is_const = (sym->kind == SymbolKind::Constant);
if (result.is_const && sym->type && !sym->type->IsArray()) {
if (sym->is_int_const) {
result.is_const_int = true;
result.const_int_value = sym->const_value.i32;
} else {
result.const_float_value = sym->const_value.f32;
}
}
}
sema_.SetExprType(ctx, result);
return {};
}
@ -956,33 +1071,30 @@ private:
if (!sym) {
throw std::runtime_error(FormatError("sema", "未定义的变量: " + name));
}
// ========== 添加绑定 ==========
if (sym->var_def_ctx) {
std::cout << "[DEBUG] CheckLValue 绑定变量: " << name << std::endl;
sema_.BindVarUse(ctx, sym->var_def_ctx);
}
// ============================
bool is_array_access = !ctx->exp().empty();
bool is_const = (sym->kind == SymbolKind::Constant);
bool is_array_or_ptr = false;
if (sym->type) {
is_array_or_ptr = sym->type->IsArray() || sym->type->IsPtrInt32() || sym->type->IsPtrFloat();
}
size_t dim_count = 0;
std::shared_ptr<ir::Type> elem_type = sym->type;
std::vector<int> dims;
// 获取维度信息
if (sym->type && sym->type->IsArray()) {
if (auto* arr_type = dynamic_cast<ir::ArrayType*>(sym->type.get())) {
dims = arr_type->GetDimensions();
dim_count = dims.size();
dim_count = arr_type->GetDimensions().size();
elem_type = arr_type->GetElementType();
}
} else if (sym->is_array_param) {
// 数组参数,使用保存的维度信息
dims = sym->array_dims;
dim_count = dims.size();
// 元素类型是基本类型
if (sym->type->IsPtrInt32()) {
elem_type = ir::Type::GetInt32Type();
} else if (sym->type->IsPtrFloat()) {
elem_type = ir::Type::GetFloatType();
}
} else if (sym->type && (sym->type->IsPtrInt32() || sym->type->IsPtrFloat())) {
// 普通指针,只能有一个下标
dim_count = 1;
if (sym->type->IsPtrInt32()) {
elem_type = ir::Type::GetInt32Type();
@ -1408,4 +1520,4 @@ SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit) {
SemaVisitor visitor;
comp_unit.accept(&visitor);
return visitor.TakeSemanticContext();
}
}

Loading…
Cancel
Save