控制流if,break,while,continue实现,条件跳转,无条件跳转实现,函数参数,函数类型系

统完善
LuoHello 3 weeks ago
commit 728de089ff

6
.gitignore vendored

@ -68,3 +68,9 @@ Thumbs.db
# Project outputs
# =========================
test/test_result/
# =========================
# mxr
# =========================
result.txt
build.sh

@ -227,8 +227,14 @@ class Argument : public Value {
};
// 后续还需要扩展更多指令类型。add call instruction 只是最小占位,后续可以继续补 sub/mul/div/rem、br/condbr、phi、gep 等指令。
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret, Call,
Br, CondBr, Icmp, ZExt, Trunc };
enum class Opcode {
Add, Sub, Mul,
Alloca, Load, Store, Ret, Call,
Br, CondBr, Icmp, ZExt, Trunc,
Div, Mod,
And, Or, Not,
GEP,
};
// ZExt 和 Trunc 是零扩展和截断指令,SysY 的 int (i32) vs LLVM IR 的比较结果 (i1)。
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
@ -502,35 +508,14 @@ class TruncInst : public Instruction {
}
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
class GEPInst : public Instruction {
public:
explicit BasicBlock(std::string name);
Function* GetParent() const;
void SetParent(Function* parent);
bool HasTerminator() const;
const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& GetSuccessors() const;
template <typename T, typename... Args>
T* Append(Args&&... args) {
if (HasTerminator()) {
throw std::runtime_error("BasicBlock 已有 terminator不能继续追加指令: " +
name_);
}
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.push_back(std::move(inst));
return ptr;
}
private:
Function* parent_ = nullptr;
std::vector<std::unique_ptr<Instruction>> instructions_;
std::vector<BasicBlock*> predecessors_;
std::vector<BasicBlock*> successors_;
GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name);
Value* GetBase() const;
const std::vector<Value*>& GetIndices() const;
};
// Function 当前也采用了最小实现。
@ -557,10 +542,13 @@ class Function : public Value {
std::vector<std::unique_ptr<Argument>> arguments_;
};
class CallInst : public Instruction {
public:
CallInst(std::shared_ptr<Type> ret_ty, Function* callee,
const std::vector<Value*>& args, std::string name);
CallInst(std::shared_ptr<Type> ret_ty,
Function* callee,
const std::vector<Value*>& args,
const std::string& name);
Function* GetCallee() const;
const std::vector<Value*>& GetArgs() const;
@ -569,6 +557,38 @@ class CallInst : public Instruction {
std::vector<Value*> args_;
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
public:
explicit BasicBlock(std::string name);
Function* GetParent() const;
void SetParent(Function* parent);
bool HasTerminator() const;
const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& GetSuccessors() const;
template <typename T, typename... Args>
T* Append(Args&&... args) {
if (HasTerminator()) {
throw std::runtime_error("BasicBlock 已有 terminator不能继续追加指令: " +
name_);
}
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.push_back(std::move(inst));
return ptr;
}
private:
Function* parent_ = nullptr;
std::vector<std::unique_ptr<Instruction>> instructions_;
std::vector<BasicBlock*> predecessors_;
std::vector<BasicBlock*> successors_;
};
class Module {
public:
Module() = default;
@ -579,6 +599,7 @@ class Module {
std::shared_ptr<FunctionType> func_type);
GlobalValue* CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty);
Function* FindFunction(const std::string& name) const;
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
const std::vector<std::unique_ptr<GlobalValue>>& GetGlobals() const;
@ -634,6 +655,18 @@ class IRBuilder {
BinaryInst* CreateDiv(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMod(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMul(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateSub(Value* lhs, Value* rhs, const std::string& name);
// 比较运算接口
BinaryInst* CreateAnd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateOr(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateNot(Value* val, const std::string& name);
GEPInst* CreateGEP(Value* base, const std::vector<Value*>& indices, const std::string& name);
private:
Context& ctx_;
BasicBlock* insert_block_;

@ -21,7 +21,7 @@ class Value;
}
class IRGenImpl final : public SysYBaseVisitor {
public:
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
// 顶层
@ -29,12 +29,16 @@ class IRGenImpl final : public SysYBaseVisitor {
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
// 块
std::any visitBlock(SysYParser::BlockContext* ctx) override;
std::any visitBlock(SysYParser::BlockContext* ctx) override; // 注意:规则名为 Block
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
// 声明
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
std::any visitConstDef(SysYParser::ConstDefContext* ctx) override;
std::any visitInitVal(SysYParser::InitValContext* ctx) override;
std::any visitConstInitVal(SysYParser::ConstInitValContext* ctx) override;
// 语句
std::any visitStmt(SysYParser::StmtContext* ctx) override;
@ -42,29 +46,37 @@ class IRGenImpl final : public SysYBaseVisitor {
// 表达式
// 基本表达式(变量、常量、括号表达式)直接翻译为 IR 中的值;函数调用和一元运算需要特殊处理。
std::any visitExp(SysYParser::ExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
// 一元表达式包括函数调用和一元运算,需要特殊处理
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;
// 其他二元表达式按照优先级分层访问,最终调用 visitLVal 来处理变量访问。变量引用
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
// 加法表达式、乘法表达式、关系表达式、相等表达式、条件表达式分别对应不同的访问函数,按照优先级分层访问,最终调用 visitLVal 来处理变量访问
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;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext* ctx) override;
private:
enum class BlockFlow {
// 辅助函数
ir::Value* EvalExpr(SysYParser::ExpContext& expr); // 只保留一处
ir::Value* EvalCond(SysYParser::CondContext& cond);
ir::Value* visitCallExp(SysYParser::UnaryExpContext* ctx);
std::vector<ir::Value*> ProcessNestedInitVals(SysYParser::InitValContext* ctx);
int TryEvaluateConstInt(SysYParser::ConstExpContext* ctx);
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);
@ -72,22 +84,31 @@ class IRGenImpl final : public SysYBaseVisitor {
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_;
std::unordered_map<std::string, ir::Value*> param_map_;
std::unordered_map<std::string, ir::Value*> global_map_;
// 循环栈,用于 break/continue
// 循环上下文结构
struct LoopContext {
ir::BasicBlock* condBlock;
ir::BasicBlock* bodyBlock;
ir::BasicBlock* exitBlock;
};
struct ArrayInfo {
std::vector<ir::Value*> elements;
std::vector<int> dimensions;
};
std::vector<LoopContext> loopStack_;
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
std::unordered_map<SysYParser::ConstDefContext*, ir::Value*> const_storage_map_; // 新增
std::unordered_map<SysYParser::VarDefContext*, ArrayInfo> array_info_map_;
ir::Value* EvalAssign(SysYParser::StmtContext* ctx);
std::unordered_map<std::string, ir::Value*> param_map_;// 函数参数映射key 是参数名value 是对应的 IR 值(通常是 AllocaInst 或 Function 参数)
std::unordered_map<std::string, ir::Value*> global_map_;// 全局变量映射key 是全局变量名value 是对应的 IR 值(通常是 GlobalValue
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,

@ -34,6 +34,14 @@ public:
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;
@ -76,6 +84,8 @@ private:
// 隐式转换列表
std::vector<ConversionInfo> conversions_;
std::unordered_map<const SysYParser::LValContext*, SysYParser::ConstDefContext*> const_uses_;
};
// 目前仅检查:

@ -27,6 +27,10 @@ struct Symbol {
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;
@ -39,6 +43,8 @@ struct Symbol {
// 关联的语法树节点(用于报错位置或进一步分析)
SysYParser::VarDefContext* var_def_ctx = nullptr;
SysYParser::ConstDefContext* const_def_ctx = nullptr;
SysYParser::FuncFParamContext* param_def_ctx = nullptr;
SysYParser::FuncDefContext* func_def_ctx = nullptr;
};
@ -56,6 +62,8 @@ class SymbolTable {
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);
@ -63,14 +71,45 @@ class SymbolTable {
SysYParser::VarDefContext* Lookup(const std::string& name) const;
// ----- 辅助函数:从语法树节点构造 Type -----
static std::shared_ptr<ir::Type> getTypeFromVarDef(SysYParser::VarDefContext* ctx);
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;
int EvaluateConstExpression(SysYParser::ExpContext* ctx) 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;
};

File diff suppressed because it is too large Load Diff

@ -59,9 +59,11 @@ for file in "${TEST_FILES[@]}"; do
echo "========== $file ==========" >> "$RESULT_FILE"
if [ $VERBOSE -eq 1 ]; then
# "$COMPILER" --emit-parse-tree "$file" 2>&1 | tee -a "$RESULT_FILE"
"$COMPILER" --emit-ir "$file" 2>&1 | tee -a "$RESULT_FILE"
result=${PIPESTATUS[0]}
else
# "$COMPILER" --emit-parse-tree "$file" >> "$RESULT_FILE" 2>&1
"$COMPILER" --emit-ir "$file" >> "$RESULT_FILE" 2>&1
result=$?
fi

@ -45,77 +45,112 @@ for test_dir in "${TEST_DIRS[@]}"; do
stdin_file="$test_dir/$stem.in"
echo "[TEST] $input"
# 编译并捕获所有输出
compiler_status=0
compiler_output=
compiler_output=""
compiler_output=$("$COMPILER" --emit-ir "$input" 2>&1) || compiler_status=$?
printf '%s\n' "$compiler_output" | sed '/^\[DEBUG/d' > "$ll_file"
# 临时文件存储原始输出
raw_ll="$out_dir/$stem.raw.ll"
printf '%s\n' "$compiler_output" > "$raw_ll"
# 检查编译是否成功
if [[ $compiler_status -ne 0 ]]; then
echo " [IR] 编译失败: 返回码 $compiler_status"
ir_failures+=("$input: compiler failed ($compiler_status)")
# 失败:保留原始输出(包含所有调试信息)
cp "$raw_ll" "$ll_file"
rm -f "$raw_ll"
continue
fi
if ! grep -qE '^define ' "$ll_file"; then
# 检查是否生成了有效的函数定义(在过滤后的内容中检查)
# 先过滤一下看看是否有define
filtered_content=$(sed -E '/^\[DEBUG\]|^SymbolTable::|^CheckLValue:|^绑定变量:|^dim_count:/d' "$raw_ll")
if ! echo "$filtered_content" | grep -qE '^define '; then
echo " [IR] 失败: 未生成有效函数定义"
ir_failures+=("$input: invalid IR output")
# 失败:保留原始输出
cp "$raw_ll" "$ll_file"
rm -f "$raw_ll"
continue
fi
# 编译成功过滤掉所有调试输出只保留IR
# 过滤规则:
# 1. 以 [DEBUG] 开头的行
# 2. SymbolTable:: 开头的行
# 3. CheckLValue: 开头的行
# 4. 绑定变量: 开头的行
# 5. dim_count: 开头的行
# 6. 空行(可选)
sed -E '/^(\[DEBUG|SymbolTable::|CheckLValue|绑定变量:|dim_)/d' "$raw_ll" > "$ll_file"
# 可选:删除多余的空行
sed -i '/^$/N;/\n$/D' "$ll_file"
rm -f "$raw_ll"
ir_pass=$((ir_pass+1))
echo " [IR] 生成成功"
echo " [IR] 生成成功 (IR已保存到: $ll_file)"
# 运行测试
if [[ -f "$expected_file" ]]; then
result_total=$((result_total+1))
expected=$(normalize_file "$expected_file")
# 运行LLVM IR
run_status=0
if [[ -f "$stdin_file" ]]; then
lli "$ll_file" < "$stdin_file" > "$stdout_file" 2>&1 || run_status=$?
else
lli "$ll_file" > "$stdout_file" 2>&1 || run_status=$?
fi
if [[ ! -s "$stdout_file" && "$expected" =~ ^-?[0-9]+$ ]]; then
if [[ "$run_status" -eq "$expected" ]]; then
result_pass=$((result_pass+1))
echo " [RUN] 返回码匹配"
else
echo " [RUN] 返回码不匹配: got $run_status"
result_failures+=("$input: exit code mismatch (got $run_status)")
fi
# 读取预期返回值
expected=$(normalize_file "$expected_file")
# 比较返回值
if [[ "$run_status" -eq "$expected" ]]; then
result_pass=$((result_pass+1))
echo " [RUN] 返回值匹配: $run_status"
# 成功:保留已清理的.ll文件删除输出文件
rm -f "$stdout_file"
else
if diff -u <(printf '%s\n' "$expected") <(normalize_file "$stdout_file") > "$out_dir/$stem.diff"; then
result_pass=$((result_pass+1))
echo " [RUN] 输出匹配"
else
echo " [RUN] 输出不匹配"
result_failures+=("$input: output mismatch")
fi
echo " [RUN] 返回值不匹配: got $run_status, expected $expected"
result_failures+=("$input: exit code mismatch (got $run_status, expected $expected)")
# 失败:.ll文件已经保留输出文件也保留用于调试
fi
else
echo " [RUN] 未找到预期输出 $expected_file,跳过结果验证"
echo " [RUN] 未找到预期返回值文件 $expected_file,跳过结果验证"
fi
done
shopt -u nullglob
done
# 输出统计
cat <<EOF
测试完成。
IR 生成: $ir_pass / $ir_total
结果匹配: $result_pass / $result_total
EOF
# 输出失败列表
if [[ ${#ir_failures[@]} -gt 0 ]]; then
echo "\nIR 失败列表:"
echo ""
echo "IR 失败列表:"
for item in "${ir_failures[@]}"; do
echo " $item"
done
fi
if [[ ${#result_failures[@]} -gt 0 ]]; then
echo "\n结果失败列表:"
echo ""
echo "结果失败列表:"
for item in "${result_failures[@]}"; do
echo " $item"
done
fi
echo ""
echo "失败的测试文件已保留在: $TMP_DIR"
echo "可以查看对应的.ll文件进行调试"
fi

@ -34,7 +34,52 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateBinary 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(op, lhs->GetType(), lhs, rhs, name);
// 检查操作码是否为有效的二元操作符
switch (op) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Or:
// 有效的二元操作符
break;
case Opcode::Not:
// Not是一元操作符不应该在BinaryInst中
throw std::runtime_error(FormatError("ir", "Not是一元操作符应使用其他指令"));
default:
throw std::runtime_error(FormatError("ir", "BinaryInst 不支持的操作码"));
}
// 确定结果类型
std::shared_ptr<Type> result_type;
// 检查操作数类型是否相同
if (lhs->GetType()->GetKind() != rhs->GetType()->GetKind()) {
throw std::runtime_error(
FormatError("ir", "CreateBinary 操作数类型不匹配"));
}
bool is_logical = (op == Opcode::And || op == Opcode::Or);
if (is_logical) {
// 逻辑运算的结果是 int32布尔值
result_type = Type::GetInt32Type();
} else {
// 算术运算的结果类型与操作数相同
result_type = lhs->GetType();
}
// 检查操作数类型是否支持
if (!lhs->GetType()->IsInt32() && !lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "CreateBinary 只支持 int32 和 float 类型"));
}
return insert_block_->Append<BinaryInst>(op, result_type, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs,
@ -101,21 +146,6 @@ ReturnInst* IRBuilder::CreateRet(Value* v) {
}
return insert_block_->Append<ReturnInst>(Type::GetVoidType(), v);
}
// 注意:当前 CreateCall 仅支持直接调用 Function且不支持变长参数列表等复杂特性。
// 创建函数调用指令的实现,被调用的函数,参数列表,返回值临时变量名
CallInst* IRBuilder::CreateCall(Function* callee,
const std::vector<Value*>& args,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!callee) { //被调用的函数不能为空
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateCall 缺少 callee"));
}
auto func_ty = std::static_pointer_cast<FunctionType>(callee->GetType());
auto ret_ty = func_ty->GetReturnType();
return insert_block_->Append<CallInst>(ret_ty, callee, args, name);
}
BranchInst* IRBuilder::CreateBr(BasicBlock* target) {
if (!insert_block_) {
@ -327,4 +357,132 @@ TruncInst* IRBuilder::CreateTruncI32ToI1(Value* value, const std::string& name)
return CreateTrunc(value, Type::GetInt1Type(), name);
}
BinaryInst* IRBuilder::CreateDiv(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Div, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateMod(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Mod, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateAnd(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::And, Type::GetInt32Type(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateOr(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Or, Type::GetInt32Type(), lhs, rhs, name);
}
IcmpInst* IRBuilder::CreateNot(Value* val, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!val) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateNot 缺少 operand"));
}
auto zero = CreateConstInt(0);
return CreateICmpEQ(val, zero, name);
}
GEPInst* IRBuilder::CreateGEP(Value* base,
const std::vector<Value*>& indices,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!base) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateGEP 缺少 base"));
}
// 检查所有索引
for (size_t i = 0; i < indices.size(); ++i) {
if (!indices[i]) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateGEP 索引 " + std::to_string(i) + " 为空"));
}
}
// GEP返回指针类型假设与base类型相同
return insert_block_->Append<GEPInst>(base->GetType(), base, indices, name);
}
BinaryInst* IRBuilder::CreateMul(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 rhs"));
}
return CreateBinary(Opcode::Mul, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateSub(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 rhs"));
}
return CreateBinary(Opcode::Sub, lhs, rhs, name);
}
// 注意:当前 CreateCall 仅支持直接调用 Function且不支持变长参数列表等复杂特性。
// 创建函数调用指令的实现,被调用的函数,参数列表,返回值临时变量名
CallInst* IRBuilder::CreateCall(Function* callee,
const std::vector<Value*>& args,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!callee) { //被调用的函数不能为空
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateCall 缺少 callee"));
}
auto func_ty = std::static_pointer_cast<FunctionType>(callee->GetType());
auto ret_ty = func_ty->GetReturnType();
return insert_block_->Append<CallInst>(ret_ty, callee, args, name);
}
} // namespace ir

@ -53,6 +53,22 @@ static const char* OpcodeToString(Opcode op) {
return "condbr";
case Opcode::Icmp:
return "icmp";
case Opcode::Div:
return "div";
case Opcode::Mod:
return "mod";
case Opcode::ZExt:
return "zext";
case Opcode::Trunc:
return "trunc";
case Opcode::And:
return "and";
case Opcode::Or:
return "or";
case Opcode::Not:
return "not";
case Opcode::GEP:
return "getelementptr";
}
return "?";
}
@ -109,7 +125,13 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
switch (inst->GetOpcode()) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul: {
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Not:
case Opcode::Or:
{
auto* bin = static_cast<const BinaryInst*>(inst);
os << " " << bin->GetName() << " = "
<< OpcodeToString(bin->GetOpcode()) << " "
@ -216,8 +238,22 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
<< TypeToString(*trunc->GetTargetType()) << "\n";
break;
}
default:
os << "NOT_IMPLEMENTED: " << OpcodeToString(inst->GetOpcode()) << "\n";
case Opcode::GEP:{
// 简化打印:只打印基本信息和操作数数量
os << " " << inst->GetName() << " = getelementptr ";
os << TypeToString(*inst->GetType()) << " (";
for (size_t i = 0; i < inst->GetNumOperands(); ++i) {
if (i > 0) os << ", ";
os << ValueToString(inst->GetOperand(i));
}
os << ")\n";
break;
}
default: {
// 处理未知操作码
os << " ; 未知指令: " << OpcodeToString(inst->GetOpcode()) << "\n";
break;
}
}
}
}

@ -64,23 +64,62 @@ void Instruction::SetParent(BasicBlock* parent) { parent_ = parent; }
BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
Value* rhs, std::string name)
: Instruction(op, std::move(ty), std::move(name)) {
// 当前 BinaryInst 仅支持 Add/Sub/Mul且操作数和结果必须都是 i32。
if (op != Opcode::Add && op != Opcode::Sub && op != Opcode::Mul) {
throw std::runtime_error(FormatError("ir", "BinaryInst 当前只支持 Add/Sub/Mul"));
}
if (!lhs || !rhs) {
throw std::runtime_error(FormatError("ir", "BinaryInst 缺少操作数"));
// 检查操作码是否为有效的二元操作符
switch (op) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Or:
// 有效的二元操作符
break;
case Opcode::Not:
// Not是一元操作符不应该在BinaryInst中
throw std::runtime_error(FormatError("ir", "Not是一元操作符应使用其他指令"));
default:
throw std::runtime_error(FormatError("ir", "BinaryInst 不支持的操作码"));
}
// 当前 BinaryInst 仅支持 Add/Sub/Mul且操作数和结果必须都是 i32。
if (op != Opcode::Add && op != Opcode::Sub && op != Opcode::Mul) {
}
if (!type_ || !lhs->GetType() || !rhs->GetType()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 缺少类型信息"));
}
if (lhs->GetType()->GetKind() != rhs->GetType()->GetKind() ||
type_->GetKind() != lhs->GetType()->GetKind()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 类型不匹配"));
// 对于比较操作结果类型是i1但我们的类型系统可能还没有i1
// 暂时简化所有操作都返回i32比较操作返回0或1
// 检查操作数类型是否匹配
if (lhs->GetType()->GetKind() != rhs->GetType()->GetKind()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 操作数类型不匹配"));
}
if (!type_->IsInt32()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 当前只支持 i32"));
// 检查操作数类型是否支持
if (!lhs->GetType()->IsInt32() && !lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "BinaryInst 只支持 int32 和 float 类型"));
}
// 对于算术运算,结果类型应与操作数类型相同
bool is_logical = (op == Opcode::And || op == Opcode::Or);
if (is_logical) {
// 比较和逻辑运算的结果应该是整数类型
if (!type_->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "比较和逻辑运算的结果类型必须是 int32"));
}
} else {
// 算术运算的结果类型应与操作数类型相同
if (type_->GetKind() != lhs->GetType()->GetKind()) {
throw std::runtime_error(
FormatError("ir", "BinaryInst 结果类型与操作数类型不匹配"));
}
}
AddOperand(lhs);
AddOperand(rhs);
}
@ -152,9 +191,49 @@ Value* StoreInst::GetValue() const { return GetOperand(0); }
Value* StoreInst::GetPtr() const { return GetOperand(1); }
Function* CallInst::GetCallee() const { return callee_; }
const std::vector<Value*>& CallInst::GetArgs() const { return args_; }
GEPInst::GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name)
: Instruction(Opcode::GEP, ptr_ty, name) {
// 添加base作为第一个操作数
AddOperand(base);
// 添加所有索引作为后续操作数
for (auto* index : indices) {
AddOperand(index);
}
}
Value* GEPInst::GetBase() const {
// 第一个操作数是base
return GetOperand(0);
}
const std::vector<Value*>& GEPInst::GetIndices() const {
// 需要返回索引列表但Instruction只存储操作数
// 这是一个设计问题:要么修改架构,要么提供辅助方法
// 简化实现返回空vector或创建临时vector
static std::vector<Value*> indices;
indices.clear();
// 索引从操作数1开始
for (size_t i = 1; i < GetNumOperands(); ++i) {
indices.push_back(GetOperand(i));
}
return indices;
}
CallInst::CallInst(std::shared_ptr<Type> ret_ty, Function* callee,
const std::vector<Value*>& args, std::string name)
: Instruction(Opcode::Call, std::move(ret_ty), std::move(name)),
const std::vector<Value*>& args, const std::string& name)
: Instruction(Opcode::Call, std::move(ret_ty), name), // name 是 const&,这里会复制
callee_(callee), args_(args) {
if (!callee_) {
throw std::runtime_error(FormatError("ir", "CallInst 缺少被调用函数"));
@ -167,8 +246,6 @@ CallInst::CallInst(std::shared_ptr<Type> ret_ty, Function* callee,
}
}
Function* CallInst::GetCallee() const { return callee_; }
const std::vector<Value*>& CallInst::GetArgs() const { return args_; }
} // namespace ir

