更新目录结构,修改IR结构,部分修复IR生成

This commit is contained in:
rain2133
2025-06-20 22:46:04 +08:00
parent 1de8c0e7d7
commit c54543bff3
16 changed files with 1699 additions and 1890 deletions

59
src/include/ASTPrinter.h Normal file
View File

@@ -0,0 +1,59 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
class ASTPrinter : public SysYBaseVisitor {
private:
int indentLevel = 0;
std::string getIndent() {
return std::string(indentLevel * 4, ' ');
}
public:
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
// std::any visitBType(SysYParser::BTypeContext *ctx) override;
// std::any visitDecl(SysYParser::DeclContext *ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
// std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
std::any visitInitVal(SysYParser::InitValContext *ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext *ctx) override;
// std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override;
std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override;
// std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override;
// std::any visitStmt(SysYParser::StmtContext *ctx) override;
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
// std::any visitExp(SysYParser::ExpContext *ctx) override;
// std::any visitCond(SysYParser::CondContext *ctx) override;
std::any visitLValue(SysYParser::LValueContext *ctx) override;
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
std::any visitParenExp(SysYParser::ParenExpContext *ctx) override;
std::any visitNumber(SysYParser::NumberContext *ctx) override;
std::any visitString(SysYParser::StringContext *ctx) override;
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
std::any visitCall(SysYParser::CallContext *ctx) override;
// std::any visitUnExpOp(SysYParser::UnExpContext *ctx) override;
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
std::any visitEqExp(SysYParser::EqExpContext *ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
};

217
src/include/Backend.h Normal file
View File

@@ -0,0 +1,217 @@
#pragma once
/**
* 后端设计需要注意的点
*
* label分配 :
* 全局变量的label,常量的label,basicblock的label,函数入口label,函数出口label
* 全局数据处理
* 常量处理
* 临时变量的处理(包括函数参数也是临时变量)
* 函数参数的处理
* 块参数的处理 (如果SSA问题通过块传参解决则需要处理块参数)
* 函数栈空间结构的设计
* 块的遍历问题
* arm32的过程调用约定
*
* 后端测试需要注意的点
*
* 如何汇编与链接.
* qemu以及树莓派如何运行.
*/
#include <algorithm>
#include <set>
#include <string>
#include <vector>
#include "IR.h"
using std::find;
using std::map;
using std::pair;
using std::set;
using std::string;
using std::to_string;
using std::vector;
#define Macro_ERROR_MSG(...) \
do { \
fprintf(stderr, "ERROR in line-%d of %s: ", __LINE__, __FILE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
fflush(stderr); \
exit(1); \
} while (0);
#define M_emitInst(STR) (space + STR + eol)
#define M_emitComment(STR) (space + "//" + STR + eol)
#define M_emitLabel(STR) (STR + ":" + eol)
// #define REG_EXP
static const string space = string(4, ' ');
static const string eol = "\n";
// only for armv7
static const int int_align = 4;
static const int int_size = 4;
static const int int_p2align = 2;
static const int reg_size = 4;
// default arm32 max imm
//
static const uint32_t maxMovImm = 0xFFF;
static const string stackIndexReg = "fp";
static uint16_t getWordHigh(uint32_t cval) { return (cval >> 16) & 0xFFFF; }
static uint16_t getWordLow(uint32_t cval) { return cval & 0xFFFF; }
//
static string emitInst_1srcR_noDstR(string name, string srcReg) {
return space + name + " " + srcReg + eol;
}
static string emitInst_2srcR_1dstR(string name, string srcReg0, string srcReg1,
string dstReg) {
return space + name + " " + dstReg + ", " + srcReg0 + ", " + srcReg1 + eol;
}
namespace sysy {
//
class RegManager {
public:
//{0,1,2,3,4,5,6,7,8,9,10};
enum RegId : unsigned {
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
RNONE = 1024,
RANY = 2048,
};
static string toString(RegId reg) {
if (reg == RNONE)
return "RNONE";
if (reg == RANY)
return "RANY";
return "r" + to_string(reg);
}
};
class Operand {
public:
using RegId = RegManager::RegId;
enum Kind {
kReg,
kImm,
};
Kind kind;
union {
uint32_t imm;
RegId regId;
};
Operand(){};
Operand(uint32_t imm) : kind(kImm), imm(imm) {}
Operand(RegId regId) : kind(kReg), regId(regId) {}
bool isImm(void) { return kind == kImm; }
bool isReg(void) { return kind == kReg; }
uint32_t getImm(void) {
assert(kind == kImm);
return imm;
}
RegId getRegId(void) {
assert(kind == kReg);
return regId;
}
string toString(void) {
if (kind == kImm)
return "#" + to_string(imm);
else
return RegManager::toString(regId);
}
};
class CodeGen {
public:
using RegId = RegManager::RegId;
private:
sysy::Module *module;
Function *curFunc;
BasicBlock *curBB;
//
RegManager regm;
// globalValue
bool loadGlobalValByMOVWT = true;
// basicBlock
vector<BasicBlock *> linear_bb;
int bb_no = 0;
// function params, return value and localVar
map<Argument *, int> paramsStOffset;
map<Instruction *, int> localVarStOffset;
int retValueStOffset = 0;
size_t stOffsetAcc = 0;
// label manager
map<BasicBlock *, string> bb_labels;
uint64_t label_no = 0;
public:
CodeGen(Module *module) : module(module) {}
// code_gen function list
string code_gen();
string module_gen(Module *module);
string function_gen(Function *func);
string basicBlock_gen(BasicBlock *bb);
string instruction_gen(Instruction *instr);
string globaldata_gen();
string prologueCode_gen(Function *func);
string epilogueCode_gen(Function *func);
string literalPoolsCode_gen(Function *func);
string functionHead_gen(Function *func);
// Module
void clearModuleRecord(Module *module) { label_no = 0; }
// instruction gen function list
//<dstReg, code>
pair<RegId, string> loadInst_gen(LoadInst *ldInst, RegId dstRegId);
string storeInst_gen(StoreInst *stInst);
pair<RegId, string> allocaInst_gen(AllocaInst *aInst, RegId dstRegId);
string returnInst_gen(ReturnInst *retInst);
pair<RegId, string> callInst_gen(CallInst *retInst, RegId dstRegId);
pair<RegId, string> binaryInst_gen(BinaryInst *bInst, RegId dstRegId);
pair<RegId, string> unaryInst_gen(UnaryInst *bInst, RegId dstRegId);
string uncondBrInst_gen(UncondBrInst *ubInst);
string condBrInst_gen(CondBrInst *ubInst);
//
string storeRegToStack_gen(RegId regId, Instruction *inst) {
string code;
/**
*code in here
*/
return code;
}
// function
void clearFunctionRecord(Function *func) {
localVarStOffset.clear();
paramsStOffset.clear();
retValueStOffset = 0;
bb_labels.clear();
//
stOffsetAcc = 0;
}
string getBBLabel(BasicBlock *bb) {
auto t = bb_labels.find(bb);
string label;
if (t == bb_labels.end()) {
label = ".LBB_" + to_string(label_no++);
bb_labels.emplace(bb, label);
} else {
label = t->second;
}
return label;
}
};
} // namespace sysy

1319
src/include/IR.h Normal file

File diff suppressed because it is too large Load Diff

241
src/include/IRBuilder.h Normal file
View File

@@ -0,0 +1,241 @@
#pragma once
#include "IR.h"
#include <cassert>
#include <memory>
namespace sysy {
class IRBuilder {
private:
unsigned labelIndex; ///< 基本块标签编号
unsigned tmpIndex; ///< 临时变量编号
BasicBlock *block; ///< 当前基本块
BasicBlock::iterator position; ///< 当前基本块指令列表位置的迭代器
std::vector<BasicBlock *> trueBlocks; ///< true分支基本块列表
std::vector<BasicBlock *> falseBlocks; ///< false分支基本块列表
std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
public:
IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
explicit IRBuilder(BasicBlock *block) : labelIndex(0), tmpIndex(0), block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: labelIndex(0), tmpIndex(0), block(block), position(position) {}
public:
BasicBlock *getBasicBlock() const { return block; }
BasicBlock::iterator getPosition() const { return position; }
void setPosition(BasicBlock *block, BasicBlock::iterator position) {
this->block = block;
this->position = position;
}
void setPosition(BasicBlock::iterator position) { this->position = position; }
public:
CallInst *createCallInst(Function *callee,
const std::vector<Value *> &args = {},
const std::string &name = "") {
auto inst = new CallInst(callee, args, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UnaryInst *createUnaryInst(Instruction::Kind kind, Type *type, Value *operand,
const std::string &name = "") {
auto inst = new UnaryInst(kind, type, operand, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UnaryInst *createNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand,
name);
}
UnaryInst *createNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNot, Type::getIntType(), operand,
name);
}
UnaryInst *createFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand,
name);
}
UnaryInst *createFNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand,
name);
}
UnaryInst *createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand,
name);
}
BinaryInst *createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs,
Value *rhs, const std::string &name = "") {
auto inst = new BinaryInst(kind, type, lhs, rhs, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
BinaryInst *createAddInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createSubInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createMulInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createDivInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createRemInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpEQInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpNEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpLTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpLEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpGTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpGEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createFAddInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFSubInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFMulInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFDivInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFRemInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFRem, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFCmpEQInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpEQ, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpNEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpNE, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpLTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLT, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpLEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLE, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpGTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGT, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpGEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGE, Type::getFloatType(), lhs,
rhs, name);
}
ReturnInst *createReturnInst(Value *value = nullptr) {
auto inst = new ReturnInst(value);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UncondBrInst *createUncondBrInst(BasicBlock *block,
std::vector<Value *> args) {
auto inst = new UncondBrInst(block, args, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
CondBrInst *createCondBrInst(Value *condition, BasicBlock *thenBlock,
BasicBlock *elseBlock,
const std::vector<Value *> &thenArgs,
const std::vector<Value *> &elseArgs) {
auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs,
elseArgs, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
AllocaInst *createAllocaInst(Type *type,
const std::vector<Value *> &dims = {},
const std::string &name = "") {
auto inst = new AllocaInst(type, dims, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
LoadInst *createLoadInst(Value *pointer,
const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new LoadInst(pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
StoreInst *createStoreInst(Value *value, Value *pointer,
const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new StoreInst(value, pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
};
} // namespace sysy

View File

@@ -0,0 +1,78 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "IR.h"
#include "IRBuilder.h"
#include <sstream>
#include <map>
#include <vector>
#include <stack>
class LLVMIRGenerator : public SysYBaseVisitor {
public:
sysy::Module* getIRModule() const { return irModule.get(); }
std::string generateIR(SysYParser::CompUnitContext* unit);
std::string getIR() const { return irStream.str(); }
private:
std::unique_ptr<sysy::Module> irModule; // IR数据结构
std::stringstream irStream; // 文本输出流
sysy::IRBuilder irBuilder; // IR构建器
int tempCounter = 0;
std::string currentVarType;
// std::map<std::string, sysy::Value*> symbolTable;
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
std::map<std::string, std::string> tmpTable;
std::vector<std::string> globalVars;
std::string currentFunction;
std::string currentReturnType;
std::vector<std::string> breakStack;
std::vector<std::string> continueStack;
bool hasReturn = false;
struct LoopLabels {
std::string breakLabel; // break跳转的目标标签
std::string continueLabel; // continue跳转的目标标签
};
std::stack<LoopLabels> loopStack; // 用于管理循环的break和continue标签
std::string getNextTemp();
std::string getLLVMType(const std::string&);
sysy::Type* getSysYType(const std::string&);
bool inFunction = false; // 标识当前是否处于函数内部
// 访问方法
std::any visitCompUnit(SysYParser::CompUnitContext* ctx);
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx);
std::any visitVarDecl(SysYParser::VarDeclContext* ctx);
std::any visitVarDef(SysYParser::VarDefContext* ctx);
std::any visitFuncDef(SysYParser::FuncDefContext* ctx);
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx);
// std::any visitStmt(SysYParser::StmtContext* ctx);
std::any visitLValue(SysYParser::LValueContext* ctx);
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx);
std::any visitPrimExp(SysYParser::PrimExpContext* ctx);
std::any visitParenExp(SysYParser::ParenExpContext* ctx);
std::any visitNumber(SysYParser::NumberContext* ctx);
std::any visitString(SysYParser::StringContext* ctx);
std::any visitCall(SysYParser::CallContext *ctx);
std::any visitUnExp(SysYParser::UnExpContext* ctx);
std::any visitMulExp(SysYParser::MulExpContext* ctx);
std::any visitAddExp(SysYParser::AddExpContext* ctx);
std::any visitRelExp(SysYParser::RelExpContext* ctx);
std::any visitEqExp(SysYParser::EqExpContext* ctx);
std::any visitLAndExp(SysYParser::LAndExpContext* ctx);
std::any visitLOrExp(SysYParser::LOrExpContext* ctx);
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
// 统一创建二元操作(同时生成数据结构和文本)
sysy::Value* createBinaryOp(SysYParser::ExpContext* lhs,
SysYParser::ExpContext* rhs,
sysy::Instruction::Kind opKind);
};

View File

@@ -0,0 +1,99 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "IR.h" // 引入 SysY IR 头文件
#include "IRBuilder.h"
#include <sstream>
#include <map>
#include <vector>
#include <stack>
#include <memory>
class LLVMIRGenerator : public SysYBaseVisitor {
public:
// 生成 IR文本和数据结构
std::string generateIR(SysYParser::CompUnitContext* unit);
// 获取文本格式的 LLVM IR
std::string getIR() const { return irStream.str(); }
// 获取 SysY IR 数据结构
sysy::Module* getModule() const { return module.get(); }
private:
// 文本输出相关
std::stringstream irStream;
int tempCounter = 0; // 临时变量计数器
std::string currentVarType; // 当前变量类型(文本 IR 用)
// 符号表:映射变量名到 {分配地址/寄存器, 类型}(文本 IR
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
// 临时变量表:映射临时变量名到类型(文本 IR
std::map<std::string, std::string> tmpTable;
std::vector<std::string> globalVars; // 全局变量列表(文本 IR
// SysY IR 数据结构
std::unique_ptr<sysy::Module> module; // SysY IR 模块
// 符号表:映射变量名到 SysY IR 的 Value 指针
std::map<std::string, sysy::Value*> irSymbolTable;
// 临时变量表:映射临时变量名到 SysY IR 的 Value 指针
std::map<std::string, sysy::Value*> irTmpTable;
// 当前上下文
std::string currentFunction; // 当前函数名(文本 IR
std::string currentReturnType; // 当前函数返回类型(文本 IR
sysy::Function* currentIRFunction = nullptr; // 当前 SysY IR 函数
sysy::BasicBlock* currentIRBlock = nullptr; // 当前 SysY IR 基本块
// 循环控制
std::vector<std::string> breakStack; // break 标签栈(文本 IR
std::vector<std::string> continueStack; // continue 标签栈(文本 IR
bool hasReturn = false; // 是否有返回语句(文本 IR
struct LoopLabels {
std::string breakLabel; // break 跳转目标标签(文本 IR
std::string continueLabel; // continue 跳转目标标签(文本 IR
sysy::BasicBlock* irBreakBlock = nullptr; // break 跳转目标块SysY IR
sysy::BasicBlock* irContinueBlock = nullptr; // continue 跳转目标块SysY IR
};
std::stack<LoopLabels> loopStack; // 管理循环的 break 和 continue 标签
bool inFunction = false; // 标记是否在函数内部
// 辅助函数(文本 IR
std::string getNextTemp(); // 获取下一个临时变量名
std::string getLLVMType(const std::string& type); // 转换 SysY 类型到 LLVM 类型
// 辅助函数SysY IR
sysy::Type* getIRType(const std::string& type); // 转换 SysY 类型到 SysY IR 类型
std::string getIRTempName(); // 获取 SysY IR 临时变量名
void setIRPosition(sysy::BasicBlock* block); // 设置当前 IR 插入点
// 访问方法
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
std::any visitLValue(SysYParser::LValueContext* ctx) override;
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitPrimExp(SysYParser::PrimExpContext* ctx) override;
std::any visitParenExp(SysYParser::ParenExpContext* ctx) override;
std::any visitNumber(SysYParser::NumberContext* ctx) override;
std::any visitString(SysYParser::StringContext* ctx) override;
std::any visitCall(SysYParser::CallContext* ctx) override;
std::any visitUnExp(SysYParser::UnExpContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitAssignStmt(SysYParser::AssignStmtContext* ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext* ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext* ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext* ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext* ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext* ctx) override;
};

340
src/include/SysYFormatter.h Normal file
View File

@@ -0,0 +1,340 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include <ostream>
namespace sysy {
class SysYFormatter : public SysYBaseVisitor {
protected:
std::ostream &os;
int indent = 0;
public:
SysYFormatter(std::ostream &os) : os(os), indent(0) {}
protected:
struct Indentor {
static constexpr int TabSize = 2;
int &indent;
Indentor(int &indent) : indent(indent) { indent += TabSize; }
~Indentor() { indent -= TabSize; }
};
std::ostream &space() { return os << std::string(indent, ' '); }
template <typename T>
std::ostream &interleave(const T &container, const std::string sep = ", ") {
auto b = container.begin(), e = container.end();
(*b)->accept(this);
for (b = std::next(b); b != e; b = std::next(b)) {
os << sep;
(*b)->accept(this);
}
return os;
}
public:
// virtual std::any visitModule(SysYParser::ModuleContext *ctx) override {
// return visitChildren(ctx);
// }
virtual std::any visitBtype(SysYParser::BtypeContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any visitDecl(SysYParser::DeclContext *ctx) override {
space();
if (ctx->CONST())
os << ctx->CONST()->getText() << ' ';
ctx->btype()->accept(this);
os << ' ';
interleave(ctx->varDef(), ", ") << ';' << '\n';
return 0;
}
virtual std::any visitVarDef(SysYParser::VarDefContext *ctx) override {
ctx->lValue()->accept(this);
if (ctx->initValue()) {
os << ' ' << '=' << ' ';
ctx->initValue()->accept(this);
}
return 0;
}
virtual std::any visitInitValue(SysYParser::InitValueContext *ctx) override {
if (not ctx->exp()) {
os << '{';
auto values = ctx->initValue();
if (values.size())
interleave(values, ", ");
os << '}';
}
return 0;
}
virtual std::any visitFunc(SysYParser::FuncContext *ctx) override {
ctx->funcType()->accept(this);
os << ' ' << ctx->ID()->getText() << '(';
if (ctx->funcFParams())
ctx->funcFParams()->accept(this);
os << ')' << ' ';
ctx->blockStmt()->accept(this);
os << '\n';
return 0;
}
virtual std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any
visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override {
interleave(ctx->funcFParam(), ", ");
return 0;
}
virtual std::any
visitFuncFParam(SysYParser::FuncFParamContext *ctx) override {
ctx->btype()->accept(this);
os << ' ' << ctx->ID()->getText();
if (not ctx->LBRACKET().empty()) {
os << '[';
auto exp = ctx->exp();
if (not exp.empty()) {
os << '[';
interleave(exp, "][") << ']';
}
}
return 0;
}
virtual std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override {
os << '{' << '\n';
{
Indentor indentor(indent);
auto items = ctx->blockItem();
if (not items.empty())
interleave(items, "");
}
space() << ctx->RBRACE()->getText() << '\n';
return 0;
}
// virtual std::any visitBlockItem(SysYParser::BlockItemContext *ctx)
// override {
// return visitChildren(ctx);
// }
// virtual std::any visitStmt(SysYParser::StmtContext *ctx) override {
// return visitChildren(ctx);
// }
virtual std::any
visitAssignStmt(SysYParser::AssignStmtContext *ctx) override {
space();
ctx->lValue()->accept(this);
os << " = ";
ctx->exp()->accept(this);
os << ';' << '\n';
return 0;
}
virtual std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override {
space();
ctx->exp()->accept(this);
os << ';' << '\n';
return 0;
}
void wrapBlock(SysYParser::StmtContext *stmt) {
bool isBlock = stmt->blockStmt();
if (isBlock) {
stmt->accept(this);
} else {
os << "{\n";
{
Indentor indentor(indent);
stmt->accept(this);
}
space() << "}\n";
}
};
virtual std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override {
space();
os << ctx->IF()->getText() << " (";
ctx->exp()->accept(this);
os << ") ";
auto stmt = ctx->stmt();
auto ifStmt = stmt[0];
wrapBlock(ifStmt);
if (stmt.size() == 2) {
auto elseStmt = stmt[1];
wrapBlock(elseStmt);
}
return 0;
}
virtual std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override {
space();
os << ctx->WHILE()->getText() << " (";
ctx->exp()->accept(this);
os << ") ";
wrapBlock(ctx->stmt());
return 0;
}
virtual std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override {
space() << ctx->BREAK()->getText() << ';' << '\n';
return 0;
}
virtual std::any
visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override {
space() << ctx->CONTINUE()->getText() << ';' << '\n';
return 0;
}
virtual std::any
visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override {
space() << ctx->RETURN()->getText();
if (ctx->exp()) {
os << ' ';
ctx->exp()->accept(this);
}
os << ';' << '\n';
return 0;
}
// virtual std::any visitEmptyStmt(SysYParser::EmptyStmtContext *ctx)
// override {
// return visitChildren(ctx);
// }
virtual std::any
visitRelationExp(SysYParser::RelationExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op =
ctx->LT() ? "<" : (ctx->LE() ? "<=" : (ctx->GT() ? ">" : ">="));
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
virtual std::any
visitMultiplicativeExp(SysYParser::MultiplicativeExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op = ctx->MUL() ? "*" : (ctx->DIV() ? "/" : "%");
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
// virtual std::any visitLValueExp(SysYParser::LValueExpContext *ctx)
// override {
// return visitChildren(ctx);
// }
// virtual std::any visitNumberExp(SysYParser::NumberExpContext *ctx)
// override {
// return visitChildren(ctx);
// }
virtual std::any visitAndExp(SysYParser::AndExpContext *ctx) override {
ctx->exp(0)->accept(this);
os << " && ";
ctx->exp(1)->accept(this);
return 0;
}
virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override {
std::string op = ctx->ADD() ? "+" : (ctx->SUB() ? "-" : "!");
os << op;
ctx->exp()->accept(this);
return 0;
}
virtual std::any visitParenExp(SysYParser::ParenExpContext *ctx) override {
os << '(';
ctx->exp()->accept(this);
os << ')';
return 0;
}
virtual std::any visitStringExp(SysYParser::StringExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitOrExp(SysYParser::OrExpContext *ctx) override {
ctx->exp(0)->accept(this);
os << " || ";
ctx->exp(1)->accept(this);
return 0;
}
// virtual std::any visitCallExp(SysYParser::CallExpContext *ctx) override {
// return visitChildren(ctx);
// }
virtual std::any
visitAdditiveExp(SysYParser::AdditiveExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op = ctx->ADD() ? "+" : "-";
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
virtual std::any visitEqualExp(SysYParser::EqualExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op = ctx->EQ() ? "==" : "!=";
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
virtual std::any visitCall(SysYParser::CallContext *ctx) override {
os << ctx->ID()->getText() << '(';
if (ctx->funcRParams())
ctx->funcRParams()->accept(this);
os << ')';
return 0;
}
virtual std::any visitLValue(SysYParser::LValueContext *ctx) override {
os << ctx->ID()->getText();
auto exp = ctx->exp();
if (not exp.empty()) {
os << '[';
interleave(exp, "][") << ']';
}
return 0;
}
virtual std::any visitNumber(SysYParser::NumberContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any visitString(SysYParser::StringContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any
visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override {
interleave(ctx->exp(), ", ");
return 0;
}
};
} // namespace sysy

View File

View File

@@ -0,0 +1,140 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h"
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include <memory>
#include <unordered_map>
#include <forward_list>
namespace sysy {
class SymbolTable{
private:
enum Kind
{
kModule,
kFunction,
kBlock,
};
std::forward_list<std::pair<Kind, std::unordered_map<std::string, Value*>>> Scopes;
public:
struct ModuleScope {
SymbolTable& tables_ref;
ModuleScope(SymbolTable& tables) : tables_ref(tables) {
tables.enter(kModule);
}
~ModuleScope() { tables_ref.exit(); }
};
struct FunctionScope {
SymbolTable& tables_ref;
FunctionScope(SymbolTable& tables) : tables_ref(tables) {
tables.enter(kFunction);
}
~FunctionScope() { tables_ref.exit(); }
};
struct BlockScope {
SymbolTable& tables_ref;
BlockScope(SymbolTable& tables) : tables_ref(tables) {
tables.enter(kBlock);
}
~BlockScope() { tables_ref.exit(); }
};
SymbolTable() = default;
bool isModuleScope() const { return Scopes.front().first == kModule; }
bool isFunctionScope() const { return Scopes.front().first == kFunction; }
bool isBlockScope() const { return Scopes.front().first == kBlock; }
Value *lookup(const std::string &name) const {
for (auto &scope : Scopes) {
auto iter = scope.second.find(name);
if (iter != scope.second.end())
return iter->second;
}
return nullptr;
}
auto insert(const std::string &name, Value *value) {
assert(not Scopes.empty());
return Scopes.front().second.emplace(name, value);
}
private:
void enter(Kind kind) {
Scopes.emplace_front();
Scopes.front().first = kind;
}
void exit() {
Scopes.pop_front();
}
};
class SysYIRGenerator : public SysYBaseVisitor {
private:
std::unique_ptr<Module> module;
IRBuilder builder;
SymbolTable symbols_table;
int trueBlockNum = 0, falseBlockNum = 0;
int d = 0, n = 0;
vector<int> path;
bool isalloca;
AllocaInst *current_alloca;
GlobalValue *current_global;
Type* current_type;
int numdims = 0;
public:
SysYIRGenerator() = default;
public:
Module *get() const { return module.get(); }
public:
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
std::any visitDecl(SysYParser::DeclContext *ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
std::any visitBType(SysYParser::BTypeContext *ctx) override;
std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
std::any visitInitVal(SysYParser::InitValContext *ctx) override;
// std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
// std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
// std::any visitStmt(SysYParser::StmtContext *ctx) override;
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
// std::any visitExp(SysYParser::ExpContext *ctx) override;
std::any visitLValue(SysYParser::LValueContext *ctx) override;
std::any visitPrimExp(SysYParser::PrimExpContext *ctx) override;
// std::any visitParenExp(SysYParser::ParenExpContext *ctx) override;
std::any visitNumber(SysYParser::NumberContext *ctx) override;
// std::any visitString(SysYParser::StringContext *ctx) override;
std::any visitCall(SysYParser::CallContext *ctx) override;
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
std::any visitUnExp(SysYParser::UnExpContext *ctx) override;
// std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
std::any visitEqExp(SysYParser::EqExpContext *ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
}; // class SysYIRGenerator
} // namespace sysy

63
src/include/range.h Normal file
View File

@@ -0,0 +1,63 @@
#pragma once
#include <iterator>
namespace sysy {
/*!
* \defgroup utility Utilities
* @{
*/
/*!
* \brief `range` is an simple wrapper of an iterator pair [begin, end)
*
* Example usage
*
* ```cpp
* vector<int> v = {1,2,3};
* auto rg = make_range(v);
* for (auto v : rg)
* cout << v << '\n';
* ```
*/
template <typename IterT> struct range {
using iterator = IterT;
using value_type = typename std::iterator_traits<iterator>::value_type;
using reference = typename std::iterator_traits<iterator>::reference;
private:
iterator b;
iterator e;
public:
explicit range(iterator b, iterator e) : b(b), e(e) {}
iterator begin() { return b; }
iterator end() { return e; }
iterator begin() const { return b; }
iterator end() const { return e; }
auto size() const { return std::distance(b, e); }
auto empty() const { return b == e; }
};
//! create `range` object from iterator pair [begin, end)
template <typename IterT> range<IterT> make_range(IterT b, IterT e) {
return range(b, e);
}
//! create `range` object from a container who has `begin()` and `end()` methods
template <typename ContainerT>
range<typename ContainerT::iterator> make_range(ContainerT &c) {
return make_range(c.begin(), c.end());
}
//! create `range` object from a container who has `begin()` and `end()` methods
template <typename ContainerT>
range<typename ContainerT::const_iterator> make_range(const ContainerT &c) {
return make_range(c.begin(), c.end());
}
/*!
* @}
*/
} // namespace sysy