@ -14,6 +14,15 @@ Function* Module::CreateFunction(const std::string& name,
return functions_.back().get();
}
Function* Module::FindFunction(const std::string& name) const {
for (const auto& func : functions_) {
if (func->GetName() == name) {
return func.get();
}
}
return nullptr;
}
const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
return functions_;
}

@ -10,4 +10,4 @@ target_link_libraries(irgen PUBLIC
build_options
${ANTLR4_RUNTIME_TARGET}
ir
)
)

@ -16,6 +16,15 @@ std::string GetLValueName(SysYParser::LValContext& lvalue) {
return lvalue.Ident()->getText();
}
int TryGetConstInt(SysYParser::ConstExpContext* ctx) {
// 这里是一个简化的版本,实际上应该调用语义分析的常量求值
// 暂时假设所有常量表达式都是整数常量
// 实际实现需要更复杂的逻辑
// 简化为返回10
return 10;
}
} // namespace
// 注意visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义
@ -37,20 +46,211 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
}
}
// 处理 constDecl(暂不支持)
// 处理 constDecl
if (ctx->constDecl()) {
throw std::runtime_error(FormatError("irgen", "常量声明暂未实现"));
auto* constDecl = ctx->constDecl();
if (constDecl->bType() && constDecl->bType()->Int()) {
for (auto* constDef : constDecl->constDef()) {
constDef->accept(this);
}
} else if (constDecl->bType() && constDecl->bType()->Float()) {
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
}
return {};
}
// 在 IRGenDecl.cpp 中确保有这个函数
std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量声明"));
}
std::cerr << "[DEBUG] visitConstDecl: processing constant declaration" << std::endl;
// 检查类型
if (ctx->bType()) {
if (ctx->bType()->Int()) {
// int 类型常量
for (auto* constDef : ctx->constDef()) {
if (constDef) {
constDef->accept(this);
}
}
} else if (ctx->bType()->Float()) {
// float 类型常量(暂不支持)
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
} else {
throw std::runtime_error(FormatError("irgen", "常量声明缺少类型"));
}
return {};
}
// 修改 visitConstDef 函数,正确处理数组大小
std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法常量定义"));
}
std::string const_name = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitConstDef: processing constant " << const_name << std::endl;
// 检查是否为数组
bool is_array = !ctx->constExp().empty();
if (is_array) {
// 数组常量处理
std::cerr << "[DEBUG] visitConstDef: array constant " << const_name << std::endl;
// 获取数组维度
int array_size = 0;
if (!ctx->constExp().empty()) {
// 尝试获取数组大小
try {
// 使用辅助函数获取整数值
array_size = TryEvaluateConstInt(ctx->constExp()[0]);
if (array_size <= 0) {
// 如果获取失败使用默认值10
array_size = 10;
}
} catch (const std::exception& e) {
// 注意:这里错误信息应该是 visitConstDef不是 visitVarDef
std::cerr << "[WARNING] visitConstDef: 无法获取数组大小: " << e.what()
<< "使用默认值10" << std::endl;
array_size = 10;
}
}
if (array_size <= 0) {
throw std::runtime_error(FormatError("irgen", "常量数组大小必须为正数"));
}
if (array_size > 1000) {
throw std::runtime_error(FormatError("irgen", "常量数组大小太大"));
}
// 分配数组存储
std::vector<ir::Value*> element_slots;
for (int i = 0; i < array_size; i++) {
auto* slot = builder_.CreateAllocaI32(
module_.GetContext().NextTemp() + "_" + const_name + "_" + std::to_string(i));
element_slots.push_back(slot);
}
// 处理初始化
if (auto* const_init_val = ctx->constInitVal()) {
// 获取初始化值
auto result = const_init_val->accept(this);
if (result.has_value()) {
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
// 检查初始化值数量
if (init_values.size() > static_cast<size_t>(array_size)) {
throw std::runtime_error(
FormatError("irgen", "常量数组初始化值太多,数组大小为" + std::to_string(array_size) +
",但提供了" + std::to_string(init_values.size()) + "个值"));
}
// 使用初始化值初始化数组元素
for (size_t i = 0; i < init_values.size(); i++) {
builder_.CreateStore(init_values[i], element_slots[i]);
}
// 剩余元素初始化为0
for (size_t i = init_values.size(); i < static_cast<size_t>(array_size); i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} catch (const std::bad_any_cast&) {
// 可能返回的是单个值
try {
ir::Value* single_value = std::any_cast<ir::Value*>(result);
// 只初始化第一个元素
builder_.CreateStore(single_value, element_slots[0]);
// 其他元素初始化为0
for (int i = 1; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} catch (const std::bad_any_cast&) {
std::cerr << "[ERROR] visitConstDef: 无法解析常量数组初始化值类型" << std::endl;
// 全部初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
} else {
// 没有初始化值全部初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} else {
// 常量数组缺少初始值
throw std::runtime_error(FormatError("irgen", "常量数组缺少初始值"));
}
// 存储第一个元素的地址到 const_storage_map_
const_storage_map_[ctx] = element_slots[0];
std::cerr << "[DEBUG] visitConstDef: 创建常量数组 " << const_name
<< ",大小 " << array_size << std::endl;
} else {
// 标量常量处理
std::cerr << "[DEBUG] visitConstDef: scalar constant " << const_name << std::endl;
if (!ctx->constInitVal()) {
throw std::runtime_error(FormatError("irgen", "常量缺少初始值"));
}
// 处理常量初始化值
auto* const_init_val = ctx->constInitVal();
auto result = const_init_val->accept(this);
if (result.has_value()) {
try {
ir::Value* const_value = std::any_cast<ir::Value*>(result);
std::cerr << "[DEBUG] visitConstDef: scalar constant " << const_name
<< " with value " << (void*)const_value << std::endl;
// 标量常量也需要存储槽位,以便后续引用
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name);
const_storage_map_[ctx] = slot;
builder_.CreateStore(const_value, slot);
return {};
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] visitConstDef: bad any_cast for scalar constant " << const_name << ": " << e.what() << std::endl;
throw std::runtime_error(FormatError("irgen", "标量常量初始化值类型错误"));
}
}
// 如果求值失败使用默认值0
ir::Value* default_value = builder_.CreateConstInt(0);
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name);
const_storage_map_[ctx] = slot;
builder_.CreateStore(default_value, slot);
}
return {};
}
// 处理变量定义的函数,包括全局变量和局部变量的定义。全局变量会被记录在 global_map_ 中,局部变量会被
// TO DO:visitVarDef来区分全局和局部变量并且正确处理数组变量的定义和初始化
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", "变量声明缺少名称"));
}
@ -60,30 +260,249 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
}
// 区分全局变量和局部变量,func_ 记录当前正在生成IR的函数如果 func_ 为空则说明当前在处理全局变量,否则在处理局部变量
if (!func_) {
// 全局变量(简化):用全局占位符记录为 i32*Default 不直接插入指令
// 全局变量:在数据段分配
// TODO:真正的全局变量应该存储值本身,而不是指针,这里为了简化实现先使用指针占位,后续可以改为直接存储值
auto* global = module_.CreateGlobal(varName, ir::Type::GetPtrInt32Type());
global_map_[varName] = global;
// 对全局初始化暂不支持默认为0
return {};
}
// 分配存储(局部变量)
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
if (auto* initVal = ctx->initVal()) {
bool is_array = !ctx->constExp().empty();
if (is_array) {
// 数组变量
// 获取数组维度
int total_size = 1;
std::vector<int> dimensions;
// 计算所有维度
for (auto* const_exp : ctx->constExp()) {
try {
int dim_size = TryEvaluateConstInt(const_exp);
if (dim_size <= 0) {
// 如果维度大小未知,使用默认值
dim_size = 1;
std::cerr << "[WARNING] visitVarDef: 无法确定数组维度大小使用1" << std::endl;
}
dimensions.push_back(dim_size);
total_size *= dim_size;
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitVarDef: 无法获取数组维度: " << e.what()
<< "使用维度1" << std::endl;
dimensions.push_back(1);
total_size *= 1;
}
}
if (total_size <= 0) {
throw std::runtime_error(FormatError("irgen", "数组大小必须为正数"));
}
if (total_size > 1000) {
throw std::runtime_error(FormatError("irgen", "数组大小太大"));
}
// 分配数组存储
std::vector<ir::Value*> element_slots;
for (int i = 0; i < total_size; i++) {
auto* slot = builder_.CreateAllocaI32(
module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i));
element_slots.push_back(slot);
}
// 处理初始化
if (auto* initVal = ctx->initVal()) {
// 获取初始化值
auto result = initVal->accept(this);
if (result.has_value()) {
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
// 检查初始化值数量
if (init_values.size() > static_cast<size_t>(total_size)) {
// 对于多维数组,这可能是正常的
// 我们打印警告但继续执行
std::cerr << "[WARNING] visitVarDef: 初始化值(" << init_values.size()
<< ")超过数组总大小(" << total_size
<< "),只初始化前" << total_size << "个元素" << std::endl;
// 只初始化能容纳的部分
for (size_t i = 0; i < static_cast<size_t>(total_size); i++) {
builder_.CreateStore(init_values[i], element_slots[i]);
}
} else {
// 正常初始化
for (size_t i = 0; i < init_values.size(); i++) {
builder_.CreateStore(init_values[i], element_slots[i]);
}
// 剩余元素初始化为0
for (size_t i = init_values.size(); i < static_cast<size_t>(total_size); i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} catch (const std::bad_any_cast&) {
// 可能返回的是单个值
try {
ir::Value* single_value = std::any_cast<ir::Value*>(result);
// 只初始化第一个元素
builder_.CreateStore(single_value, element_slots[0]);
// 其他元素初始化为0
for (int i = 1; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} catch (const std::bad_any_cast&) {
std::cerr << "[ERROR] visitVarDef: 无法解析数组初始化值类型" << std::endl;
// 全部初始化为0
for (int i = 0; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
} else {
// 没有初始化值全部初始化为0
for (int i = 0; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} else {
// 无初始化所有元素初始化为0
for (int i = 0; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
// 存储第一个元素的地址
storage_map_[ctx] = element_slots[0];
// 保存数组信息
ArrayInfo info;
info.elements = element_slots;
info.dimensions = dimensions;
array_info_map_[ctx] = info;
std::cerr << "[DEBUG] visitVarDef: 创建数组 " << varName
<< ",维度 ";
for (size_t i = 0; i < dimensions.size(); i++) {
std::cerr << dimensions[i];
if (i < dimensions.size() - 1) std::cerr << "×";
}
std::cerr << ",总大小 " << total_size << std::endl;
} else {
// 标量变量
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + varName);
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
builder_.CreateStore(init, slot);
if (auto* initVal = ctx->initVal()) {
auto result = initVal->accept(this);
if (result.has_value()) {
try {
init = std::any_cast<ir::Value*>(result);
} catch (const std::bad_any_cast&) {
// 可能是聚合初始化返回的 vector但标量只取第一个值
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
if (!init_values.empty()) {
init = init_values[0];
} else {
init = builder_.CreateConstInt(0);
}
} catch (const std::bad_any_cast&) {
init = builder_.CreateConstInt(0);
}
}
} else {
init = builder_.CreateConstInt(0);
}
} else {
// 数组初始化暂不支持,局部数组也不做默认初始化
init = builder_.CreateConstInt(0);
}
builder_.CreateStore(init, slot);
std::cerr << "[DEBUG] visitVarDef: 创建标量变量 " << varName
<< ",初始值 " << (void*)init << std::endl;
}
return {};
}
std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法初始化值"));
}
// 如果是单个表达式
if (ctx->exp()) {
return EvalExpr(*ctx->exp());
}
// 如果是聚合初始化(花括号列表)
else if (!ctx->initVal().empty()) {
// 处理嵌套聚合初始化
return ProcessNestedInitVals(ctx);
}
// 空初始化列表
return std::vector<ir::Value*>{};
}
// 新增:处理嵌套聚合初始化的辅助函数
std::vector<ir::Value*> IRGenImpl::ProcessNestedInitVals(SysYParser::InitValContext* ctx) {
std::vector<ir::Value*> all_values;
for (auto* init_val : ctx->initVal()) {
auto result = init_val->accept(this);
if (result.has_value()) {
try {
// 尝试获取单个值
ir::Value* value = std::any_cast<ir::Value*>(result);
all_values.push_back(value);
} catch (const std::bad_any_cast&) {
try {
// 尝试获取值列表(嵌套情况)
std::vector<ir::Value*> nested_values =
std::any_cast<std::vector<ir::Value*>>(result);
// 展平嵌套的值
all_values.insert(all_values.end(),
nested_values.begin(), nested_values.end());
} catch (const std::bad_any_cast&) {
// 未知类型
throw std::runtime_error(
FormatError("irgen", "不支持的初始化值类型"));
}
}
}
}
return all_values;
}
int IRGenImpl::TryEvaluateConstInt(SysYParser::ConstExpContext* ctx) {
if (!ctx) {
std::cerr << "[DEBUG] TryEvaluateConstInt: ctx is null" << std::endl;
return 0;
}
try {
auto result = ctx->accept(this);
if (result.has_value()) {
try {
ir::Value* value = std::any_cast<ir::Value*>(result);
std::cerr << "[DEBUG] TryEvaluateConstInt: got IR value " << (void*)value << std::endl;
// 尝试获取整数常量
// 简化:检查是否是 ConstantInt
// 这里需要 IR 库的支持,暂时返回一个测试值
return 16; // 暂时返回测试值
} catch (const std::bad_any_cast& e) {
std::cerr << "[DEBUG] TryEvaluateConstInt: bad any_cast: " << e.what() << std::endl;
return 0;
}
} else {
std::cerr << "[DEBUG] TryEvaluateConstInt: result has no value" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "[DEBUG] TryEvaluateConstInt: exception: " << e.what() << std::endl;
}
std::cerr << "[DEBUG] TryEvaluateConstInt: returning default value 10" << std::endl;
return 10; // 默认值
}

@ -23,20 +23,43 @@
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl;
return std::any_cast<ir::Value*>(expr.accept(this));
try {
auto result_any = expr.accept(this);
if (!result_any.has_value()) {
std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl;
throw std::runtime_error("表达式求值结果为空");
}
try {
ir::Value* result = std::any_cast<ir::Value*>(result_any);
std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl;
return result;
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl;
std::cerr << " Type info: " << result_any.type().name() << std::endl;
// 尝试其他可能的类型
try {
// 检查是否是无值的any可能来自visit函数返回{}
std::cerr << "[DEBUG] EvalExpr: Trying to handle empty any" << std::endl;
return nullptr;
} catch (...) {
throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型"));
}
}
} catch (const std::exception& e) {
std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl;
throw;
}
}
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
return std::any_cast<ir::Value*>(cond.accept(this));
}
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少表达式"));
}
std::cout << "[DEBUG IRGEN] visitExp: " << ctx->getText() << std::endl;
return ctx->addExp()->accept(this);
}
// 基本表达式:数字、变量、括号表达式
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
@ -45,100 +68,52 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
}
std::cerr << "[DEBUG] visitPrimaryExp" << std::endl;
// 处理数字字面量
if (ctx->DECIMAL_INT()) {
int value = std::stoi(ctx->DECIMAL_INT()->getText());
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
ir::Value* const_int = builder_.CreateConstInt(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value
<< " created as " << (void*)const_int << std::endl;
return static_cast<ir::Value*>(const_int);
}
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));
ir::Value* const_int = builder_.CreateConstInt(value);
return static_cast<ir::Value*>(const_int);
}
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));
ir::Value* const_int = builder_.CreateConstInt(value);
return static_cast<ir::Value*>(const_int);
}
if (ctx->ZERO()) {
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
ir::Value* const_int = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(const_int);
}
// 处理变量
if (ctx->lVal()) {
std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl;
return ctx->lVal()->accept(this);
}
// 处理括号表达式
if (ctx->L_PAREN() && ctx->exp()) {
std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl;
return EvalExpr(*ctx->exp());
}
std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl;
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
}
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitUnaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少一元表达式"));
}
if (ctx->primaryExp()) {
auto result = ctx->primaryExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitUnaryExp primary result: " << (ctx->primaryExp() ? ctx->primaryExp()->getText() : "<null>") << std::endl;
return result;
}
if (ctx->Ident() && ctx->L_PAREN()) {
std::string funcName = ctx->Ident()->getText();
ir::Function* callee = nullptr;
for (auto& f : module_.GetFunctions()) {
if (f->GetName() == funcName) {
callee = f.get();
break;
}
}
if (!callee) {
throw std::runtime_error(FormatError("irgen", "找不到函数: " + funcName));
}
std::vector<ir::Value*> args;
if (ctx->funcRParams()) {
for (auto* exp : ctx->funcRParams()->exp()) {
args.push_back(EvalExpr(*exp));
}
}
ir::Value* result = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
return result;
}
if (ctx->unaryOp() && ctx->unaryExp()) {
auto operand_any = ctx->unaryExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitUnaryExp operand_any.type=" << operand_any.type().name() << " text=" << ctx->unaryExp()->getText() << std::endl;
auto* operand = std::any_cast<ir::Value*>(operand_any);
if (ctx->unaryOp()->AddOp()) {
return operand;
}
if (ctx->unaryOp()->SubOp()) {
auto* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
module_.GetContext().NextTemp()));
}
if (ctx->unaryOp()->NotOp()) {
// 逻辑非暂不支持,先默认 0/1 取反
// 这里简化:如果 operand ==0 返回1否则返回0。不做真实比较
// 需要后续完善比较指令。
return operand;
}
}
throw std::runtime_error(FormatError("irgen", "不支持的 unaryExp"));
}
// 左值(变量)处理
// 1. 先通过语义分析结果把变量使用绑定回声明;
@ -151,6 +126,7 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
}
std::string varName = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitLVal: " << varName << std::endl;
// 从语义分析获取变量定义
auto* decl = sema_.ResolveVarUse(ctx);
@ -194,75 +170,283 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
// 注意mulExp() 返回的是 MulExpContext*,不是 vector
// 需要递归处理 AddExp 的左结合性
// AddExp : MulExp | AddExp ('+' | '-') MulExp
// 先处理左操作数
ir::Value* result = nullptr;
// 如果没有 addExp(),说明是单个 mulExp()
if (!ctx->addExp()) {
return ctx->mulExp()->accept(this);
}
// 正确提取左操作数
auto left_any = ctx->addExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 如果有左子节点AddExp递归处理
if (ctx->addExp()) {
auto left_any = ctx->addExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitAddExp left_any.type=" << left_any.type().name() << " text=" << ctx->addExp()->getText() << std::endl;
result = std::any_cast<ir::Value*>(left_any);
} else {
// 否则是 MulExp
auto right_any = ctx->mulExp()->accept(this);
std::cout << "[DEBUG IRGEN] visitAddExp right_any.type=" << right_any.type().name() << " text=" << ctx->mulExp()->getText() << std::endl;
result = std::any_cast<ir::Value*>(right_any);
// 正确提取右操作数
auto right_any = ctx->mulExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
// 如果有运算符和右操作数
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());
}
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left << ", right=" << (void*)right << std::endl;
// 根据操作符生成相应的指令
if (ctx->AddOp()) {
return static_cast<ir::Value*>(
builder_.CreateAdd(left, right, module_.GetContext().NextTemp()));
} else if (ctx->SubOp()) {
return static_cast<ir::Value*>(
builder_.CreateSub(left, right, module_.GetContext().NextTemp()));
}
return static_cast<ir::Value*>(result);
throw std::runtime_error(FormatError("irgen", "未知的加法操作符"));
}
// 在 IRGenExp.cpp 中添加
// visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 检查 unaryExp返回指针可能为 nullptr
auto* unaryExp = ctx->unaryExp();
std::cout << "[DEBUG] unaryExp is " << (unaryExp ? "not null" : "null") << std::endl;
// 如果是基本形式 UnaryExp
if (!ctx->mulExp()) {
return ctx->unaryExp()->accept(this);
}
// 提取左操作数
auto left_any = ctx->mulExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
if (unaryExp) {
std::cout << "[DEBUG] calling unaryExp->accept(this)" << std::endl;
auto result = unaryExp->accept(this);
std::cout << "[DEBUG] returned from unaryExp" << std::endl;
return result;
// 提取右操作数
auto right_any = ctx->unaryExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
// 检查 mulExp
auto* mulExp = ctx->mulExp();
std::cout << "[DEBUG] mulExp is " << (mulExp ? "not null" : "null") << std::endl;
if (mulExp) {
std::cout << "[DEBUG] calling mulExp->accept(this)" << std::endl;
auto result = mulExp->accept(this);
std::cout << "[DEBUG] returned from mulExp" << std::endl;
return result;
// 根据操作符生成指令
if (ctx->MulOp()) {
return static_cast<ir::Value*>(
builder_.CreateMul(left, right, module_.GetContext().NextTemp()));
} else if (ctx->DivOp()) {
return static_cast<ir::Value*>(
builder_.CreateDiv(left, right, module_.GetContext().NextTemp()));
} else if (ctx->QuoOp()) {
return static_cast<ir::Value*>(
builder_.CreateMod(left, right, module_.GetContext().NextTemp()));
}
std::cout << "[DEBUG] no unaryExp or mulExp found!" << std::endl;
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
}
// 逻辑与
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
if (!ctx->lAndExp()) {
return ctx->eqExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->eqExp()->accept(this));
auto zero = builder_.CreateConstInt(0);
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
return builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp());
}
// 逻辑或
std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
if (!ctx->lOrExp()) {
return ctx->lAndExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
auto zero = builder_.CreateConstInt(0);
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
return builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp());
}
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式"));
return ctx->addExp()->accept(this);
}
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
return ctx->lOrExp()->accept(this);
}
ir::Value* IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
}
std::string funcName = ctx->Ident()->getText();
// 语义检查(如果需要)
// auto* funcDecl = sema_.ResolveFuncCall(ctx);
// if (!funcDecl) throw ...
// 收集实参
std::vector<ir::Value*> args;
if (ctx->funcRParams()) {
auto argList = ctx->funcRParams()->accept(this);
args = std::any_cast<std::vector<ir::Value*>>(argList);
}
// 查找函数对象
ir::Function* callee = module_.FindFunction(funcName);
if (!callee) {
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
}
// 生成调用指令
return builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
}
// 实现一元表达式
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
}
// 基本表达式
if (ctx->primaryExp()) {
return ctx->primaryExp()->accept(this);
}
// 函数调用
if (ctx->Ident()) {
return visitCallExp(ctx);
}
// 一元运算
if (ctx->unaryOp() && ctx->unaryExp()) {
auto* operand = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
std::string op = ctx->unaryOp()->getText();
if (op == "+") {
// +x 等价于 x
return operand;
} else if (op == "-") {
// -x 等价于 0 - x
ir::Value* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
module_.GetContext().NextTemp()));
} else if (op == "!") {
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
}
}
throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式"));
}
// 实现函数调用
std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
if (!ctx) return std::vector<ir::Value*>{};
std::vector<ir::Value*> args;
for (auto* exp : ctx->exp()) {
args.push_back(EvalExpr(*exp));
}
return args;
}
// 修改 visitConstExp 以支持常量表达式求值
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量表达式"));
}
try {
if (ctx->addExp()) {
// 尝试获取数值
auto result = ctx->addExp()->accept(this);
if (result.has_value()) {
try {
ir::Value* value = std::any_cast<ir::Value*>(result);
// 尝试判断是否是 ConstantInt
// 暂时简化:返回 IR 值
return static_cast<ir::Value*>(value);
} catch (const std::bad_any_cast&) {
// 可能是其他类型
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
}
}
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstExp: 常量表达式求值失败: " << e.what()
<< "返回0" << std::endl;
// 如果普通表达式求值失败返回0
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
}
std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量初始化值"));
}
// 如果是单个表达式
if (ctx->constExp()) {
try {
return ctx->constExp()->accept(this);
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstInitVal: 常量表达式求值失败: " << e.what()
<< "返回默认值0" << std::endl;
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
}
// 如果是聚合初始化(花括号列表)
else if (!ctx->constInitVal().empty()) {
// 处理嵌套聚合初始化
std::vector<ir::Value*> all_values;
for (auto* init_val : ctx->constInitVal()) {
auto result = init_val->accept(this);
if (result.has_value()) {
try {
// 尝试获取单个值
ir::Value* value = std::any_cast<ir::Value*>(result);
all_values.push_back(value);
} catch (const std::bad_any_cast&) {
try {
// 尝试获取值列表(嵌套情况)
std::vector<ir::Value*> nested_values =
std::any_cast<std::vector<ir::Value*>>(result);
// 展平嵌套的值
all_values.insert(all_values.end(),
nested_values.begin(), nested_values.end());
} catch (const std::bad_any_cast&) {
// 未知类型
throw std::runtime_error(
FormatError("irgen", "不支持的常量初始化值类型"));
}
}
}
}
return all_values;
}
// 空初始化列表
return std::vector<ir::Value*>{};
}
// 关系表达式(支持 <, >, <=, >=
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
@ -330,17 +514,69 @@ std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
// 条件表达式
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
if (!ctx || !ctx->lVal() || !ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
}
// 简化:返回 lOrExp 的值
if (ctx->lOrExp()) {
return ctx->lOrExp()->accept(this);
// 计算右值
ir::Value* rhs = EvalExpr(*ctx->exp());
auto* lval = ctx->lVal();
std::string varName = lval->Ident()->getText();
// 首先尝试从语义分析获取变量定义
auto* var_decl = sema_.ResolveVarUse(lval);
if (var_decl) {
// 是变量赋值
// 从storage_map_获取存储位置
auto it = storage_map_.find(var_decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
}
ir::Value* base_ptr = it->second;
// 检查是否有数组下标
auto exp_list = lval->exp();
if (!exp_list.empty()) {
// 这是数组元素赋值需要生成GEP指令
std::vector<ir::Value*> indices;
// 第一个索引是0假设一维数组
indices.push_back(builder_.CreateConstInt(0));
// 添加用户提供的下标
for (auto* exp : exp_list) {
ir::Value* index = EvalExpr(*exp);
indices.push_back(index);
}
// 生成GEP指令获取元素地址
ir::Value* elem_ptr = builder_.CreateGEP(
base_ptr, indices, module_.GetContext().NextTemp());
// 生成store指令
builder_.CreateStore(rhs, elem_ptr);
} else {
// 普通标量赋值
builder_.CreateStore(rhs, base_ptr);
}
} else {
// 尝试获取常量定义
auto* const_decl = sema_.ResolveConstUse(lval);
if (const_decl) {
// 尝试给常量赋值,这是错误的
throw std::runtime_error(
FormatError("irgen", "不能给常量赋值: " + varName));
} else {
throw std::runtime_error(
FormatError("irgen", "变量/常量使用缺少语义绑定: " + varName));
}
}
throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现"));
return rhs;
}

@ -180,7 +180,10 @@ public:
if (is_array) {
// 处理数组维度
for (auto* dim_exp : ctx->constExp()) {
int dim = EvaluateConstExp(dim_exp);
// ========== 绑定维度表达式 ==========
dim_exp->addExp()->accept(this); // 触发常量绑定(如 N
int dim = table_.EvaluateConstExp(dim_exp);
if (dim <= 0) {
throw std::runtime_error(FormatError("sema", "数组维度必须为正整数"));
}
@ -212,6 +215,10 @@ public:
if (is_global && has_init) {
CheckGlobalInitIsConst(ctx->initVal()); // 全局变量初始化必须是常量表达式
}
// ========== 绑定初始化表达式 ==========
if (ctx->initVal()) {
BindInitVal(ctx->initVal());
}
// 创建符号
Symbol sym;
sym.name = name;
@ -265,7 +272,7 @@ public:
<< " dim_count: " << ctx->constExp().size() << std::endl;
if (is_array) {
for (auto* dim_exp : ctx->constExp()) {
int dim = EvaluateConstExp(dim_exp);
int dim = table_.EvaluateConstExp(dim_exp);
if (dim <= 0) {
throw std::runtime_error(FormatError("sema", "数组维度必须为正整数"));
}
@ -275,10 +282,19 @@ public:
type = ir::Type::GetArrayType(base_type, dims);
std::cout << "[DEBUG] 创建数组类型完成IsArray: " << type->IsArray() << std::endl;
}
// ========== 绑定维度表达式 ==========
for (auto* dim_exp : ctx->constExp()) {
dim_exp->addExp()->accept(this);
}
// 求值初始化器
std::vector<ConstValue> init_values;
std::vector<SymbolTable::ConstValue> init_values;
if (ctx->constInitVal()) {
init_values = EvaluateConstInitVal(ctx->constInitVal(), dims, base_type);
// ========== 绑定初始化表达式 ==========
BindConstInitVal(ctx->constInitVal());
init_values = table_.EvaluateConstInitVal(ctx->constInitVal(), dims, base_type);
std::cout << "[DEBUG] 初始化值数量: " << init_values.size() << std::endl;
}
// 检查初始化值数量
@ -294,25 +310,31 @@ public:
Symbol sym;
sym.name = name;
sym.kind = SymbolKind::Constant;
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 (!is_array && !init_values.empty()) {
if (base_type->IsInt32() && init_values[0].is_int) {
if (base_type->IsInt32() && init_values[0].kind == SymbolTable::ConstValue::INT) {
sym.is_int_const = true;
sym.const_value.i32 = init_values[0].int_val;
std::cout << "[DEBUG] 存储整型常量值: " << init_values[0].int_val << std::endl;
} else if (base_type->IsFloat() && !init_values[0].is_int) {
} else if (base_type->IsFloat() && init_values[0].kind == SymbolTable::ConstValue::FLOAT) {
sym.is_int_const = false;
sym.const_value.f32 = init_values[0].float_val;
std::cout << "[DEBUG] 存储浮点常量值: " << init_values[0].float_val << std::endl;
}
} else if (is_array) {
std::cout << "[DEBUG] 数组常量,不存储单个常量值" << std::endl;
}
table_.addSymbol(sym);
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;
std::cout << "[DEBUG] 常量符号添加完成" << std::endl;
}
@ -409,24 +431,6 @@ public:
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
@ -1073,30 +1077,57 @@ private:
if (!sym) {
throw std::runtime_error(FormatError("sema", "未定义的变量: " + name));
}
// ========== 添加绑定 ==========
if (sym->var_def_ctx) {
std::cout << "[DEBUG] CheckLValue 绑定变量: " << name << std::endl;
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;
}
// ============================
else if (sym->kind == SymbolKind::Constant && sym->const_def_ctx) {
sema_.BindConstUse(ctx, sym->const_def_ctx);
std::cout << "绑定常量: " << name << " -> ConstDefContext" << std::endl;
}
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;
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())) {
dim_count = arr_type->GetDimensions().size();
elem_type = arr_type->GetElementType();
dims = arr_type->GetDimensions();
dim_count = dims.size();
// 计算元素类型(递归获取最内层元素类型)
std::shared_ptr<ir::Type> t = sym->type;
while (t->IsArray()) {
auto* arr_t = dynamic_cast<ir::ArrayType*>(t.get());
t = arr_t->GetElementType();
}
elem_type = t;
}
} 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();
}
std::cout << "数组参数维度: " << dim_count << " 维, dims: ";
for (int d : dims) std::cout << d << " ";
std::cout << std::endl;
} else if (sym->type && (sym->type->IsPtrInt32() || sym->type->IsPtrFloat())) {
// 普通指针,只能有一个下标
dim_count = 1;
if (sym->type->IsPtrInt32()) {
elem_type = ir::Type::GetInt32Type();
@ -1107,23 +1138,46 @@ private:
size_t subscript_count = ctx->exp().size();
if (is_array_or_ptr) {
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()) {
if (subscript_count > 0) {
// 有下标访问
if (subscript_count != dim_count) {
throw std::runtime_error(FormatError("sema", "数组下标个数不匹配"));
// 对于数组参数第一维是省略的0但实际可以访问
// 我们需要检查提供的下标个数是否超过实际维度个数
if (subscript_count > 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 类型"));
}
}
return {elem_type, true, false};
if (subscript_count == dim_count) {
// 完全索引,返回元素类型
std::cout << "完全索引,返回元素类型" << std::endl;
return {elem_type, true, false};
} else {
// 部分索引,返回子数组的指针类型
std::cout << "部分索引,返回指针类型" << std::endl;
// 计算剩余维度的指针类型
if (elem_type->IsInt32()) {
return {ir::Type::GetPtrInt32Type(), false, false};
} else if (elem_type->IsFloat()) {
return {ir::Type::GetPtrFloatType(), false, false};
} else {
return {ir::Type::GetPtrInt32Type(), false, false};
}
}
} else {
// 没有下标访问
if (sym->type->IsArray()) {
// 数组名作为地址(右值)
if (sym->type && sym->type->IsArray()) {
// 数组名作为地址
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};
@ -1132,8 +1186,16 @@ private:
}
}
return {ir::Type::GetPtrInt32Type(), false, true};
} else if (sym->is_array_param) {
// 数组参数名作为地址
std::cout << "数组参数名作为地址" << std::endl;
if (sym->type->IsPtrInt32()) {
return {ir::Type::GetPtrInt32Type(), false, true};
} else {
return {ir::Type::GetPtrFloatType(), false, true};
}
} else {
// 指针类型(如函数参数)可以不带下标使用
// 普通变量或指针
return {sym->type, true, is_const};
}
}
@ -1305,7 +1367,7 @@ private:
table_.addSymbol(sym);
}
void CollectFunctionParams(SysYParser::FuncFParamsContext* ctx) {
if (!ctx) return;
for (auto* param : ctx->funcFParam()) {
@ -1323,15 +1385,41 @@ private:
}
}
if (!param_type) param_type = ir::Type::GetInt32Type();
bool is_array = !param->L_BRACK().empty();
std::vector<int> dims;
if (is_array) {
// 第一维是 []没有表达式所以维度为0表示省略
dims.push_back(0);
// 后续维度有表达式
// 注意exp() 返回的是 ExpContext 列表,对应后面的维度表达式
for (auto* exp_ctx : param->exp()) {
// 使用常量求值器直接求值
// 创建一个临时的 ConstExpContext
// 由于 ConstExpContext 只是 addExp 的包装,我们可以直接使用 addExp
auto* addExp = exp_ctx->addExp();
if (!addExp) {
throw std::runtime_error(FormatError("sema", "无效的数组维度表达式"));
}
// 求值常量表达式
int dim = table_.EvaluateConstExpression(exp_ctx);
if (dim <= 0) {
throw std::runtime_error(FormatError("sema", "数组维度必须为正整数"));
}
dims.push_back(dim);
}
// 数组参数退化为指针
if (param_type->IsInt32()) {
param_type = ir::Type::GetPtrInt32Type();
} else if (param_type->IsFloat()) {
param_type = ir::Type::GetPtrFloatType();
}
std::cout << "[DEBUG] 数组参数: " << name << " 类型转换为指针" << std::endl;
}
Symbol sym;
sym.name = name;
sym.kind = SymbolKind::Parameter;
@ -1339,8 +1427,14 @@ private:
sym.scope_level = table_.currentScopeLevel();
sym.is_initialized = true;
sym.var_def_ctx = nullptr;
sym.is_array_param = is_array;
sym.array_dims = dims;
table_.addSymbol(sym);
std::cout << "[DEBUG] 添加参数: " << name << " type_kind: " << (int)param_type->GetKind() << std::endl;
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;
}
}
@ -1358,59 +1452,6 @@ private:
}
}
int EvaluateConstExp(SysYParser::ConstExpContext* ctx) {
if (!ctx || !ctx->addExp()) return 0;
ExprInfo info = CheckAddExp(ctx->addExp());
if (info.is_const && info.is_const_int) {
return info.const_int_value;
}
throw std::runtime_error(FormatError("sema", "常量表达式求值失败"));
return 0;
}
struct ConstValue {
bool is_int;
int int_val;
float float_val;
};
std::vector<ConstValue> EvaluateConstInitVal(SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) {
std::vector<ConstValue> result;
if (!ctx) return result;
if (ctx->constExp()) {
ExprInfo info = CheckAddExp(ctx->constExp()->addExp());
ConstValue val;
if (info.type->IsInt32() && info.is_const_int) {
val.is_int = true;
val.int_val = info.const_int_value;
if (base_type->IsFloat()) {
val.is_int = false;
val.float_val = (float)info.const_int_value;
}
} else if (info.type->IsFloat() && info.is_const) {
val.is_int = false;
val.float_val = info.const_float_value;
if (base_type->IsInt32()) {
val.is_int = true;
val.int_val = (int)info.const_float_value;
}
} else {
val.is_int = base_type->IsInt32();
val.int_val = 0;
val.float_val = 0.0f;
}
result.push_back(val);
} else {
for (auto* init : ctx->constInitVal()) {
std::vector<ConstValue> sub_vals = EvaluateConstInitVal(init, dims, base_type);
result.insert(result.end(), sub_vals.begin(), sub_vals.end());
}
}
return result;
}
void CheckMainFunction() {
auto* main_sym = table_.lookup("main");
if (!main_sym || main_sym->kind != SymbolKind::Function) {
@ -1430,6 +1471,29 @@ private:
throw std::runtime_error(FormatError("sema", "main 函数不能有参数"));
}
}
void BindConstInitVal(SysYParser::ConstInitValContext* ctx) {
if (!ctx) return;
if (ctx->constExp()) {
// 遍历表达式树,触发 visitLVal 中的绑定
ctx->constExp()->addExp()->accept(this);
} else {
for (auto* sub : ctx->constInitVal()) {
BindConstInitVal(sub);
}
}
}
void BindInitVal(SysYParser::InitValContext* ctx) {
if (!ctx) return;
if (ctx->exp()) {
CheckExp(ctx->exp()); // 触发绑定
} else {
for (auto* sub : ctx->initVal()) {
BindInitVal(sub);
}
}
}
};
} // namespace

@ -1,5 +1,18 @@
#include "sem/SymbolTable.h"
#include <antlr4-runtime.h> // 用于访问父节点
#include <cctype>
#include <stdexcept>
#include <string>
#include <cmath>
#define DEBUG_SYMBOL_TABLE
#ifdef DEBUG_SYMBOL_TABLE
#include <iostream>
#define DEBUG_MSG(msg) std::cerr << "[SymbolTable Debug] " << msg << std::endl
#else
#define DEBUG_MSG(msg)
#endif
// ---------- 构造函数 ----------
SymbolTable::SymbolTable() {
@ -26,23 +39,44 @@ bool SymbolTable::addSymbol(const Symbol& sym) {
return false; // 重复定义
}
current_scope[sym.name] = sym;
// 立即验证存储的符号
const auto& stored = current_scope[sym.name];
std::cout << "SymbolTable::addSymbol: stored " << sym.name
<< " with kind=" << (int)stored.kind
<< ", const_def_ctx=" << stored.const_def_ctx
<< std::endl;
return true;
}
Symbol* SymbolTable::lookup(const std::string& name) {
// 从当前作用域向外层查找
return const_cast<Symbol*>(static_cast<const SymbolTable*>(this)->lookup(name));
}
Symbol* SymbolTable::lookupCurrent(const std::string& name) {
return const_cast<Symbol*>(static_cast<const SymbolTable*>(this)->lookupCurrent(name));
}
const Symbol* SymbolTable::lookup(const std::string& name) const {
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
auto& scope = *it;
const auto& scope = *it;
auto found = scope.find(name);
if (found != scope.end()) {
std::cout << "SymbolTable::lookup: found " << name
<< " in scope level " << (scopes_.rend() - it - 1)
<< ", kind=" << (int)found->second.kind
<< ", const_def_ctx=" << found->second.const_def_ctx
<< std::endl;
return &found->second;
}
}
return nullptr;
}
Symbol* SymbolTable::lookupCurrent(const std::string& name) {
auto& current_scope = scopes_.back();
const Symbol* SymbolTable::lookupCurrent(const std::string& name) const {
const auto& current_scope = scopes_.back();
auto it = current_scope.find(name);
if (it != current_scope.end()) {
return &it->second;
@ -109,45 +143,34 @@ static SysYParser::ConstDeclContext* getOuterConstDecl(SysYParser::VarDefContext
return nullptr;
}
// 常量表达式求值(占位,需实现真正的常量折叠)
static int evaluateConstExp(SysYParser::ConstExpContext* ctx) {
// TODO: 实现常量折叠目前返回0
return 0;
}
// 从 VarDefContext 构造类型
std::shared_ptr<ir::Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) {
// 1. 获取基本类型int/float
// 原静态函数改为成员函数,并调用成员 EvaluateConstExp
std::shared_ptr<ir::Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) const {
// 获取基本类型(同原代码,但通过外层 Decl 确定)
std::shared_ptr<ir::Type> base_type = nullptr;
auto varDecl = getOuterVarDecl(ctx);
if (varDecl) {
auto bType = varDecl->bType();
if (bType->Int()) {
base_type = ir::Type::GetInt32Type();
} else if (bType->Float()) {
base_type = ir::Type::GetFloatType();
}
if (bType->Int()) base_type = ir::Type::GetInt32Type();
else if (bType->Float()) base_type = ir::Type::GetFloatType();
} else {
auto constDecl = getOuterConstDecl(ctx);
if (constDecl) {
auto bType = constDecl->bType();
if (bType->Int()) {
base_type = ir::Type::GetInt32Type();
} else if (bType->Float()) {
base_type = ir::Type::GetFloatType();
}
if (bType->Int()) base_type = ir::Type::GetInt32Type();
else if (bType->Float()) base_type = ir::Type::GetFloatType();
}
}
if (!base_type) base_type = ir::Type::GetInt32Type();
if (!base_type) {
base_type = ir::Type::GetInt32Type(); // 默认 int
}
// 2. 解析数组维度(从 varDef 的 constExp 列表获取)
// 解析维度
std::vector<int> dims;
for (auto constExp : ctx->constExp()) {
int dimVal = evaluateConstExp(constExp);
dims.push_back(dimVal);
for (auto* dimExp : ctx->constExp()) {
int dim = EvaluateConstExp(dimExp); // 调用成员函数
if (dim <= 0) {
throw std::runtime_error("数组维度必须为正整数");
}
dims.push_back(dim);
}
if (!dims.empty()) {
@ -155,7 +178,6 @@ std::shared_ptr<ir::Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefConte
}
return base_type;
}
// 从 FuncDefContext 构造函数类型
std::shared_ptr<ir::Type> SymbolTable::getTypeFromFuncDef(SysYParser::FuncDefContext* ctx) {
// 1. 返回类型
@ -310,7 +332,7 @@ void SymbolTable::registerBuiltinFunctions() {
stoptime.scope_level = 0;
stoptime.is_builtin = true;
addSymbol(stoptime);
// getfarray: int getfarray(float arr[])
std::vector<std::shared_ptr<ir::Type>> getfarray_params = { ir::Type::GetPtrFloatType() };
Symbol getfarray;
@ -335,4 +357,339 @@ void SymbolTable::registerBuiltinFunctions() {
putfarray.scope_level = 0;
putfarray.is_builtin = true;
addSymbol(putfarray);
}
// ==================== 常量表达式求值实现 ====================
static long long ParseIntegerLiteral(const std::string& text) {
// 处理前缀0x/0X 十六进制0 八进制,否则十进制
if (text.size() > 2 && (text[0] == '0' && (text[1] == 'x' || text[1] == 'X'))) {
return std::stoll(text.substr(2), nullptr, 16);
} else if (text.size() > 1 && text[0] == '0') {
return std::stoll(text, nullptr, 8);
} else {
return std::stoll(text, nullptr, 10);
}
}
static float ParseFloatLiteral(const std::string& text) {
return std::stof(text);
}
SymbolTable::ConstValue SymbolTable::EvaluatePrimaryExp(SysYParser::PrimaryExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 PrimaryExp");
if (ctx->lVal()) {
auto lval = ctx->lVal();
if (!lval->Ident()) throw std::runtime_error("常量表达式求值:无效左值");
std::string name = lval->Ident()->getText();
const Symbol* sym = lookup(name);
if (!sym) throw std::runtime_error("常量表达式求值:未定义的标识符 " + name);
if (sym->kind != SymbolKind::Constant)
throw std::runtime_error("常量表达式求值:标识符 " + name + " 不是常量");
ConstValue val;
if (sym->is_int_const) {
val.kind = ConstValue::INT;
val.int_val = sym->const_value.i32;
} else {
val.kind = ConstValue::FLOAT;
val.float_val = sym->const_value.f32;
}
return val;
}
else if (ctx->HEX_FLOAT() || ctx->DEC_FLOAT()) {
std::string text;
if (ctx->HEX_FLOAT()) text = ctx->HEX_FLOAT()->getText();
else text = ctx->DEC_FLOAT()->getText();
ConstValue val;
val.kind = ConstValue::FLOAT;
val.float_val = ParseFloatLiteral(text);
return val;
}
else if (ctx->HEX_INT() || ctx->OCTAL_INT() || ctx->DECIMAL_INT() || ctx->ZERO()) {
std::string text;
if (ctx->HEX_INT()) text = ctx->HEX_INT()->getText();
else if (ctx->OCTAL_INT()) text = ctx->OCTAL_INT()->getText();
else if (ctx->DECIMAL_INT()) text = ctx->DECIMAL_INT()->getText();
else text = ctx->ZERO()->getText();
ConstValue val;
val.kind = ConstValue::INT;
val.int_val = static_cast<int>(ParseIntegerLiteral(text));
return val;
}
else if (ctx->exp()) {
return EvaluateAddExp(ctx->exp()->addExp());
}
else {
throw std::runtime_error("常量表达式求值:不支持的 PrimaryExp 类型");
}
}
SymbolTable::ConstValue SymbolTable::EvaluateUnaryExp(SysYParser::UnaryExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 UnaryExp");
if (ctx->primaryExp()) {
return EvaluatePrimaryExp(ctx->primaryExp());
}
else if (ctx->unaryOp()) {
ConstValue operand = EvaluateUnaryExp(ctx->unaryExp());
std::string op = ctx->unaryOp()->getText();
if (op == "+") {
return operand;
}
else if (op == "-") {
if (operand.kind == ConstValue::INT) {
operand.int_val = -operand.int_val;
} else {
operand.float_val = -operand.float_val;
}
return operand;
}
else if (op == "!") {
if (operand.kind != ConstValue::INT) {
throw std::runtime_error("常量表达式求值:逻辑非操作数必须是整数");
}
ConstValue res;
res.kind = ConstValue::INT;
res.int_val = (operand.int_val == 0) ? 1 : 0;
return res;
}
else {
throw std::runtime_error("常量表达式求值:未知一元运算符 " + op);
}
}
else {
// 函数调用在常量表达式中不允许
throw std::runtime_error("常量表达式求值:不允许函数调用");
}
}
SymbolTable::ConstValue SymbolTable::EvaluateMulExp(SysYParser::MulExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 MulExp");
if (ctx->mulExp()) {
ConstValue left = EvaluateMulExp(ctx->mulExp());
ConstValue right = EvaluateUnaryExp(ctx->unaryExp());
std::string op;
if (ctx->MulOp()) op = "*";
else if (ctx->DivOp()) op = "/";
else if (ctx->QuoOp()) op = "%";
else throw std::runtime_error("常量表达式求值:未知乘法运算符");
bool is_float = (left.kind == ConstValue::FLOAT || right.kind == ConstValue::FLOAT);
if (is_float) {
float l = (left.kind == ConstValue::INT) ? static_cast<float>(left.int_val) : left.float_val;
float r = (right.kind == ConstValue::INT) ? static_cast<float>(right.int_val) : right.float_val;
ConstValue res;
res.kind = ConstValue::FLOAT;
if (op == "*") res.float_val = l * r;
else if (op == "/") res.float_val = l / r;
else if (op == "%") throw std::runtime_error("常量表达式求值:浮点数不支持取模运算");
return res;
} else {
int l = left.int_val;
int r = right.int_val;
ConstValue res;
res.kind = ConstValue::INT;
if (op == "*") res.int_val = l * r;
else if (op == "/") {
if (r == 0) throw std::runtime_error("常量表达式求值:除零错误");
res.int_val = l / r;
}
else if (op == "%") {
if (r == 0) throw std::runtime_error("常量表达式求值:模零错误");
res.int_val = l % r;
}
return res;
}
}
else {
return EvaluateUnaryExp(ctx->unaryExp());
}
}
SymbolTable::ConstValue SymbolTable::EvaluateAddExp(SysYParser::AddExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 AddExp");
if (ctx->addExp()) {
ConstValue left = EvaluateAddExp(ctx->addExp());
ConstValue right = EvaluateMulExp(ctx->mulExp());
std::string op;
if (ctx->AddOp()) op = "+";
else if (ctx->SubOp()) op = "-";
else throw std::runtime_error("常量表达式求值:未知加法运算符");
bool is_float = (left.kind == ConstValue::FLOAT || right.kind == ConstValue::FLOAT);
if (is_float) {
float l = (left.kind == ConstValue::INT) ? static_cast<float>(left.int_val) : left.float_val;
float r = (right.kind == ConstValue::INT) ? static_cast<float>(right.int_val) : right.float_val;
ConstValue res;
res.kind = ConstValue::FLOAT;
if (op == "+") res.float_val = l + r;
else res.float_val = l - r;
return res;
} else {
int l = left.int_val;
int r = right.int_val;
ConstValue res;
res.kind = ConstValue::INT;
if (op == "+") res.int_val = l + r;
else res.int_val = l - r;
return res;
}
}
else {
return EvaluateMulExp(ctx->mulExp());
}
}
int SymbolTable::EvaluateConstExp(SysYParser::ConstExpContext* ctx) const {
if (!ctx || !ctx->addExp())
throw std::runtime_error("常量表达式求值:无效 ConstExp");
ConstValue val = EvaluateAddExp(ctx->addExp());
if (val.kind == ConstValue::INT) {
return val.int_val;
} else {
float f = val.float_val;
int i = static_cast<int>(f);
if (std::abs(f - i) > 1e-6) {
throw std::runtime_error("常量表达式求值:浮点常量不能隐式转换为整数");
}
return i;
}
}
float SymbolTable::EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const {
if (!ctx || !ctx->addExp())
throw std::runtime_error("常量表达式求值:无效 ConstExp");
ConstValue val = EvaluateAddExp(ctx->addExp());
if (val.kind == ConstValue::INT) {
return static_cast<float>(val.int_val);
} else {
return val.float_val;
}
}
void SymbolTable::flattenInit(SysYParser::ConstInitValContext* ctx,
std::vector<ConstValue>& out,
std::shared_ptr<ir::Type> base_type) const {
if (!ctx) return;
// 获取当前初始化列表的文本(用于调试)
std::string ctxText;
if (ctx->constExp()) {
ctxText = ctx->constExp()->getText();
} else {
ctxText = "{ ... }";
}
if (ctx->constExp()) {
ConstValue val = EvaluateAddExp(ctx->constExp()->addExp());
DEBUG_MSG("处理常量表达式: " << ctxText
<< " 类型=" << (val.kind == ConstValue::INT ? "INT" : "FLOAT")
<< " 值=" << (val.kind == ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val))
<< " 目标类型=" << (base_type->IsInt32() ? "Int32" : "Float"));
// 整型数组不能接受浮点常量
if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) {
DEBUG_MSG("错误:整型数组遇到浮点常量,值=" << val.float_val);
throw std::runtime_error("常量初始化:整型数组不能使用浮点常量");
}
// 浮点数组接受整型常量,并隐式转换
if (base_type->IsFloat() && val.kind == ConstValue::INT) {
DEBUG_MSG("浮点数组接收整型常量,隐式转换为浮点: " << val.int_val);
val.kind = ConstValue::FLOAT;
val.float_val = static_cast<float>(val.int_val);
}
out.push_back(val);
} else {
DEBUG_MSG("进入花括号初始化列表: " << ctxText);
// 花括号初始化列表:递归展开所有子项
for (auto* sub : ctx->constInitVal()) {
flattenInit(sub, out, base_type);
}
DEBUG_MSG("退出花括号初始化列表");
}
}
std::vector<SymbolTable::ConstValue> SymbolTable::EvaluateConstInitVal(
SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) const {
// ========== 1. 标量常量dims 为空)==========
if (dims.empty()) {
if (!ctx || !ctx->constExp()) {
throw std::runtime_error("标量常量初始化必须使用单个表达式");
}
ConstValue val = EvaluateAddExp(ctx->constExp()->addExp());
// 类型兼容性检查
/*
if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) {
throw std::runtime_error("整型常量不能使用浮点常量初始化");
}
*/
// 隐式类型转换
if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) {
val.kind = ConstValue::INT;
val.float_val = static_cast<int>(val.int_val);
}
if (base_type->IsFloat() && val.kind == ConstValue::INT) {
val.kind = ConstValue::FLOAT;
val.float_val = static_cast<float>(val.int_val);
}
return {val}; // 返回包含单个值的向量
}
// ========== 2. 数组常量dims 非空)==========
// 计算数组总元素个数
size_t total = 1;
for (int d : dims) total *= d;
// 展平初始化列表(递归处理花括号)
std::vector<ConstValue> flat;
flattenInit(ctx, flat, base_type);
// 检查数量是否超过数组容量
if (flat.size() > total) {
throw std::runtime_error("常量初始化:提供的初始值数量超过数组元素总数");
}
// 不足的部分补零
if (flat.size() < total) {
ConstValue zero;
if (base_type->IsInt32()) {
zero.kind = ConstValue::INT;
zero.int_val = 0;
} else {
zero.kind = ConstValue::FLOAT;
zero.float_val = 0.0f;
}
flat.resize(total, zero);
}
return flat;
}
int SymbolTable::EvaluateConstExpression(SysYParser::ExpContext* ctx) const {
if (!ctx || !ctx->addExp()) {
throw std::runtime_error("常量表达式求值:无效 ExpContext");
}
ConstValue val = EvaluateAddExp(ctx->addExp());
if (val.kind == ConstValue::INT) {
return val.int_val;
} else {
float f = val.float_val;
int i = static_cast<int>(f);
if (std::abs(f - i) > 1e-6) {
throw std::runtime_error("常量表达式求值:浮点常量不能隐式转换为整数");
}
return i;
}
}
Loading…
Cancel
Save