编译通过,还需补全功能

dahmer11
zjx 2 weeks ago
parent d6926a7b75
commit 52c4b75a9e

@ -37,6 +37,7 @@
#include <unordered_map>
#include <utility>
#include <vector>
#include <variant>
namespace ir {
@ -45,17 +46,15 @@ class Value;
class User;
class ConstantValue;
class ConstantInt;
class ConstantFloat;
class ConstantArray;
class GlobalValue;
class Instruction;
class BasicBlock;
class Function;
class Module;
// Use 表示一个 Value 的一次使用记录。
// 当前实现设计:
// - value被使用的值
// - user使用该值的 User
// - operand_index该值在 user 操作数列表中的位置
// ======================== Use 类 ========================
class Use {
public:
Use() = default;
@ -76,54 +75,130 @@ class Use {
size_t operand_index_ = 0;
};
// IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。
// ======================== Context 类 ========================
class Context {
public:
Context() = default;
~Context();
// 去重创建 i32 常量。
// 常量创建
ConstantInt* GetConstInt(int v);
ConstantFloat* GetConstFloat(float v);
// 临时变量名生成
std::string NextTemp();
private:
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_ints_;
std::unordered_map<float, std::unique_ptr<ConstantFloat>> const_floats_;
int temp_index_ = -1;
};
// ======================== Type 类型体系 ========================
// 类型基类,支持参数化类型
class Type {
public:
enum class Kind { Void, Int32, PtrInt32 };
enum class Kind {
Void,
Int32,
Float32,
Pointer,
Array,
Function,
Label
};
explicit Type(Kind k);
// 使用静态共享对象获取类型。
// 同一类型可直接比较返回值是否相等,例如:
// Type::GetInt32Type() == Type::GetInt32Type()
static const std::shared_ptr<Type>& GetVoidType();
static const std::shared_ptr<Type>& GetInt32Type();
static const std::shared_ptr<Type>& GetPtrInt32Type();
virtual ~Type() = default;
Kind GetKind() const;
bool IsVoid() const;
bool IsInt32() const;
bool IsPtrInt32() const;
bool IsFloat32() const;
bool IsPointer() const;
bool IsArray() const;
bool IsFunction() const;
bool IsLabel() const;
bool IsPtrInt32() const; // 兼容旧接口
bool IsPtrFloat32() const; // 判断是否为 float32*
bool operator==(const Type& other) const;
bool operator!=(const Type& other) const;
// 静态单例获取基础类型
static const std::shared_ptr<Type>& GetVoidType();
static const std::shared_ptr<Type>& GetInt32Type();
static const std::shared_ptr<Type>& GetFloat32Type();
static const std::shared_ptr<Type>& GetLabelType();
static const std::shared_ptr<Type>& GetPtrInt32Type();
// 复合类型工厂方法
static std::shared_ptr<Type> GetPointerType(std::shared_ptr<Type> pointee);
static std::shared_ptr<Type> GetArrayType(std::shared_ptr<Type> elem, size_t size);
static std::shared_ptr<Type> GetFunctionType(std::shared_ptr<Type> ret,
std::vector<std::shared_ptr<Type>> params);
private:
Kind kind_;
};
// 指针类型
class PointerType : public Type {
public:
PointerType(std::shared_ptr<Type> pointee)
: Type(Type::Kind::Pointer), pointee_(std::move(pointee)) {}
const std::shared_ptr<Type>& GetPointeeType() const { return pointee_; }
private:
std::shared_ptr<Type> pointee_;
};
// 数组类型
class ArrayType : public Type {
public:
ArrayType(std::shared_ptr<Type> elem, size_t size)
: Type(Type::Kind::Array), elem_type_(std::move(elem)), size_(size) {}
const std::shared_ptr<Type>& GetElementType() const { return elem_type_; }
size_t GetSize() const { return size_; }
private:
std::shared_ptr<Type> elem_type_;
size_t size_;
};
// 函数类型
class FunctionType : public Type {
public:
FunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params)
: Type(Type::Kind::Function), ret_type_(std::move(ret)), param_types_(std::move(params)) {}
const std::shared_ptr<Type>& GetReturnType() const { return ret_type_; }
const std::vector<std::shared_ptr<Type>>& GetParamTypes() const { return param_types_; }
private:
std::shared_ptr<Type> ret_type_;
std::vector<std::shared_ptr<Type>> param_types_;
};
// ======================== Value 类 ========================
class Value {
public:
Value(std::shared_ptr<Type> ty, std::string name);
virtual ~Value() = default;
const std::shared_ptr<Type>& GetType() const;
const std::string& GetName() const;
void SetName(std::string n);
bool IsVoid() const;
bool IsInt32() const;
bool IsPtrInt32() const;
bool IsFloat32() const;
bool IsPtrInt32() const; // 兼容旧接口,实际上判断是否为 i32*
bool IsPtrFloat32() const; // 判断是否为 float32*
bool IsConstant() const;
bool IsInstruction() const;
bool IsUser() const;
bool IsFunction() const;
bool IsGlobalValue() const;
void AddUse(User* user, size_t operand_index);
void RemoveUse(User* user, size_t operand_index);
const std::vector<Use>& GetUses() const;
@ -135,8 +210,7 @@ class Value {
std::vector<Use> uses_;
};
// ConstantValue 是常量体系的基类。
// 当前只实现了 ConstantInt后续可继续扩展更多常量种类。
// ======================== 常量体系 ========================
class ConstantValue : public Value {
public:
ConstantValue(std::shared_ptr<Type> ty, std::string name = "");
@ -151,11 +225,26 @@ class ConstantInt : public ConstantValue {
int value_{};
};
// 后续还需要扩展更多指令类型。
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
class ConstantFloat : public ConstantValue {
public:
ConstantFloat(std::shared_ptr<Type> ty, float v);
float GetValue() const { return value_; }
private:
float value_{};
};
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
// 当前实现中只有 Instruction 继承自 User。
// 常量数组(简单聚合,可存储常量元素)
class ConstantArray : public ConstantValue {
public:
ConstantArray(std::shared_ptr<Type> ty, std::vector<ConstantValue*> elems);
const std::vector<ConstantValue*>& GetElements() const { return elements_; }
private:
std::vector<ConstantValue*> elements_;
};
// ======================== User 类 ========================
class User : public Value {
public:
User(std::shared_ptr<Type> ty, std::string name);
@ -164,20 +253,44 @@ class User : public Value {
void SetOperand(size_t index, Value* value);
protected:
// 统一的 operand 入口。
void AddOperand(Value* value);
private:
std::vector<Value*> operands_;
};
// GlobalValue 是全局值/全局变量体系的空壳占位类。
// 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。
// ======================== GlobalValue 类 ========================
class GlobalValue : public User {
public:
GlobalValue(std::shared_ptr<Type> ty, std::string name);
ConstantValue* GetInitializer() const { return init_; }
void SetInitializer(ConstantValue* init) { init_ = init; }
private:
ConstantValue* init_ = nullptr;
};
// ======================== 指令操作码 ========================
enum class Opcode {
// 算术
Add, Sub, Mul, Div, Mod,
// 位运算
And, Or, Xor, Shl, LShr, AShr,
// 比较
ICmp, FCmp,
// 内存
Alloca, Load, Store,
// 控制流
Ret, Br, CondBr,
// 函数调用
Call,
// 数组访问
GEP,
// Phi
Phi
};
// ======================== Instruction 类 ========================
class Instruction : public User {
public:
Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = "");
@ -191,31 +304,94 @@ class Instruction : public User {
BasicBlock* parent_ = nullptr;
};
// 二元运算指令
class BinaryInst : public Instruction {
public:
BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, Value* rhs,
std::string name);
Value* GetLhs() const;
Value* GetRhs() const;
Value* GetRhs() const;
};
// 比较指令icmp/fcmp
class CmpInst : public Instruction {
public:
enum Predicate {
EQ, NE, LT, LE, GT, GE
};
CmpInst(Opcode op, Predicate pred, Value* lhs, Value* rhs, std::string name);
Predicate GetPredicate() const { return pred_; }
Value* GetLhs() const { return lhs_; }
Value* GetRhs() const { return rhs_; }
private:
Predicate pred_;
Value* lhs_;
Value* rhs_;
};
// 返回指令
class ReturnInst : public Instruction {
public:
ReturnInst(std::shared_ptr<Type> void_ty, Value* val);
ReturnInst(std::shared_ptr<Type> void_ty, Value* val = nullptr);
Value* GetValue() const;
};
// 无条件分支
class BranchInst : public Instruction {
public:
BranchInst(BasicBlock* target);
BasicBlock* GetTarget() const;
};
// 条件分支
class CondBranchInst : public Instruction {
public:
CondBranchInst(Value* cond, BasicBlock* true_bb, BasicBlock* false_bb);
Value* GetCond() const;
BasicBlock* GetTrueBlock() const;
BasicBlock* GetFalseBlock() const;
};
// 函数调用
class CallInst : public Instruction {
public:
CallInst(Function* callee, std::vector<Value*> args, std::string name);
Function* GetCallee() const;
const std::vector<Value*>& GetArgs() const;
};
// Phi 指令(用于 SSA
class PhiInst : public Instruction {
public:
PhiInst(std::shared_ptr<Type> ty, std::string name);
void AddIncoming(Value* val, BasicBlock* block);
const std::vector<std::pair<Value*, BasicBlock*>>& GetIncomings() const;
};
// GetElementPtr 指令(数组/结构体指针计算)
class GetElementPtrInst : public Instruction {
public:
GetElementPtrInst(std::shared_ptr<Type> ty, Value* ptr,
std::vector<Value*> indices, std::string name);
Value* GetPtr() const;
const std::vector<Value*>& GetIndices() const;
};
// 分配栈内存指令
class AllocaInst : public Instruction {
public:
AllocaInst(std::shared_ptr<Type> ptr_ty, std::string name);
};
// 加载指令
class LoadInst : public Instruction {
public:
LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name);
Value* GetPtr() const;
};
// 存储指令
class StoreInst : public Instruction {
public:
StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr);
@ -223,8 +399,7 @@ class StoreInst : public Instruction {
Value* GetPtr() const;
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
// ======================== BasicBlock 类 ========================
class BasicBlock : public Value {
public:
explicit BasicBlock(std::string name);
@ -234,6 +409,11 @@ class BasicBlock : public Value {
const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& GetSuccessors() const;
void AddPredecessor(BasicBlock* pred);
void AddSuccessor(BasicBlock* succ);
void RemovePredecessor(BasicBlock* pred);
void RemoveSuccessor(BasicBlock* succ);
template <typename T, typename... Args>
T* Append(Args&&... args) {
if (HasTerminator()) {
@ -254,65 +434,117 @@ class BasicBlock : public Value {
std::vector<BasicBlock*> successors_;
};
// Function 当前也采用了最小实现。
// 需要特别注意:由于项目里还没有单独的 FunctionType
// Function 继承自 Value 后,其 type_ 目前只保存“返回类型”,
// 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。
// 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、
// 形参和调用,通常需要引入专门的函数类型表示。
// ======================== Function 类 ========================
class Function : public Value {
public:
// 当前构造函数接收的也是返回类型,而不是完整函数类型。
Function(std::string name, std::shared_ptr<Type> ret_type);
// 构造函数,接收函数名、返回类型和参数类型列表(可选)
Function(std::string name, std::shared_ptr<Type> ret_type,
std::vector<std::shared_ptr<Type>> param_types = {});
BasicBlock* CreateBlock(const std::string& name);
BasicBlock* GetEntry();
const BasicBlock* GetEntry() const;
const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
// 参数管理
const std::vector<Value*>& GetParams() const { return params_; }
void AddParam(Value* param);
// 函数类型(完整签名)
std::shared_ptr<FunctionType> GetFunctionType() const;
private:
BasicBlock* entry_ = nullptr;
std::vector<std::unique_ptr<BasicBlock>> blocks_;
std::vector<Value*> params_; // 参数值(通常是 Argument 类型,后续可定义)
std::shared_ptr<FunctionType> func_type_; // 缓存函数类型
};
// ======================== Module 类 ========================
class Module {
public:
Module() = default;
Context& GetContext();
const Context& GetContext() const;
// 创建函数时当前只显式传入返回类型,尚未接入完整的 FunctionType。
// 创建函数,支持参数类型
Function* CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type);
std::shared_ptr<Type> ret_type,
std::vector<std::shared_ptr<Type>> param_types = {});
// 创建全局变量
GlobalValue* CreateGlobalVariable(const std::string& name,
std::shared_ptr<Type> ty,
ConstantValue* init = nullptr);
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
const std::vector<std::unique_ptr<GlobalValue>>& GetGlobalVariables() const;
private:
Context context_;
std::vector<std::unique_ptr<Function>> functions_;
std::vector<std::unique_ptr<GlobalValue>> global_vars_;
};
// ======================== IRBuilder 类 ========================
class IRBuilder {
public:
IRBuilder(Context& ctx, BasicBlock* bb);
IRBuilder(Context& ctx, BasicBlock* bb = nullptr);
void SetInsertPoint(BasicBlock* bb);
BasicBlock* GetInsertBlock() const;
// 构造常量、二元运算、返回指令的最小集合。
// 常量创建
ConstantInt* CreateConstInt(int v);
ConstantFloat* CreateConstFloat(float v);
// 算术指令
BinaryInst* CreateBinary(Opcode op, Value* lhs, Value* rhs,
const std::string& name);
BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateSub(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMul(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateDiv(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMod(Value* lhs, Value* rhs, const std::string& name);
// 比较指令
CmpInst* CreateICmp(CmpInst::Predicate pred, Value* lhs, Value* rhs,
const std::string& name);
CmpInst* CreateFCmp(CmpInst::Predicate pred, Value* lhs, Value* rhs,
const std::string& name);
// 内存指令
AllocaInst* CreateAllocaI32(const std::string& name);
AllocaInst* CreateAllocaFloat(const std::string& name);
AllocaInst* CreateAlloca(std::shared_ptr<Type> ty, const std::string& name);
LoadInst* CreateLoad(Value* ptr, const std::string& name);
StoreInst* CreateStore(Value* val, Value* ptr);
// 控制流指令
ReturnInst* CreateRet(Value* v);
BranchInst* CreateBr(BasicBlock* target);
CondBranchInst* CreateCondBr(Value* cond, BasicBlock* true_bb,
BasicBlock* false_bb);
// 函数调用
CallInst* CreateCall(Function* callee, std::vector<Value*> args,
const std::string& name);
// 数组访问
GetElementPtrInst* CreateGEP(Value* ptr, std::vector<Value*> indices,
const std::string& name);
// Phi 指令
PhiInst* CreatePhi(std::shared_ptr<Type> ty, const std::string& name);
private:
Context& ctx_;
BasicBlock* insert_block_;
};
// ======================== IRPrinter 类 ========================
class IRPrinter {
public:
void Print(const Module& module, std::ostream& os);
};
} // namespace ir
} // namespace ir

@ -22,20 +22,19 @@ class Value;
class IRGenImpl final : public SysYBaseVisitor {
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
IRGenImpl(ir::Module& module, IRGenContext& sema);
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
std::any visitBlock(SysYParser::BlockContext* ctx) override;
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitStmt(SysYParser::StmtContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext* ctx) override;
std::any visitParenExp(SysYParser::ParenExpContext* ctx) override;
std::any visitNumberExp(SysYParser::NumberExpContext* ctx) override;
std::any visitVarExp(SysYParser::VarExpContext* ctx) override;
std::any visitAdditiveExp(SysYParser::AdditiveExpContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitNumber(SysYParser::NumberContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
private:
enum class BlockFlow {
@ -47,7 +46,7 @@ class IRGenImpl final : public SysYBaseVisitor {
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
ir::Module& module_;
const SemanticContext& sema_;
IRGenContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
@ -55,4 +54,4 @@ class IRGenImpl final : public SysYBaseVisitor {
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema);
IRGenContext& sema);

@ -2,7 +2,7 @@
#define SEMANTIC_ANALYSIS_H
#include "SymbolTable.h"
#include "../../generated/antlr4/SysYBaseVisitor.h"
#include "SysYBaseVisitor.h"
#include <vector>
#include <string>
#include <sstream>
@ -175,4 +175,7 @@ private:
// 语义分析入口函数
void RunSemanticAnalysis(SysYParser::CompUnitContext* ctx, IRGenContext& ir_ctx);
// 兼容主程序的简单包装:返回构造好的 IRGenContext按值
IRGenContext RunSema(SysYParser::CompUnitContext& ctx);
#endif // SEMANTIC_ANALYSIS_H

@ -1,7 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#include "SysYBaseVisitor.h"

@ -1,144 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#pragma once
#include "antlr4-runtime.h"
#include "SysYVisitor.h"
/**
* This class provides an empty implementation of SysYVisitor, which can be
* extended to create a visitor which only needs to handle a subset of the available methods.
*/
class SysYBaseVisitor : public SysYVisitor {
public:
virtual antlrcpp::Any visitCompUnit(SysYParser::CompUnitContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitDecl(SysYParser::DeclContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitConstDecl(SysYParser::ConstDeclContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitBType(SysYParser::BTypeContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitConstDef(SysYParser::ConstDefContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitVarDecl(SysYParser::VarDeclContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitVarDef(SysYParser::VarDefContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitInitVal(SysYParser::InitValContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitFuncDef(SysYParser::FuncDefContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitFuncType(SysYParser::FuncTypeContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitBlock(SysYParser::BlockContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitBlockItem(SysYParser::BlockItemContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitStmt(SysYParser::StmtContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitExp(SysYParser::ExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitCond(SysYParser::CondContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitLVal(SysYParser::LValContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitNumber(SysYParser::NumberContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitMulExp(SysYParser::MulExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitAddExp(SysYParser::AddExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitRelExp(SysYParser::RelExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitEqExp(SysYParser::EqExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitLAndExp(SysYParser::LAndExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitLOrExp(SysYParser::LOrExpContext *ctx) override {
return visitChildren(ctx);
}
virtual antlrcpp::Any visitConstExp(SysYParser::ConstExpContext *ctx) override {
return visitChildren(ctx);
}
};

@ -1,377 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#include "SysYLexer.h"
using namespace antlr4;
SysYLexer::SysYLexer(CharStream *input) : Lexer(input) {
_interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);
}
SysYLexer::~SysYLexer() {
delete _interpreter;
}
std::string SysYLexer::getGrammarFileName() const {
return "SysY.g4";
}
const std::vector<std::string>& SysYLexer::getRuleNames() const {
return _ruleNames;
}
const std::vector<std::string>& SysYLexer::getChannelNames() const {
return _channelNames;
}
const std::vector<std::string>& SysYLexer::getModeNames() const {
return _modeNames;
}
const std::vector<std::string>& SysYLexer::getTokenNames() const {
return _tokenNames;
}
dfa::Vocabulary& SysYLexer::getVocabulary() const {
return _vocabulary;
}
const std::vector<uint16_t> SysYLexer::getSerializedATN() const {
return _serializedATN;
}
const atn::ATN& SysYLexer::getATN() const {
return _atn;
}
// Static vars and initialization.
std::vector<dfa::DFA> SysYLexer::_decisionToDFA;
atn::PredictionContextCache SysYLexer::_sharedContextCache;
// We own the ATN which in turn owns the ATN states.
atn::ATN SysYLexer::_atn;
std::vector<uint16_t> SysYLexer::_serializedATN;
std::vector<std::string> SysYLexer::_ruleNames = {
u8"T__0", u8"T__1", u8"T__2", u8"T__3", u8"T__4", u8"T__5", u8"T__6",
u8"T__7", u8"T__8", u8"T__9", u8"T__10", u8"T__11", u8"T__12", u8"T__13",
u8"T__14", u8"T__15", u8"T__16", u8"T__17", u8"T__18", u8"T__19", u8"T__20",
u8"T__21", u8"T__22", u8"T__23", u8"T__24", u8"T__25", u8"T__26", u8"T__27",
u8"T__28", u8"T__29", u8"T__30", u8"T__31", u8"T__32", u8"DIGIT", u8"HEXDIGIT",
u8"EXP", u8"PEXP", u8"FloatConst", u8"IntConst", u8"Ident", u8"WS", u8"LINE_COMMENT",
u8"BLOCK_COMMENT"
};
std::vector<std::string> SysYLexer::_channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
std::vector<std::string> SysYLexer::_modeNames = {
u8"DEFAULT_MODE"
};
std::vector<std::string> SysYLexer::_literalNames = {
"", u8"'const'", u8"','", u8"';'", u8"'int'", u8"'float'", u8"'['", u8"']'",
u8"'='", u8"'{'", u8"'}'", u8"'('", u8"')'", u8"'void'", u8"'if'", u8"'else'",
u8"'while'", u8"'break'", u8"'continue'", u8"'return'", u8"'+'", u8"'-'",
u8"'!'", u8"'*'", u8"'/'", u8"'%'", u8"'<'", u8"'>'", u8"'<='", u8"'>='",
u8"'=='", u8"'!='", u8"'&&'", u8"'||'"
};
std::vector<std::string> SysYLexer::_symbolicNames = {
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", u8"FloatConst",
u8"IntConst", u8"Ident", u8"WS", u8"LINE_COMMENT", u8"BLOCK_COMMENT"
};
dfa::Vocabulary SysYLexer::_vocabulary(_literalNames, _symbolicNames);
std::vector<std::string> SysYLexer::_tokenNames;
SysYLexer::Initializer::Initializer() {
// This code could be in a static initializer lambda, but VS doesn't allow access to private class members from there.
for (size_t i = 0; i < _symbolicNames.size(); ++i) {
std::string name = _vocabulary.getLiteralName(i);
if (name.empty()) {
name = _vocabulary.getSymbolicName(i);
}
if (name.empty()) {
_tokenNames.push_back("<INVALID>");
} else {
_tokenNames.push_back(name);
}
}
_serializedATN = {
0x3, 0x608b, 0xa72a, 0x8133, 0xb9ed, 0x417c, 0x3be7, 0x7786, 0x5964,
0x2, 0x29, 0x160, 0x8, 0x1, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3,
0x4, 0x4, 0x9, 0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, 0x7,
0x9, 0x7, 0x4, 0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x4, 0xa, 0x9, 0xa,
0x4, 0xb, 0x9, 0xb, 0x4, 0xc, 0x9, 0xc, 0x4, 0xd, 0x9, 0xd, 0x4, 0xe,
0x9, 0xe, 0x4, 0xf, 0x9, 0xf, 0x4, 0x10, 0x9, 0x10, 0x4, 0x11, 0x9,
0x11, 0x4, 0x12, 0x9, 0x12, 0x4, 0x13, 0x9, 0x13, 0x4, 0x14, 0x9, 0x14,
0x4, 0x15, 0x9, 0x15, 0x4, 0x16, 0x9, 0x16, 0x4, 0x17, 0x9, 0x17, 0x4,
0x18, 0x9, 0x18, 0x4, 0x19, 0x9, 0x19, 0x4, 0x1a, 0x9, 0x1a, 0x4, 0x1b,
0x9, 0x1b, 0x4, 0x1c, 0x9, 0x1c, 0x4, 0x1d, 0x9, 0x1d, 0x4, 0x1e, 0x9,
0x1e, 0x4, 0x1f, 0x9, 0x1f, 0x4, 0x20, 0x9, 0x20, 0x4, 0x21, 0x9, 0x21,
0x4, 0x22, 0x9, 0x22, 0x4, 0x23, 0x9, 0x23, 0x4, 0x24, 0x9, 0x24, 0x4,
0x25, 0x9, 0x25, 0x4, 0x26, 0x9, 0x26, 0x4, 0x27, 0x9, 0x27, 0x4, 0x28,
0x9, 0x28, 0x4, 0x29, 0x9, 0x29, 0x4, 0x2a, 0x9, 0x2a, 0x4, 0x2b, 0x9,
0x2b, 0x4, 0x2c, 0x9, 0x2c, 0x3, 0x2, 0x3, 0x2, 0x3, 0x2, 0x3, 0x2,
0x3, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x4, 0x3, 0x5,
0x3, 0x5, 0x3, 0x5, 0x3, 0x5, 0x3, 0x6, 0x3, 0x6, 0x3, 0x6, 0x3, 0x6,
0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3, 0x7, 0x3, 0x8, 0x3, 0x8, 0x3, 0x9,
0x3, 0x9, 0x3, 0xa, 0x3, 0xa, 0x3, 0xb, 0x3, 0xb, 0x3, 0xc, 0x3, 0xc,
0x3, 0xd, 0x3, 0xd, 0x3, 0xe, 0x3, 0xe, 0x3, 0xe, 0x3, 0xe, 0x3, 0xe,
0x3, 0xf, 0x3, 0xf, 0x3, 0xf, 0x3, 0x10, 0x3, 0x10, 0x3, 0x10, 0x3,
0x10, 0x3, 0x10, 0x3, 0x11, 0x3, 0x11, 0x3, 0x11, 0x3, 0x11, 0x3, 0x11,
0x3, 0x11, 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, 0x3,
0x12, 0x3, 0x13, 0x3, 0x13, 0x3, 0x13, 0x3, 0x13, 0x3, 0x13, 0x3, 0x13,
0x3, 0x13, 0x3, 0x13, 0x3, 0x13, 0x3, 0x14, 0x3, 0x14, 0x3, 0x14, 0x3,
0x14, 0x3, 0x14, 0x3, 0x14, 0x3, 0x14, 0x3, 0x15, 0x3, 0x15, 0x3, 0x16,
0x3, 0x16, 0x3, 0x17, 0x3, 0x17, 0x3, 0x18, 0x3, 0x18, 0x3, 0x19, 0x3,
0x19, 0x3, 0x1a, 0x3, 0x1a, 0x3, 0x1b, 0x3, 0x1b, 0x3, 0x1c, 0x3, 0x1c,
0x3, 0x1d, 0x3, 0x1d, 0x3, 0x1d, 0x3, 0x1e, 0x3, 0x1e, 0x3, 0x1e, 0x3,
0x1f, 0x3, 0x1f, 0x3, 0x1f, 0x3, 0x20, 0x3, 0x20, 0x3, 0x20, 0x3, 0x21,
0x3, 0x21, 0x3, 0x21, 0x3, 0x22, 0x3, 0x22, 0x3, 0x22, 0x3, 0x23, 0x3,
0x23, 0x3, 0x24, 0x3, 0x24, 0x3, 0x25, 0x3, 0x25, 0x5, 0x25, 0xcd, 0xa,
0x25, 0x3, 0x25, 0x6, 0x25, 0xd0, 0xa, 0x25, 0xd, 0x25, 0xe, 0x25, 0xd1,
0x3, 0x26, 0x3, 0x26, 0x5, 0x26, 0xd6, 0xa, 0x26, 0x3, 0x26, 0x6, 0x26,
0xd9, 0xa, 0x26, 0xd, 0x26, 0xe, 0x26, 0xda, 0x3, 0x27, 0x3, 0x27, 0x3,
0x27, 0x3, 0x27, 0x5, 0x27, 0xe1, 0xa, 0x27, 0x3, 0x27, 0x6, 0x27, 0xe4,
0xa, 0x27, 0xd, 0x27, 0xe, 0x27, 0xe5, 0x3, 0x27, 0x3, 0x27, 0x7, 0x27,
0xea, 0xa, 0x27, 0xc, 0x27, 0xe, 0x27, 0xed, 0xb, 0x27, 0x3, 0x27, 0x3,
0x27, 0x6, 0x27, 0xf1, 0xa, 0x27, 0xd, 0x27, 0xe, 0x27, 0xf2, 0x3, 0x27,
0x6, 0x27, 0xf6, 0xa, 0x27, 0xd, 0x27, 0xe, 0x27, 0xf7, 0x5, 0x27, 0xfa,
0xa, 0x27, 0x3, 0x27, 0x3, 0x27, 0x3, 0x27, 0x3, 0x27, 0x6, 0x27, 0x100,
0xa, 0x27, 0xd, 0x27, 0xe, 0x27, 0x101, 0x3, 0x27, 0x5, 0x27, 0x105,
0xa, 0x27, 0x3, 0x27, 0x6, 0x27, 0x108, 0xa, 0x27, 0xd, 0x27, 0xe, 0x27,
0x109, 0x3, 0x27, 0x3, 0x27, 0x7, 0x27, 0x10e, 0xa, 0x27, 0xc, 0x27,
0xe, 0x27, 0x111, 0xb, 0x27, 0x3, 0x27, 0x5, 0x27, 0x114, 0xa, 0x27,
0x3, 0x27, 0x6, 0x27, 0x117, 0xa, 0x27, 0xd, 0x27, 0xe, 0x27, 0x118,
0x3, 0x27, 0x3, 0x27, 0x5, 0x27, 0x11d, 0xa, 0x27, 0x3, 0x28, 0x3, 0x28,
0x3, 0x28, 0x7, 0x28, 0x122, 0xa, 0x28, 0xc, 0x28, 0xe, 0x28, 0x125,
0xb, 0x28, 0x3, 0x28, 0x3, 0x28, 0x6, 0x28, 0x129, 0xa, 0x28, 0xd, 0x28,
0xe, 0x28, 0x12a, 0x3, 0x28, 0x3, 0x28, 0x3, 0x28, 0x3, 0x28, 0x5, 0x28,
0x131, 0xa, 0x28, 0x3, 0x28, 0x6, 0x28, 0x134, 0xa, 0x28, 0xd, 0x28,
0xe, 0x28, 0x135, 0x5, 0x28, 0x138, 0xa, 0x28, 0x3, 0x29, 0x3, 0x29,
0x7, 0x29, 0x13c, 0xa, 0x29, 0xc, 0x29, 0xe, 0x29, 0x13f, 0xb, 0x29,
0x3, 0x2a, 0x6, 0x2a, 0x142, 0xa, 0x2a, 0xd, 0x2a, 0xe, 0x2a, 0x143,
0x3, 0x2a, 0x3, 0x2a, 0x3, 0x2b, 0x3, 0x2b, 0x3, 0x2b, 0x3, 0x2b, 0x7,
0x2b, 0x14c, 0xa, 0x2b, 0xc, 0x2b, 0xe, 0x2b, 0x14f, 0xb, 0x2b, 0x3,
0x2b, 0x3, 0x2b, 0x3, 0x2c, 0x3, 0x2c, 0x3, 0x2c, 0x3, 0x2c, 0x7, 0x2c,
0x157, 0xa, 0x2c, 0xc, 0x2c, 0xe, 0x2c, 0x15a, 0xb, 0x2c, 0x3, 0x2c,
0x3, 0x2c, 0x3, 0x2c, 0x3, 0x2c, 0x3, 0x2c, 0x3, 0x158, 0x2, 0x2d, 0x3,
0x3, 0x5, 0x4, 0x7, 0x5, 0x9, 0x6, 0xb, 0x7, 0xd, 0x8, 0xf, 0x9, 0x11,
0xa, 0x13, 0xb, 0x15, 0xc, 0x17, 0xd, 0x19, 0xe, 0x1b, 0xf, 0x1d, 0x10,
0x1f, 0x11, 0x21, 0x12, 0x23, 0x13, 0x25, 0x14, 0x27, 0x15, 0x29, 0x16,
0x2b, 0x17, 0x2d, 0x18, 0x2f, 0x19, 0x31, 0x1a, 0x33, 0x1b, 0x35, 0x1c,
0x37, 0x1d, 0x39, 0x1e, 0x3b, 0x1f, 0x3d, 0x20, 0x3f, 0x21, 0x41, 0x22,
0x43, 0x23, 0x45, 0x2, 0x47, 0x2, 0x49, 0x2, 0x4b, 0x2, 0x4d, 0x24,
0x4f, 0x25, 0x51, 0x26, 0x53, 0x27, 0x55, 0x28, 0x57, 0x29, 0x3, 0x2,
0xd, 0x3, 0x2, 0x32, 0x3b, 0x5, 0x2, 0x32, 0x3b, 0x43, 0x48, 0x63, 0x68,
0x4, 0x2, 0x47, 0x47, 0x67, 0x67, 0x4, 0x2, 0x2d, 0x2d, 0x2f, 0x2f,
0x4, 0x2, 0x52, 0x52, 0x72, 0x72, 0x3, 0x2, 0x33, 0x3b, 0x3, 0x2, 0x32,
0x39, 0x5, 0x2, 0x43, 0x5c, 0x61, 0x61, 0x63, 0x7c, 0x6, 0x2, 0x32,
0x3b, 0x43, 0x5c, 0x61, 0x61, 0x63, 0x7c, 0x5, 0x2, 0xb, 0xc, 0xf, 0xf,
0x22, 0x22, 0x4, 0x2, 0xc, 0xc, 0xf, 0xf, 0x2, 0x17a, 0x2, 0x3, 0x3,
0x2, 0x2, 0x2, 0x2, 0x5, 0x3, 0x2, 0x2, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2,
0x2, 0x2, 0x9, 0x3, 0x2, 0x2, 0x2, 0x2, 0xb, 0x3, 0x2, 0x2, 0x2, 0x2,
0xd, 0x3, 0x2, 0x2, 0x2, 0x2, 0xf, 0x3, 0x2, 0x2, 0x2, 0x2, 0x11, 0x3,
0x2, 0x2, 0x2, 0x2, 0x13, 0x3, 0x2, 0x2, 0x2, 0x2, 0x15, 0x3, 0x2, 0x2,
0x2, 0x2, 0x17, 0x3, 0x2, 0x2, 0x2, 0x2, 0x19, 0x3, 0x2, 0x2, 0x2, 0x2,
0x1b, 0x3, 0x2, 0x2, 0x2, 0x2, 0x1d, 0x3, 0x2, 0x2, 0x2, 0x2, 0x1f,
0x3, 0x2, 0x2, 0x2, 0x2, 0x21, 0x3, 0x2, 0x2, 0x2, 0x2, 0x23, 0x3, 0x2,
0x2, 0x2, 0x2, 0x25, 0x3, 0x2, 0x2, 0x2, 0x2, 0x27, 0x3, 0x2, 0x2, 0x2,
0x2, 0x29, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2b, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2d,
0x3, 0x2, 0x2, 0x2, 0x2, 0x2f, 0x3, 0x2, 0x2, 0x2, 0x2, 0x31, 0x3, 0x2,
0x2, 0x2, 0x2, 0x33, 0x3, 0x2, 0x2, 0x2, 0x2, 0x35, 0x3, 0x2, 0x2, 0x2,
0x2, 0x37, 0x3, 0x2, 0x2, 0x2, 0x2, 0x39, 0x3, 0x2, 0x2, 0x2, 0x2, 0x3b,
0x3, 0x2, 0x2, 0x2, 0x2, 0x3d, 0x3, 0x2, 0x2, 0x2, 0x2, 0x3f, 0x3, 0x2,
0x2, 0x2, 0x2, 0x41, 0x3, 0x2, 0x2, 0x2, 0x2, 0x43, 0x3, 0x2, 0x2, 0x2,
0x2, 0x4d, 0x3, 0x2, 0x2, 0x2, 0x2, 0x4f, 0x3, 0x2, 0x2, 0x2, 0x2, 0x51,
0x3, 0x2, 0x2, 0x2, 0x2, 0x53, 0x3, 0x2, 0x2, 0x2, 0x2, 0x55, 0x3, 0x2,
0x2, 0x2, 0x2, 0x57, 0x3, 0x2, 0x2, 0x2, 0x3, 0x59, 0x3, 0x2, 0x2, 0x2,
0x5, 0x5f, 0x3, 0x2, 0x2, 0x2, 0x7, 0x61, 0x3, 0x2, 0x2, 0x2, 0x9, 0x63,
0x3, 0x2, 0x2, 0x2, 0xb, 0x67, 0x3, 0x2, 0x2, 0x2, 0xd, 0x6d, 0x3, 0x2,
0x2, 0x2, 0xf, 0x6f, 0x3, 0x2, 0x2, 0x2, 0x11, 0x71, 0x3, 0x2, 0x2,
0x2, 0x13, 0x73, 0x3, 0x2, 0x2, 0x2, 0x15, 0x75, 0x3, 0x2, 0x2, 0x2,
0x17, 0x77, 0x3, 0x2, 0x2, 0x2, 0x19, 0x79, 0x3, 0x2, 0x2, 0x2, 0x1b,
0x7b, 0x3, 0x2, 0x2, 0x2, 0x1d, 0x80, 0x3, 0x2, 0x2, 0x2, 0x1f, 0x83,
0x3, 0x2, 0x2, 0x2, 0x21, 0x88, 0x3, 0x2, 0x2, 0x2, 0x23, 0x8e, 0x3,
0x2, 0x2, 0x2, 0x25, 0x94, 0x3, 0x2, 0x2, 0x2, 0x27, 0x9d, 0x3, 0x2,
0x2, 0x2, 0x29, 0xa4, 0x3, 0x2, 0x2, 0x2, 0x2b, 0xa6, 0x3, 0x2, 0x2,
0x2, 0x2d, 0xa8, 0x3, 0x2, 0x2, 0x2, 0x2f, 0xaa, 0x3, 0x2, 0x2, 0x2,
0x31, 0xac, 0x3, 0x2, 0x2, 0x2, 0x33, 0xae, 0x3, 0x2, 0x2, 0x2, 0x35,
0xb0, 0x3, 0x2, 0x2, 0x2, 0x37, 0xb2, 0x3, 0x2, 0x2, 0x2, 0x39, 0xb4,
0x3, 0x2, 0x2, 0x2, 0x3b, 0xb7, 0x3, 0x2, 0x2, 0x2, 0x3d, 0xba, 0x3,
0x2, 0x2, 0x2, 0x3f, 0xbd, 0x3, 0x2, 0x2, 0x2, 0x41, 0xc0, 0x3, 0x2,
0x2, 0x2, 0x43, 0xc3, 0x3, 0x2, 0x2, 0x2, 0x45, 0xc6, 0x3, 0x2, 0x2,
0x2, 0x47, 0xc8, 0x3, 0x2, 0x2, 0x2, 0x49, 0xca, 0x3, 0x2, 0x2, 0x2,
0x4b, 0xd3, 0x3, 0x2, 0x2, 0x2, 0x4d, 0x11c, 0x3, 0x2, 0x2, 0x2, 0x4f,
0x137, 0x3, 0x2, 0x2, 0x2, 0x51, 0x139, 0x3, 0x2, 0x2, 0x2, 0x53, 0x141,
0x3, 0x2, 0x2, 0x2, 0x55, 0x147, 0x3, 0x2, 0x2, 0x2, 0x57, 0x152, 0x3,
0x2, 0x2, 0x2, 0x59, 0x5a, 0x7, 0x65, 0x2, 0x2, 0x5a, 0x5b, 0x7, 0x71,
0x2, 0x2, 0x5b, 0x5c, 0x7, 0x70, 0x2, 0x2, 0x5c, 0x5d, 0x7, 0x75, 0x2,
0x2, 0x5d, 0x5e, 0x7, 0x76, 0x2, 0x2, 0x5e, 0x4, 0x3, 0x2, 0x2, 0x2,
0x5f, 0x60, 0x7, 0x2e, 0x2, 0x2, 0x60, 0x6, 0x3, 0x2, 0x2, 0x2, 0x61,
0x62, 0x7, 0x3d, 0x2, 0x2, 0x62, 0x8, 0x3, 0x2, 0x2, 0x2, 0x63, 0x64,
0x7, 0x6b, 0x2, 0x2, 0x64, 0x65, 0x7, 0x70, 0x2, 0x2, 0x65, 0x66, 0x7,
0x76, 0x2, 0x2, 0x66, 0xa, 0x3, 0x2, 0x2, 0x2, 0x67, 0x68, 0x7, 0x68,
0x2, 0x2, 0x68, 0x69, 0x7, 0x6e, 0x2, 0x2, 0x69, 0x6a, 0x7, 0x71, 0x2,
0x2, 0x6a, 0x6b, 0x7, 0x63, 0x2, 0x2, 0x6b, 0x6c, 0x7, 0x76, 0x2, 0x2,
0x6c, 0xc, 0x3, 0x2, 0x2, 0x2, 0x6d, 0x6e, 0x7, 0x5d, 0x2, 0x2, 0x6e,
0xe, 0x3, 0x2, 0x2, 0x2, 0x6f, 0x70, 0x7, 0x5f, 0x2, 0x2, 0x70, 0x10,
0x3, 0x2, 0x2, 0x2, 0x71, 0x72, 0x7, 0x3f, 0x2, 0x2, 0x72, 0x12, 0x3,
0x2, 0x2, 0x2, 0x73, 0x74, 0x7, 0x7d, 0x2, 0x2, 0x74, 0x14, 0x3, 0x2,
0x2, 0x2, 0x75, 0x76, 0x7, 0x7f, 0x2, 0x2, 0x76, 0x16, 0x3, 0x2, 0x2,
0x2, 0x77, 0x78, 0x7, 0x2a, 0x2, 0x2, 0x78, 0x18, 0x3, 0x2, 0x2, 0x2,
0x79, 0x7a, 0x7, 0x2b, 0x2, 0x2, 0x7a, 0x1a, 0x3, 0x2, 0x2, 0x2, 0x7b,
0x7c, 0x7, 0x78, 0x2, 0x2, 0x7c, 0x7d, 0x7, 0x71, 0x2, 0x2, 0x7d, 0x7e,
0x7, 0x6b, 0x2, 0x2, 0x7e, 0x7f, 0x7, 0x66, 0x2, 0x2, 0x7f, 0x1c, 0x3,
0x2, 0x2, 0x2, 0x80, 0x81, 0x7, 0x6b, 0x2, 0x2, 0x81, 0x82, 0x7, 0x68,
0x2, 0x2, 0x82, 0x1e, 0x3, 0x2, 0x2, 0x2, 0x83, 0x84, 0x7, 0x67, 0x2,
0x2, 0x84, 0x85, 0x7, 0x6e, 0x2, 0x2, 0x85, 0x86, 0x7, 0x75, 0x2, 0x2,
0x86, 0x87, 0x7, 0x67, 0x2, 0x2, 0x87, 0x20, 0x3, 0x2, 0x2, 0x2, 0x88,
0x89, 0x7, 0x79, 0x2, 0x2, 0x89, 0x8a, 0x7, 0x6a, 0x2, 0x2, 0x8a, 0x8b,
0x7, 0x6b, 0x2, 0x2, 0x8b, 0x8c, 0x7, 0x6e, 0x2, 0x2, 0x8c, 0x8d, 0x7,
0x67, 0x2, 0x2, 0x8d, 0x22, 0x3, 0x2, 0x2, 0x2, 0x8e, 0x8f, 0x7, 0x64,
0x2, 0x2, 0x8f, 0x90, 0x7, 0x74, 0x2, 0x2, 0x90, 0x91, 0x7, 0x67, 0x2,
0x2, 0x91, 0x92, 0x7, 0x63, 0x2, 0x2, 0x92, 0x93, 0x7, 0x6d, 0x2, 0x2,
0x93, 0x24, 0x3, 0x2, 0x2, 0x2, 0x94, 0x95, 0x7, 0x65, 0x2, 0x2, 0x95,
0x96, 0x7, 0x71, 0x2, 0x2, 0x96, 0x97, 0x7, 0x70, 0x2, 0x2, 0x97, 0x98,
0x7, 0x76, 0x2, 0x2, 0x98, 0x99, 0x7, 0x6b, 0x2, 0x2, 0x99, 0x9a, 0x7,
0x70, 0x2, 0x2, 0x9a, 0x9b, 0x7, 0x77, 0x2, 0x2, 0x9b, 0x9c, 0x7, 0x67,
0x2, 0x2, 0x9c, 0x26, 0x3, 0x2, 0x2, 0x2, 0x9d, 0x9e, 0x7, 0x74, 0x2,
0x2, 0x9e, 0x9f, 0x7, 0x67, 0x2, 0x2, 0x9f, 0xa0, 0x7, 0x76, 0x2, 0x2,
0xa0, 0xa1, 0x7, 0x77, 0x2, 0x2, 0xa1, 0xa2, 0x7, 0x74, 0x2, 0x2, 0xa2,
0xa3, 0x7, 0x70, 0x2, 0x2, 0xa3, 0x28, 0x3, 0x2, 0x2, 0x2, 0xa4, 0xa5,
0x7, 0x2d, 0x2, 0x2, 0xa5, 0x2a, 0x3, 0x2, 0x2, 0x2, 0xa6, 0xa7, 0x7,
0x2f, 0x2, 0x2, 0xa7, 0x2c, 0x3, 0x2, 0x2, 0x2, 0xa8, 0xa9, 0x7, 0x23,
0x2, 0x2, 0xa9, 0x2e, 0x3, 0x2, 0x2, 0x2, 0xaa, 0xab, 0x7, 0x2c, 0x2,
0x2, 0xab, 0x30, 0x3, 0x2, 0x2, 0x2, 0xac, 0xad, 0x7, 0x31, 0x2, 0x2,
0xad, 0x32, 0x3, 0x2, 0x2, 0x2, 0xae, 0xaf, 0x7, 0x27, 0x2, 0x2, 0xaf,
0x34, 0x3, 0x2, 0x2, 0x2, 0xb0, 0xb1, 0x7, 0x3e, 0x2, 0x2, 0xb1, 0x36,
0x3, 0x2, 0x2, 0x2, 0xb2, 0xb3, 0x7, 0x40, 0x2, 0x2, 0xb3, 0x38, 0x3,
0x2, 0x2, 0x2, 0xb4, 0xb5, 0x7, 0x3e, 0x2, 0x2, 0xb5, 0xb6, 0x7, 0x3f,
0x2, 0x2, 0xb6, 0x3a, 0x3, 0x2, 0x2, 0x2, 0xb7, 0xb8, 0x7, 0x40, 0x2,
0x2, 0xb8, 0xb9, 0x7, 0x3f, 0x2, 0x2, 0xb9, 0x3c, 0x3, 0x2, 0x2, 0x2,
0xba, 0xbb, 0x7, 0x3f, 0x2, 0x2, 0xbb, 0xbc, 0x7, 0x3f, 0x2, 0x2, 0xbc,
0x3e, 0x3, 0x2, 0x2, 0x2, 0xbd, 0xbe, 0x7, 0x23, 0x2, 0x2, 0xbe, 0xbf,
0x7, 0x3f, 0x2, 0x2, 0xbf, 0x40, 0x3, 0x2, 0x2, 0x2, 0xc0, 0xc1, 0x7,
0x28, 0x2, 0x2, 0xc1, 0xc2, 0x7, 0x28, 0x2, 0x2, 0xc2, 0x42, 0x3, 0x2,
0x2, 0x2, 0xc3, 0xc4, 0x7, 0x7e, 0x2, 0x2, 0xc4, 0xc5, 0x7, 0x7e, 0x2,
0x2, 0xc5, 0x44, 0x3, 0x2, 0x2, 0x2, 0xc6, 0xc7, 0x9, 0x2, 0x2, 0x2,
0xc7, 0x46, 0x3, 0x2, 0x2, 0x2, 0xc8, 0xc9, 0x9, 0x3, 0x2, 0x2, 0xc9,
0x48, 0x3, 0x2, 0x2, 0x2, 0xca, 0xcc, 0x9, 0x4, 0x2, 0x2, 0xcb, 0xcd,
0x9, 0x5, 0x2, 0x2, 0xcc, 0xcb, 0x3, 0x2, 0x2, 0x2, 0xcc, 0xcd, 0x3,
0x2, 0x2, 0x2, 0xcd, 0xcf, 0x3, 0x2, 0x2, 0x2, 0xce, 0xd0, 0x5, 0x45,
0x23, 0x2, 0xcf, 0xce, 0x3, 0x2, 0x2, 0x2, 0xd0, 0xd1, 0x3, 0x2, 0x2,
0x2, 0xd1, 0xcf, 0x3, 0x2, 0x2, 0x2, 0xd1, 0xd2, 0x3, 0x2, 0x2, 0x2,
0xd2, 0x4a, 0x3, 0x2, 0x2, 0x2, 0xd3, 0xd5, 0x9, 0x6, 0x2, 0x2, 0xd4,
0xd6, 0x9, 0x5, 0x2, 0x2, 0xd5, 0xd4, 0x3, 0x2, 0x2, 0x2, 0xd5, 0xd6,
0x3, 0x2, 0x2, 0x2, 0xd6, 0xd8, 0x3, 0x2, 0x2, 0x2, 0xd7, 0xd9, 0x5,
0x45, 0x23, 0x2, 0xd8, 0xd7, 0x3, 0x2, 0x2, 0x2, 0xd9, 0xda, 0x3, 0x2,
0x2, 0x2, 0xda, 0xd8, 0x3, 0x2, 0x2, 0x2, 0xda, 0xdb, 0x3, 0x2, 0x2,
0x2, 0xdb, 0x4c, 0x3, 0x2, 0x2, 0x2, 0xdc, 0xdd, 0x7, 0x32, 0x2, 0x2,
0xdd, 0xe1, 0x7, 0x7a, 0x2, 0x2, 0xde, 0xdf, 0x7, 0x32, 0x2, 0x2, 0xdf,
0xe1, 0x7, 0x5a, 0x2, 0x2, 0xe0, 0xdc, 0x3, 0x2, 0x2, 0x2, 0xe0, 0xde,
0x3, 0x2, 0x2, 0x2, 0xe1, 0xf9, 0x3, 0x2, 0x2, 0x2, 0xe2, 0xe4, 0x5,
0x47, 0x24, 0x2, 0xe3, 0xe2, 0x3, 0x2, 0x2, 0x2, 0xe4, 0xe5, 0x3, 0x2,
0x2, 0x2, 0xe5, 0xe3, 0x3, 0x2, 0x2, 0x2, 0xe5, 0xe6, 0x3, 0x2, 0x2,
0x2, 0xe6, 0xe7, 0x3, 0x2, 0x2, 0x2, 0xe7, 0xeb, 0x7, 0x30, 0x2, 0x2,
0xe8, 0xea, 0x5, 0x47, 0x24, 0x2, 0xe9, 0xe8, 0x3, 0x2, 0x2, 0x2, 0xea,
0xed, 0x3, 0x2, 0x2, 0x2, 0xeb, 0xe9, 0x3, 0x2, 0x2, 0x2, 0xeb, 0xec,
0x3, 0x2, 0x2, 0x2, 0xec, 0xfa, 0x3, 0x2, 0x2, 0x2, 0xed, 0xeb, 0x3,
0x2, 0x2, 0x2, 0xee, 0xf0, 0x7, 0x30, 0x2, 0x2, 0xef, 0xf1, 0x5, 0x47,
0x24, 0x2, 0xf0, 0xef, 0x3, 0x2, 0x2, 0x2, 0xf1, 0xf2, 0x3, 0x2, 0x2,
0x2, 0xf2, 0xf0, 0x3, 0x2, 0x2, 0x2, 0xf2, 0xf3, 0x3, 0x2, 0x2, 0x2,
0xf3, 0xfa, 0x3, 0x2, 0x2, 0x2, 0xf4, 0xf6, 0x5, 0x47, 0x24, 0x2, 0xf5,
0xf4, 0x3, 0x2, 0x2, 0x2, 0xf6, 0xf7, 0x3, 0x2, 0x2, 0x2, 0xf7, 0xf5,
0x3, 0x2, 0x2, 0x2, 0xf7, 0xf8, 0x3, 0x2, 0x2, 0x2, 0xf8, 0xfa, 0x3,
0x2, 0x2, 0x2, 0xf9, 0xe3, 0x3, 0x2, 0x2, 0x2, 0xf9, 0xee, 0x3, 0x2,
0x2, 0x2, 0xf9, 0xf5, 0x3, 0x2, 0x2, 0x2, 0xfa, 0xfb, 0x3, 0x2, 0x2,
0x2, 0xfb, 0xfc, 0x5, 0x4b, 0x26, 0x2, 0xfc, 0x11d, 0x3, 0x2, 0x2, 0x2,
0xfd, 0xff, 0x7, 0x30, 0x2, 0x2, 0xfe, 0x100, 0x5, 0x45, 0x23, 0x2,
0xff, 0xfe, 0x3, 0x2, 0x2, 0x2, 0x100, 0x101, 0x3, 0x2, 0x2, 0x2, 0x101,
0xff, 0x3, 0x2, 0x2, 0x2, 0x101, 0x102, 0x3, 0x2, 0x2, 0x2, 0x102, 0x104,
0x3, 0x2, 0x2, 0x2, 0x103, 0x105, 0x5, 0x49, 0x25, 0x2, 0x104, 0x103,
0x3, 0x2, 0x2, 0x2, 0x104, 0x105, 0x3, 0x2, 0x2, 0x2, 0x105, 0x11d,
0x3, 0x2, 0x2, 0x2, 0x106, 0x108, 0x5, 0x45, 0x23, 0x2, 0x107, 0x106,
0x3, 0x2, 0x2, 0x2, 0x108, 0x109, 0x3, 0x2, 0x2, 0x2, 0x109, 0x107,
0x3, 0x2, 0x2, 0x2, 0x109, 0x10a, 0x3, 0x2, 0x2, 0x2, 0x10a, 0x10b,
0x3, 0x2, 0x2, 0x2, 0x10b, 0x10f, 0x7, 0x30, 0x2, 0x2, 0x10c, 0x10e,
0x5, 0x45, 0x23, 0x2, 0x10d, 0x10c, 0x3, 0x2, 0x2, 0x2, 0x10e, 0x111,
0x3, 0x2, 0x2, 0x2, 0x10f, 0x10d, 0x3, 0x2, 0x2, 0x2, 0x10f, 0x110,
0x3, 0x2, 0x2, 0x2, 0x110, 0x113, 0x3, 0x2, 0x2, 0x2, 0x111, 0x10f,
0x3, 0x2, 0x2, 0x2, 0x112, 0x114, 0x5, 0x49, 0x25, 0x2, 0x113, 0x112,
0x3, 0x2, 0x2, 0x2, 0x113, 0x114, 0x3, 0x2, 0x2, 0x2, 0x114, 0x11d,
0x3, 0x2, 0x2, 0x2, 0x115, 0x117, 0x5, 0x45, 0x23, 0x2, 0x116, 0x115,
0x3, 0x2, 0x2, 0x2, 0x117, 0x118, 0x3, 0x2, 0x2, 0x2, 0x118, 0x116,
0x3, 0x2, 0x2, 0x2, 0x118, 0x119, 0x3, 0x2, 0x2, 0x2, 0x119, 0x11a,
0x3, 0x2, 0x2, 0x2, 0x11a, 0x11b, 0x5, 0x49, 0x25, 0x2, 0x11b, 0x11d,
0x3, 0x2, 0x2, 0x2, 0x11c, 0xe0, 0x3, 0x2, 0x2, 0x2, 0x11c, 0xfd, 0x3,
0x2, 0x2, 0x2, 0x11c, 0x107, 0x3, 0x2, 0x2, 0x2, 0x11c, 0x116, 0x3,
0x2, 0x2, 0x2, 0x11d, 0x4e, 0x3, 0x2, 0x2, 0x2, 0x11e, 0x138, 0x7, 0x32,
0x2, 0x2, 0x11f, 0x123, 0x9, 0x7, 0x2, 0x2, 0x120, 0x122, 0x9, 0x2,
0x2, 0x2, 0x121, 0x120, 0x3, 0x2, 0x2, 0x2, 0x122, 0x125, 0x3, 0x2,
0x2, 0x2, 0x123, 0x121, 0x3, 0x2, 0x2, 0x2, 0x123, 0x124, 0x3, 0x2,
0x2, 0x2, 0x124, 0x138, 0x3, 0x2, 0x2, 0x2, 0x125, 0x123, 0x3, 0x2,
0x2, 0x2, 0x126, 0x128, 0x7, 0x32, 0x2, 0x2, 0x127, 0x129, 0x9, 0x8,
0x2, 0x2, 0x128, 0x127, 0x3, 0x2, 0x2, 0x2, 0x129, 0x12a, 0x3, 0x2,
0x2, 0x2, 0x12a, 0x128, 0x3, 0x2, 0x2, 0x2, 0x12a, 0x12b, 0x3, 0x2,
0x2, 0x2, 0x12b, 0x138, 0x3, 0x2, 0x2, 0x2, 0x12c, 0x12d, 0x7, 0x32,
0x2, 0x2, 0x12d, 0x131, 0x7, 0x7a, 0x2, 0x2, 0x12e, 0x12f, 0x7, 0x32,
0x2, 0x2, 0x12f, 0x131, 0x7, 0x5a, 0x2, 0x2, 0x130, 0x12c, 0x3, 0x2,
0x2, 0x2, 0x130, 0x12e, 0x3, 0x2, 0x2, 0x2, 0x131, 0x133, 0x3, 0x2,
0x2, 0x2, 0x132, 0x134, 0x9, 0x3, 0x2, 0x2, 0x133, 0x132, 0x3, 0x2,
0x2, 0x2, 0x134, 0x135, 0x3, 0x2, 0x2, 0x2, 0x135, 0x133, 0x3, 0x2,
0x2, 0x2, 0x135, 0x136, 0x3, 0x2, 0x2, 0x2, 0x136, 0x138, 0x3, 0x2,
0x2, 0x2, 0x137, 0x11e, 0x3, 0x2, 0x2, 0x2, 0x137, 0x11f, 0x3, 0x2,
0x2, 0x2, 0x137, 0x126, 0x3, 0x2, 0x2, 0x2, 0x137, 0x130, 0x3, 0x2,
0x2, 0x2, 0x138, 0x50, 0x3, 0x2, 0x2, 0x2, 0x139, 0x13d, 0x9, 0x9, 0x2,
0x2, 0x13a, 0x13c, 0x9, 0xa, 0x2, 0x2, 0x13b, 0x13a, 0x3, 0x2, 0x2,
0x2, 0x13c, 0x13f, 0x3, 0x2, 0x2, 0x2, 0x13d, 0x13b, 0x3, 0x2, 0x2,
0x2, 0x13d, 0x13e, 0x3, 0x2, 0x2, 0x2, 0x13e, 0x52, 0x3, 0x2, 0x2, 0x2,
0x13f, 0x13d, 0x3, 0x2, 0x2, 0x2, 0x140, 0x142, 0x9, 0xb, 0x2, 0x2,
0x141, 0x140, 0x3, 0x2, 0x2, 0x2, 0x142, 0x143, 0x3, 0x2, 0x2, 0x2,
0x143, 0x141, 0x3, 0x2, 0x2, 0x2, 0x143, 0x144, 0x3, 0x2, 0x2, 0x2,
0x144, 0x145, 0x3, 0x2, 0x2, 0x2, 0x145, 0x146, 0x8, 0x2a, 0x2, 0x2,
0x146, 0x54, 0x3, 0x2, 0x2, 0x2, 0x147, 0x148, 0x7, 0x31, 0x2, 0x2,
0x148, 0x149, 0x7, 0x31, 0x2, 0x2, 0x149, 0x14d, 0x3, 0x2, 0x2, 0x2,
0x14a, 0x14c, 0xa, 0xc, 0x2, 0x2, 0x14b, 0x14a, 0x3, 0x2, 0x2, 0x2,
0x14c, 0x14f, 0x3, 0x2, 0x2, 0x2, 0x14d, 0x14b, 0x3, 0x2, 0x2, 0x2,
0x14d, 0x14e, 0x3, 0x2, 0x2, 0x2, 0x14e, 0x150, 0x3, 0x2, 0x2, 0x2,
0x14f, 0x14d, 0x3, 0x2, 0x2, 0x2, 0x150, 0x151, 0x8, 0x2b, 0x2, 0x2,
0x151, 0x56, 0x3, 0x2, 0x2, 0x2, 0x152, 0x153, 0x7, 0x31, 0x2, 0x2,
0x153, 0x154, 0x7, 0x2c, 0x2, 0x2, 0x154, 0x158, 0x3, 0x2, 0x2, 0x2,
0x155, 0x157, 0xb, 0x2, 0x2, 0x2, 0x156, 0x155, 0x3, 0x2, 0x2, 0x2,
0x157, 0x15a, 0x3, 0x2, 0x2, 0x2, 0x158, 0x159, 0x3, 0x2, 0x2, 0x2,
0x158, 0x156, 0x3, 0x2, 0x2, 0x2, 0x159, 0x15b, 0x3, 0x2, 0x2, 0x2,
0x15a, 0x158, 0x3, 0x2, 0x2, 0x2, 0x15b, 0x15c, 0x7, 0x2c, 0x2, 0x2,
0x15c, 0x15d, 0x7, 0x31, 0x2, 0x2, 0x15d, 0x15e, 0x3, 0x2, 0x2, 0x2,
0x15e, 0x15f, 0x8, 0x2c, 0x2, 0x2, 0x15f, 0x58, 0x3, 0x2, 0x2, 0x2,
0x1d, 0x2, 0xcc, 0xd1, 0xd5, 0xda, 0xe0, 0xe5, 0xeb, 0xf2, 0xf7, 0xf9,
0x101, 0x104, 0x109, 0x10f, 0x113, 0x118, 0x11c, 0x123, 0x12a, 0x130,
0x135, 0x137, 0x13d, 0x143, 0x14d, 0x158, 0x3, 0x8, 0x2, 0x2,
};
atn::ATNDeserializer deserializer;
_atn = deserializer.deserialize(_serializedATN);
size_t count = _atn.getNumberOfDecisions();
_decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
_decisionToDFA.emplace_back(_atn.getDecisionState(i), i);
}
}
SysYLexer::Initializer SysYLexer::_init;

@ -1,62 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#pragma once
#include "antlr4-runtime.h"
class SysYLexer : public antlr4::Lexer {
public:
enum {
T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7,
T__7 = 8, T__8 = 9, T__9 = 10, T__10 = 11, T__11 = 12, T__12 = 13, T__13 = 14,
T__14 = 15, T__15 = 16, T__16 = 17, T__17 = 18, T__18 = 19, T__19 = 20,
T__20 = 21, T__21 = 22, T__22 = 23, T__23 = 24, T__24 = 25, T__25 = 26,
T__26 = 27, T__27 = 28, T__28 = 29, T__29 = 30, T__30 = 31, T__31 = 32,
T__32 = 33, FloatConst = 34, IntConst = 35, Ident = 36, WS = 37, LINE_COMMENT = 38,
BLOCK_COMMENT = 39
};
SysYLexer(antlr4::CharStream *input);
~SysYLexer();
virtual std::string getGrammarFileName() const override;
virtual const std::vector<std::string>& getRuleNames() const override;
virtual const std::vector<std::string>& getChannelNames() const override;
virtual const std::vector<std::string>& getModeNames() const override;
virtual const std::vector<std::string>& getTokenNames() const override; // deprecated, use vocabulary instead
virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
virtual const std::vector<uint16_t> getSerializedATN() const override;
virtual const antlr4::atn::ATN& getATN() const override;
private:
static std::vector<antlr4::dfa::DFA> _decisionToDFA;
static antlr4::atn::PredictionContextCache _sharedContextCache;
static std::vector<std::string> _ruleNames;
static std::vector<std::string> _tokenNames;
static std::vector<std::string> _channelNames;
static std::vector<std::string> _modeNames;
static std::vector<std::string> _literalNames;
static std::vector<std::string> _symbolicNames;
static antlr4::dfa::Vocabulary _vocabulary;
static antlr4::atn::ATN _atn;
static std::vector<uint16_t> _serializedATN;
// Individual action functions triggered by action() above.
// Individual semantic predicate functions triggered by sempred() above.
struct Initializer {
Initializer();
};
static Initializer _init;
};

File diff suppressed because it is too large Load Diff

@ -1,513 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#pragma once
#include "antlr4-runtime.h"
class SysYParser : public antlr4::Parser {
public:
enum {
T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7,
T__7 = 8, T__8 = 9, T__9 = 10, T__10 = 11, T__11 = 12, T__12 = 13, T__13 = 14,
T__14 = 15, T__15 = 16, T__16 = 17, T__17 = 18, T__18 = 19, T__19 = 20,
T__20 = 21, T__21 = 22, T__22 = 23, T__23 = 24, T__24 = 25, T__25 = 26,
T__26 = 27, T__27 = 28, T__28 = 29, T__29 = 30, T__30 = 31, T__31 = 32,
T__32 = 33, FloatConst = 34, IntConst = 35, Ident = 36, WS = 37, LINE_COMMENT = 38,
BLOCK_COMMENT = 39
};
enum {
RuleCompUnit = 0, RuleDecl = 1, RuleConstDecl = 2, RuleBType = 3, RuleConstDef = 4,
RuleConstInitVal = 5, RuleVarDecl = 6, RuleVarDef = 7, RuleInitVal = 8,
RuleFuncDef = 9, RuleFuncType = 10, RuleFuncFParams = 11, RuleFuncFParam = 12,
RuleBlock = 13, RuleBlockItem = 14, RuleStmt = 15, RuleExp = 16, RuleCond = 17,
RuleLVal = 18, RulePrimaryExp = 19, RuleNumber = 20, RuleUnaryExp = 21,
RuleUnaryOp = 22, RuleFuncRParams = 23, RuleMulExp = 24, RuleAddExp = 25,
RuleRelExp = 26, RuleEqExp = 27, RuleLAndExp = 28, RuleLOrExp = 29,
RuleConstExp = 30
};
SysYParser(antlr4::TokenStream *input);
~SysYParser();
virtual std::string getGrammarFileName() const override;
virtual const antlr4::atn::ATN& getATN() const override { return _atn; };
virtual const std::vector<std::string>& getTokenNames() const override { return _tokenNames; }; // deprecated: use vocabulary instead.
virtual const std::vector<std::string>& getRuleNames() const override;
virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
class CompUnitContext;
class DeclContext;
class ConstDeclContext;
class BTypeContext;
class ConstDefContext;
class ConstInitValContext;
class VarDeclContext;
class VarDefContext;
class InitValContext;
class FuncDefContext;
class FuncTypeContext;
class FuncFParamsContext;
class FuncFParamContext;
class BlockContext;
class BlockItemContext;
class StmtContext;
class ExpContext;
class CondContext;
class LValContext;
class PrimaryExpContext;
class NumberContext;
class UnaryExpContext;
class UnaryOpContext;
class FuncRParamsContext;
class MulExpContext;
class AddExpContext;
class RelExpContext;
class EqExpContext;
class LAndExpContext;
class LOrExpContext;
class ConstExpContext;
class CompUnitContext : public antlr4::ParserRuleContext {
public:
CompUnitContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<DeclContext *> decl();
DeclContext* decl(size_t i);
std::vector<FuncDefContext *> funcDef();
FuncDefContext* funcDef(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
CompUnitContext* compUnit();
class DeclContext : public antlr4::ParserRuleContext {
public:
DeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ConstDeclContext *constDecl();
VarDeclContext *varDecl();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
DeclContext* decl();
class ConstDeclContext : public antlr4::ParserRuleContext {
public:
ConstDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
BTypeContext *bType();
std::vector<ConstDefContext *> constDef();
ConstDefContext* constDef(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstDeclContext* constDecl();
class BTypeContext : public antlr4::ParserRuleContext {
public:
BTypeContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BTypeContext* bType();
class ConstDefContext : public antlr4::ParserRuleContext {
public:
ConstDefContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Ident();
ConstInitValContext *constInitVal();
std::vector<ConstExpContext *> constExp();
ConstExpContext* constExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstDefContext* constDef();
class ConstInitValContext : public antlr4::ParserRuleContext {
public:
ConstInitValContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ConstExpContext *constExp();
std::vector<ConstInitValContext *> constInitVal();
ConstInitValContext* constInitVal(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstInitValContext* constInitVal();
class VarDeclContext : public antlr4::ParserRuleContext {
public:
VarDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
BTypeContext *bType();
std::vector<VarDefContext *> varDef();
VarDefContext* varDef(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
VarDeclContext* varDecl();
class VarDefContext : public antlr4::ParserRuleContext {
public:
VarDefContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Ident();
std::vector<ConstExpContext *> constExp();
ConstExpContext* constExp(size_t i);
InitValContext *initVal();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
VarDefContext* varDef();
class InitValContext : public antlr4::ParserRuleContext {
public:
InitValContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ExpContext *exp();
std::vector<InitValContext *> initVal();
InitValContext* initVal(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
InitValContext* initVal();
class FuncDefContext : public antlr4::ParserRuleContext {
public:
FuncDefContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
FuncTypeContext *funcType();
antlr4::tree::TerminalNode *Ident();
BlockContext *block();
FuncFParamsContext *funcFParams();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncDefContext* funcDef();
class FuncTypeContext : public antlr4::ParserRuleContext {
public:
FuncTypeContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncTypeContext* funcType();
class FuncFParamsContext : public antlr4::ParserRuleContext {
public:
FuncFParamsContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<FuncFParamContext *> funcFParam();
FuncFParamContext* funcFParam(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncFParamsContext* funcFParams();
class FuncFParamContext : public antlr4::ParserRuleContext {
public:
FuncFParamContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
BTypeContext *bType();
antlr4::tree::TerminalNode *Ident();
std::vector<ExpContext *> exp();
ExpContext* exp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncFParamContext* funcFParam();
class BlockContext : public antlr4::ParserRuleContext {
public:
BlockContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<BlockItemContext *> blockItem();
BlockItemContext* blockItem(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BlockContext* block();
class BlockItemContext : public antlr4::ParserRuleContext {
public:
BlockItemContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
DeclContext *decl();
StmtContext *stmt();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BlockItemContext* blockItem();
class StmtContext : public antlr4::ParserRuleContext {
public:
StmtContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
LValContext *lVal();
ExpContext *exp();
BlockContext *block();
CondContext *cond();
std::vector<StmtContext *> stmt();
StmtContext* stmt(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
StmtContext* stmt();
class ExpContext : public antlr4::ParserRuleContext {
public:
ExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
AddExpContext *addExp();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ExpContext* exp();
class CondContext : public antlr4::ParserRuleContext {
public:
CondContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
LOrExpContext *lOrExp();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
CondContext* cond();
class LValContext : public antlr4::ParserRuleContext {
public:
LValContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Ident();
std::vector<ExpContext *> exp();
ExpContext* exp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
LValContext* lVal();
class PrimaryExpContext : public antlr4::ParserRuleContext {
public:
PrimaryExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ExpContext *exp();
LValContext *lVal();
NumberContext *number();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
PrimaryExpContext* primaryExp();
class NumberContext : public antlr4::ParserRuleContext {
public:
NumberContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *FloatConst();
antlr4::tree::TerminalNode *IntConst();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
NumberContext* number();
class UnaryExpContext : public antlr4::ParserRuleContext {
public:
UnaryExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
PrimaryExpContext *primaryExp();
antlr4::tree::TerminalNode *Ident();
FuncRParamsContext *funcRParams();
UnaryOpContext *unaryOp();
UnaryExpContext *unaryExp();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
UnaryExpContext* unaryExp();
class UnaryOpContext : public antlr4::ParserRuleContext {
public:
UnaryOpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
UnaryOpContext* unaryOp();
class FuncRParamsContext : public antlr4::ParserRuleContext {
public:
FuncRParamsContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<ExpContext *> exp();
ExpContext* exp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncRParamsContext* funcRParams();
class MulExpContext : public antlr4::ParserRuleContext {
public:
MulExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<UnaryExpContext *> unaryExp();
UnaryExpContext* unaryExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
MulExpContext* mulExp();
class AddExpContext : public antlr4::ParserRuleContext {
public:
AddExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<MulExpContext *> mulExp();
MulExpContext* mulExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
AddExpContext* addExp();
class RelExpContext : public antlr4::ParserRuleContext {
public:
RelExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<AddExpContext *> addExp();
AddExpContext* addExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
RelExpContext* relExp();
class EqExpContext : public antlr4::ParserRuleContext {
public:
EqExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<RelExpContext *> relExp();
RelExpContext* relExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
EqExpContext* eqExp();
class LAndExpContext : public antlr4::ParserRuleContext {
public:
LAndExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<EqExpContext *> eqExp();
EqExpContext* eqExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
LAndExpContext* lAndExp();
class LOrExpContext : public antlr4::ParserRuleContext {
public:
LOrExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<LAndExpContext *> lAndExp();
LAndExpContext* lAndExp(size_t i);
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
LOrExpContext* lOrExp();
class ConstExpContext : public antlr4::ParserRuleContext {
public:
ConstExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
AddExpContext *addExp();
virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstExpContext* constExp();
private:
static std::vector<antlr4::dfa::DFA> _decisionToDFA;
static antlr4::atn::PredictionContextCache _sharedContextCache;
static std::vector<std::string> _ruleNames;
static std::vector<std::string> _tokenNames;
static std::vector<std::string> _literalNames;
static std::vector<std::string> _symbolicNames;
static antlr4::dfa::Vocabulary _vocabulary;
static antlr4::atn::ATN _atn;
static std::vector<uint16_t> _serializedATN;
struct Initializer {
Initializer();
};
static Initializer _init;
};

@ -1,7 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#include "SysYVisitor.h"

@ -1,86 +0,0 @@
// Generated from SysY.g4 by ANTLR 4.7.2
#pragma once
#include "antlr4-runtime.h"
#include "SysYParser.h"
/**
* This class defines an abstract visitor for a parse tree
* produced by SysYParser.
*/
class SysYVisitor : public antlr4::tree::AbstractParseTreeVisitor {
public:
/**
* Visit parse trees produced by SysYParser.
*/
virtual antlrcpp::Any visitCompUnit(SysYParser::CompUnitContext *context) = 0;
virtual antlrcpp::Any visitDecl(SysYParser::DeclContext *context) = 0;
virtual antlrcpp::Any visitConstDecl(SysYParser::ConstDeclContext *context) = 0;
virtual antlrcpp::Any visitBType(SysYParser::BTypeContext *context) = 0;
virtual antlrcpp::Any visitConstDef(SysYParser::ConstDefContext *context) = 0;
virtual antlrcpp::Any visitConstInitVal(SysYParser::ConstInitValContext *context) = 0;
virtual antlrcpp::Any visitVarDecl(SysYParser::VarDeclContext *context) = 0;
virtual antlrcpp::Any visitVarDef(SysYParser::VarDefContext *context) = 0;
virtual antlrcpp::Any visitInitVal(SysYParser::InitValContext *context) = 0;
virtual antlrcpp::Any visitFuncDef(SysYParser::FuncDefContext *context) = 0;
virtual antlrcpp::Any visitFuncType(SysYParser::FuncTypeContext *context) = 0;
virtual antlrcpp::Any visitFuncFParams(SysYParser::FuncFParamsContext *context) = 0;
virtual antlrcpp::Any visitFuncFParam(SysYParser::FuncFParamContext *context) = 0;
virtual antlrcpp::Any visitBlock(SysYParser::BlockContext *context) = 0;
virtual antlrcpp::Any visitBlockItem(SysYParser::BlockItemContext *context) = 0;
virtual antlrcpp::Any visitStmt(SysYParser::StmtContext *context) = 0;
virtual antlrcpp::Any visitExp(SysYParser::ExpContext *context) = 0;
virtual antlrcpp::Any visitCond(SysYParser::CondContext *context) = 0;
virtual antlrcpp::Any visitLVal(SysYParser::LValContext *context) = 0;
virtual antlrcpp::Any visitPrimaryExp(SysYParser::PrimaryExpContext *context) = 0;
virtual antlrcpp::Any visitNumber(SysYParser::NumberContext *context) = 0;
virtual antlrcpp::Any visitUnaryExp(SysYParser::UnaryExpContext *context) = 0;
virtual antlrcpp::Any visitUnaryOp(SysYParser::UnaryOpContext *context) = 0;
virtual antlrcpp::Any visitFuncRParams(SysYParser::FuncRParamsContext *context) = 0;
virtual antlrcpp::Any visitMulExp(SysYParser::MulExpContext *context) = 0;
virtual antlrcpp::Any visitAddExp(SysYParser::AddExpContext *context) = 0;
virtual antlrcpp::Any visitRelExp(SysYParser::RelExpContext *context) = 0;
virtual antlrcpp::Any visitEqExp(SysYParser::EqExpContext *context) = 0;
virtual antlrcpp::Any visitLAndExp(SysYParser::LAndExpContext *context) = 0;
virtual antlrcpp::Any visitLOrExp(SysYParser::LOrExpContext *context) = 0;
virtual antlrcpp::Any visitConstExp(SysYParser::ConstExpContext *context) = 0;
};

@ -10,6 +10,7 @@
#include "ir/IR.h"
#include <utility>
#include <algorithm> // 用于 std::find
namespace ir {
@ -21,7 +22,6 @@ Function* BasicBlock::GetParent() const { return parent_; }
void BasicBlock::SetParent(Function* parent) { parent_ = parent; }
bool BasicBlock::HasTerminator() const {
return !instructions_.empty() && instructions_.back()->IsTerminator();
}
@ -42,4 +42,36 @@ const std::vector<BasicBlock*>& BasicBlock::GetSuccessors() const {
return successors_;
}
} // namespace ir
// 添加前驱基本块(避免重复)
void BasicBlock::AddPredecessor(BasicBlock* pred) {
if (std::find(predecessors_.begin(), predecessors_.end(), pred) ==
predecessors_.end()) {
predecessors_.push_back(pred);
}
}
// 添加后继基本块(避免重复)
void BasicBlock::AddSuccessor(BasicBlock* succ) {
if (std::find(successors_.begin(), successors_.end(), succ) ==
successors_.end()) {
successors_.push_back(succ);
}
}
// 移除前驱基本块
void BasicBlock::RemovePredecessor(BasicBlock* pred) {
auto it = std::find(predecessors_.begin(), predecessors_.end(), pred);
if (it != predecessors_.end()) {
predecessors_.erase(it);
}
}
// 移除后继基本块
void BasicBlock::RemoveSuccessor(BasicBlock* succ) {
auto it = std::find(successors_.begin(), successors_.end(), succ);
if (it != successors_.end()) {
successors_.erase(it);
}
}
} // namespace ir

@ -15,6 +15,14 @@ ConstantInt* Context::GetConstInt(int v) {
return inserted->second.get();
}
ConstantFloat* Context::GetConstFloat(float v) {
auto it = const_floats_.find(v);
if (it != const_floats_.end()) return it->second.get();
auto inserted = const_floats_.emplace(
v, std::make_unique<ConstantFloat>(Type::GetFloat32Type(), v)).first;
return inserted->second.get();
}
std::string Context::NextTemp() {
std::ostringstream oss;
oss << "%" << ++temp_index_;

@ -5,8 +5,11 @@
namespace ir {
Function::Function(std::string name, std::shared_ptr<Type> ret_type)
Function::Function(std::string name, std::shared_ptr<Type> ret_type,
std::vector<std::shared_ptr<Type>> param_types)
: Value(std::move(ret_type), std::move(name)) {
func_type_ = std::static_pointer_cast<FunctionType>(
Type::GetFunctionType(GetType(), std::move(param_types)));
entry_ = CreateBlock("entry");
}
@ -29,4 +32,15 @@ const std::vector<std::unique_ptr<BasicBlock>>& Function::GetBlocks() const {
return blocks_;
}
void Function::AddParam(Value* param) {
if (!param) {
throw std::runtime_error("Function::AddParam cannot add null param");
}
params_.push_back(param);
}
std::shared_ptr<FunctionType> Function::GetFunctionType() const {
return func_type_;
}
} // namespace ir

@ -49,15 +49,35 @@ AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) {
return insert_block_->Append<AllocaInst>(Type::GetPtrInt32Type(), name);
}
AllocaInst* IRBuilder::CreateAllocaFloat(const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<AllocaInst>(Type::GetPointerType(Type::GetFloat32Type()), name);
}
AllocaInst* IRBuilder::CreateAlloca(std::shared_ptr<Type> ty, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!ty || !ty->IsPointer()) {
throw std::runtime_error(FormatError("ir", "CreateAlloca 仅支持指针类型"));
}
return insert_block_->Append<AllocaInst>(ty, name);
}
LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!ptr) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateLoad 缺少 ptr"));
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateLoad 缺少 ptr"));
}
return insert_block_->Append<LoadInst>(Type::GetInt32Type(), ptr, name);
if (!ptr->GetType() || !ptr->GetType()->IsPointer()) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateLoad ptr 必须为指针类型"));
}
const auto* ptr_ty = static_cast<const PointerType*>(ptr->GetType().get());
return insert_block_->Append<LoadInst>(ptr_ty->GetPointeeType(), ptr, name);
}
StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
@ -79,11 +99,78 @@ ReturnInst* IRBuilder::CreateRet(Value* v) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!v) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateRet 缺少返回值"));
}
// ReturnInst expects its own type to be void; the returned value is an
// operand. Always use void as the instruction type.
return insert_block_->Append<ReturnInst>(Type::GetVoidType(), v);
}
BinaryInst* IRBuilder::CreateSub(Value* lhs, Value* rhs, const std::string& name) {
return CreateBinary(Opcode::Sub, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateMul(Value* lhs, Value* rhs, const std::string& name) {
return CreateBinary(Opcode::Mul, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateDiv(Value* lhs, Value* rhs, const std::string& name) {
return CreateBinary(Opcode::Div, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateMod(Value* lhs, Value* rhs, const std::string& name) {
return CreateBinary(Opcode::Mod, lhs, rhs, name);
}
CmpInst* IRBuilder::CreateICmp(CmpInst::Predicate pred, Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<CmpInst>(Opcode::ICmp, pred, lhs, rhs, name);
}
CmpInst* IRBuilder::CreateFCmp(CmpInst::Predicate pred, Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<CmpInst>(Opcode::FCmp, pred, lhs, rhs, name);
}
BranchInst* IRBuilder::CreateBr(BasicBlock* target) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<BranchInst>(target);
}
CondBranchInst* IRBuilder::CreateCondBr(Value* cond, BasicBlock* true_bb, BasicBlock* false_bb) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<CondBranchInst>(cond, true_bb, false_bb);
}
CallInst* IRBuilder::CreateCall(Function* callee, std::vector<Value*> args, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<CallInst>(callee, args, name);
}
GetElementPtrInst* IRBuilder::CreateGEP(Value* ptr, std::vector<Value*> indices, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
// 计算结果类型(简化:假设为指针类型)
auto result_ty = Type::GetPointerType(ptr->GetType());
return insert_block_->Append<GetElementPtrInst>(result_ty, ptr, indices, name);
}
PhiInst* IRBuilder::CreatePhi(std::shared_ptr<Type> ty, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<PhiInst>(ty, name);
}
} // namespace ir

@ -18,28 +18,44 @@ static const char* TypeToString(const Type& ty) {
return "void";
case Type::Kind::Int32:
return "i32";
case Type::Kind::PtrInt32:
return "i32*";
case Type::Kind::Float32:
return "float";
case Type::Kind::Pointer:
return "i32*"; // 目前仅支持 i32* 指针打印
case Type::Kind::Array:
return "[array]";
case Type::Kind::Function:
return "[function]";
case Type::Kind::Label:
return "label";
}
throw std::runtime_error(FormatError("ir", "未知类型"));
}
static const char* OpcodeToString(Opcode op) {
switch (op) {
case Opcode::Add:
return "add";
case Opcode::Sub:
return "sub";
case Opcode::Mul:
return "mul";
case Opcode::Alloca:
return "alloca";
case Opcode::Load:
return "load";
case Opcode::Store:
return "store";
case Opcode::Ret:
return "ret";
case Opcode::Add: return "add";
case Opcode::Sub: return "sub";
case Opcode::Mul: return "mul";
case Opcode::Div: return "sdiv";
case Opcode::Mod: return "srem";
case Opcode::And: return "and";
case Opcode::Or: return "or";
case Opcode::Xor: return "xor";
case Opcode::Shl: return "shl";
case Opcode::LShr: return "lshr";
case Opcode::AShr: return "ashr";
case Opcode::ICmp: return "icmp";
case Opcode::FCmp: return "fcmp";
case Opcode::Alloca: return "alloca";
case Opcode::Load: return "load";
case Opcode::Store: return "store";
case Opcode::Ret: return "ret";
case Opcode::Br: return "br";
case Opcode::CondBr: return "br";
case Opcode::Call: return "call";
case Opcode::GEP: return "getelementptr";
case Opcode::Phi: return "phi";
}
return "?";
}
@ -65,7 +81,15 @@ 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::Or:
case Opcode::Xor:
case Opcode::Shl:
case Opcode::LShr:
case Opcode::AShr: {
auto* bin = static_cast<const BinaryInst*>(inst);
os << " " << bin->GetName() << " = "
<< OpcodeToString(bin->GetOpcode()) << " "
@ -74,21 +98,36 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
<< ValueToString(bin->GetRhs()) << "\n";
break;
}
case Opcode::ICmp:
case Opcode::FCmp: {
auto* cmp = static_cast<const CmpInst*>(inst);
os << " " << cmp->GetName() << " = "
<< OpcodeToString(cmp->GetOpcode()) << " eq "
<< TypeToString(*cmp->GetLhs()->GetType()) << " "
<< ValueToString(cmp->GetLhs()) << ", "
<< ValueToString(cmp->GetRhs()) << "\n";
break;
}
case Opcode::Alloca: {
auto* alloca = static_cast<const AllocaInst*>(inst);
os << " " << alloca->GetName() << " = alloca i32\n";
os << " " << alloca->GetName() << " = alloca "
<< TypeToString(*static_cast<const PointerType*>(alloca->GetType().get())->GetPointeeType()) << "\n";
break;
}
case Opcode::Load: {
auto* load = static_cast<const LoadInst*>(inst);
os << " " << load->GetName() << " = load i32, i32* "
os << " " << load->GetName() << " = load "
<< TypeToString(*load->GetType()) << ", "
<< TypeToString(*load->GetPtr()->GetType()) << " "
<< ValueToString(load->GetPtr()) << "\n";
break;
}
case Opcode::Store: {
auto* store = static_cast<const StoreInst*>(inst);
os << " store i32 " << ValueToString(store->GetValue())
<< ", i32* " << ValueToString(store->GetPtr()) << "\n";
os << " store " << TypeToString(*store->GetValue()->GetType()) << " "
<< ValueToString(store->GetValue()) << ", "
<< TypeToString(*store->GetPtr()->GetType()) << " "
<< ValueToString(store->GetPtr()) << "\n";
break;
}
case Opcode::Ret: {
@ -97,6 +136,56 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
<< ValueToString(ret->GetValue()) << "\n";
break;
}
case Opcode::Br: {
auto* br = static_cast<const BranchInst*>(inst);
os << " br label %" << br->GetTarget()->GetName() << "\n";
break;
}
case Opcode::CondBr: {
auto* condbr = static_cast<const CondBranchInst*>(inst);
os << " br i1 " << ValueToString(condbr->GetCond())
<< ", label %" << condbr->GetTrueBlock()->GetName()
<< ", label %" << condbr->GetFalseBlock()->GetName() << "\n";
break;
}
case Opcode::Call: {
auto* call = static_cast<const CallInst*>(inst);
os << " ";
if (!call->GetName().empty()) {
os << call->GetName() << " = ";
}
os << "call " << TypeToString(*call->GetCallee()->GetType()) << " @"
<< call->GetCallee()->GetName() << "(";
for (size_t i = 0; i < call->GetArgs().size(); ++i) {
if (i > 0) os << ", ";
os << TypeToString(*call->GetArgs()[i]->GetType()) << " "
<< ValueToString(call->GetArgs()[i]);
}
os << ")\n";
break;
}
case Opcode::GEP: {
auto* gep = static_cast<const GetElementPtrInst*>(inst);
os << " " << gep->GetName() << " = getelementptr "
<< TypeToString(*gep->GetPtr()->GetType()) << " "
<< ValueToString(gep->GetPtr());
for (auto* idx : gep->GetIndices()) {
os << ", " << TypeToString(*idx->GetType()) << " " << ValueToString(idx);
}
os << "\n";
break;
}
case Opcode::Phi: {
auto* phi = static_cast<const PhiInst*>(inst);
os << " " << phi->GetName() << " = phi "
<< TypeToString(*phi->GetType());
for (const auto& incoming : phi->GetIncomings()) {
os << " [ " << ValueToString(incoming.first) << ", %"
<< incoming.second->GetName() << " ]";
}
os << "\n";
break;
}
}
}
}

@ -52,7 +52,9 @@ Instruction::Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name)
Opcode Instruction::GetOpcode() const { return opcode_; }
bool Instruction::IsTerminator() const { return opcode_ == Opcode::Ret; }
bool Instruction::IsTerminator() const {
return opcode_ == Opcode::Ret || opcode_ == Opcode::Br || opcode_ == Opcode::CondBr;
}
BasicBlock* Instruction::GetParent() const { return parent_; }
@ -87,21 +89,22 @@ Value* BinaryInst::GetRhs() const { return GetOperand(1); }
ReturnInst::ReturnInst(std::shared_ptr<Type> void_ty, Value* val)
: Instruction(Opcode::Ret, std::move(void_ty), "") {
if (!val) {
throw std::runtime_error(FormatError("ir", "ReturnInst 缺少返回值"));
}
if (!type_ || !type_->IsVoid()) {
throw std::runtime_error(FormatError("ir", "ReturnInst 返回类型必须为 void"));
}
AddOperand(val);
// val may be nullptr to represent a void return; only add operand when
// a returned value is present.
if (val) {
AddOperand(val);
}
}
Value* ReturnInst::GetValue() const { return GetOperand(0); }
AllocaInst::AllocaInst(std::shared_ptr<Type> ptr_ty, std::string name)
: Instruction(Opcode::Alloca, std::move(ptr_ty), std::move(name)) {
if (!type_ || !type_->IsPtrInt32()) {
throw std::runtime_error(FormatError("ir", "AllocaInst 当前只支持 i32*"));
if (!type_ || !type_->IsPointer()) {
throw std::runtime_error(FormatError("ir", "AllocaInst 类型必须为指针"));
}
}
@ -110,12 +113,12 @@ LoadInst::LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name)
if (!ptr) {
throw std::runtime_error(FormatError("ir", "LoadInst 缺少 ptr"));
}
if (!type_ || !type_->IsInt32()) {
throw std::runtime_error(FormatError("ir", "LoadInst 当前只支持加载 i32"));
if (!ptr->GetType() || !ptr->GetType()->IsPointer()) {
throw std::runtime_error(FormatError("ir", "LoadInst ptr 必须为指针类型"));
}
if (!ptr->GetType() || !ptr->GetType()->IsPtrInt32()) {
throw std::runtime_error(
FormatError("ir", "LoadInst 当前只支持从 i32* 加载"));
const auto* ptr_ty = static_cast<const PointerType*>(ptr->GetType().get());
if (!type_ || *type_ != *ptr_ty->GetPointeeType()) {
throw std::runtime_error(FormatError("ir", "LoadInst 类型不匹配"));
}
AddOperand(ptr);
}
@ -133,12 +136,12 @@ StoreInst::StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr)
if (!type_ || !type_->IsVoid()) {
throw std::runtime_error(FormatError("ir", "StoreInst 返回类型必须为 void"));
}
if (!val->GetType() || !val->GetType()->IsInt32()) {
throw std::runtime_error(FormatError("ir", "StoreInst 当前只支持存储 i32"));
if (!ptr->GetType() || !ptr->GetType()->IsPointer()) {
throw std::runtime_error(FormatError("ir", "StoreInst ptr 必须为指针类型"));
}
if (!ptr->GetType() || !ptr->GetType()->IsPtrInt32()) {
throw std::runtime_error(
FormatError("ir", "StoreInst 当前只支持写入 i32*"));
const auto* ptr_ty = static_cast<const PointerType*>(ptr->GetType().get());
if (!val->GetType() || *val->GetType() != *ptr_ty->GetPointeeType()) {
throw std::runtime_error(FormatError("ir", "StoreInst 类型不匹配"));
}
AddOperand(val);
AddOperand(ptr);
@ -148,4 +151,120 @@ Value* StoreInst::GetValue() const { return GetOperand(0); }
Value* StoreInst::GetPtr() const { return GetOperand(1); }
CmpInst::CmpInst(Opcode op, Predicate pred, Value* lhs, Value* rhs, std::string name)
: Instruction(op, Type::GetInt32Type(), std::move(name)), pred_(pred), lhs_(lhs), rhs_(rhs) {
if (op != Opcode::ICmp && op != Opcode::FCmp) {
throw std::runtime_error(FormatError("ir", "CmpInst 仅支持 ICmp 和 FCmp"));
}
if (!lhs || !rhs) {
throw std::runtime_error(FormatError("ir", "CmpInst 缺少操作数"));
}
AddOperand(lhs);
AddOperand(rhs);
}
BranchInst::BranchInst(BasicBlock* target)
: Instruction(Opcode::Br, Type::GetVoidType(), "") {
if (!target) {
throw std::runtime_error(FormatError("ir", "BranchInst 缺少目标基本块"));
}
AddOperand(target);
}
BasicBlock* BranchInst::GetTarget() const { return static_cast<BasicBlock*>(GetOperand(0)); }
CondBranchInst::CondBranchInst(Value* cond, BasicBlock* true_bb, BasicBlock* false_bb)
: Instruction(Opcode::CondBr, Type::GetVoidType(), "") {
if (!cond || !true_bb || !false_bb) {
throw std::runtime_error(FormatError("ir", "CondBranchInst 缺少操作数"));
}
AddOperand(cond);
AddOperand(true_bb);
AddOperand(false_bb);
}
Value* CondBranchInst::GetCond() const { return GetOperand(0); }
BasicBlock* CondBranchInst::GetTrueBlock() const { return static_cast<BasicBlock*>(GetOperand(1)); }
BasicBlock* CondBranchInst::GetFalseBlock() const { return static_cast<BasicBlock*>(GetOperand(2)); }
CallInst::CallInst(Function* callee, std::vector<Value*> args, std::string name)
: Instruction(Opcode::Call, callee->GetType(), std::move(name)) {
if (!callee) {
throw std::runtime_error(FormatError("ir", "CallInst 缺少被调用函数"));
}
AddOperand(callee);
for (auto* arg : args) {
if (!arg) {
throw std::runtime_error(FormatError("ir", "CallInst 参数不能为空"));
}
AddOperand(arg);
}
}
PhiInst::PhiInst(std::shared_ptr<Type> ty, std::string name)
: Instruction(Opcode::Phi, std::move(ty), std::move(name)) {}
void PhiInst::AddIncoming(Value* val, BasicBlock* block) {
if (!val || !block) {
throw std::runtime_error(FormatError("ir", "PhiInst AddIncoming 参数不能为空"));
}
AddOperand(val);
AddOperand(block);
}
GetElementPtrInst::GetElementPtrInst(std::shared_ptr<Type> ty, Value* ptr,
std::vector<Value*> indices, std::string name)
: Instruction(Opcode::GEP, std::move(ty), std::move(name)) {
if (!ptr) {
throw std::runtime_error(FormatError("ir", "GetElementPtrInst 缺少指针"));
}
AddOperand(ptr);
for (auto* idx : indices) {
if (!idx) {
throw std::runtime_error(FormatError("ir", "GetElementPtrInst 索引不能为空"));
}
AddOperand(idx);
}
}
Function* CallInst::GetCallee() const {
return static_cast<Function*>(GetOperand(0));
}
const std::vector<Value*>& CallInst::GetArgs() const {
// 返回参数列表(跳过被调用函数)
static std::vector<Value*> args;
args.clear();
for (size_t i = 1; i < GetNumOperands(); ++i) {
args.push_back(GetOperand(i));
}
return args;
}
const std::vector<std::pair<Value*, BasicBlock*>>& PhiInst::GetIncomings() const {
// Phi 指令的操作数是成对的:值和基本块
static std::vector<std::pair<Value*, BasicBlock*>> incomings;
incomings.clear();
for (size_t i = 0; i < GetNumOperands(); i += 2) {
Value* val = GetOperand(i);
BasicBlock* block = static_cast<BasicBlock*>(GetOperand(i + 1));
incomings.emplace_back(val, block);
}
return incomings;
}
Value* GetElementPtrInst::GetPtr() const {
return GetOperand(0);
}
const std::vector<Value*>& GetElementPtrInst::GetIndices() const {
// 返回索引列表(跳过指针)
static std::vector<Value*> indices;
indices.clear();
for (size_t i = 1; i < GetNumOperands(); ++i) {
indices.push_back(GetOperand(i));
}
return indices;
}
} // namespace ir

@ -9,13 +9,30 @@ Context& Module::GetContext() { return context_; }
const Context& Module::GetContext() const { return context_; }
Function* Module::CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type) {
functions_.push_back(std::make_unique<Function>(name, std::move(ret_type)));
std::shared_ptr<Type> ret_type,
std::vector<std::shared_ptr<Type>> param_types) {
functions_.push_back(
std::make_unique<Function>(name, std::move(ret_type), std::move(param_types)));
return functions_.back().get();
}
GlobalValue* Module::CreateGlobalVariable(const std::string& name,
std::shared_ptr<Type> ty,
ConstantValue* init) {
auto gv = std::make_unique<GlobalValue>(std::move(ty), name);
if (init) {
gv->SetInitializer(init);
}
global_vars_.push_back(std::move(gv));
return global_vars_.back().get();
}
const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
return functions_;
}
const std::vector<std::unique_ptr<GlobalValue>>& Module::GetGlobalVariables() const {
return global_vars_;
}
} // namespace ir

@ -1,8 +1,20 @@
// 当前仅支持 void、i32 和 i32*。
#include "ir/IR.h"
#include <unordered_map>
#include <functional>
namespace ir {
// 用于缓存复合类型的静态映射(简单实现)
static std::unordered_map<std::size_t, std::shared_ptr<Type>> pointer_cache;
static std::unordered_map<std::size_t, std::shared_ptr<Type>> array_cache;
static std::unordered_map<std::size_t, std::shared_ptr<Type>> function_cache;
// 简单哈希组合函数
static std::size_t hash_combine(std::size_t seed, std::size_t v) {
return seed ^ (v + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
Type::Type(Kind k) : kind_(k) {}
const std::shared_ptr<Type>& Type::GetVoidType() {
@ -15,17 +27,133 @@ const std::shared_ptr<Type>& Type::GetInt32Type() {
return type;
}
const std::shared_ptr<Type>& Type::GetFloat32Type() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Float32);
return type;
}
const std::shared_ptr<Type>& Type::GetLabelType() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Label);
return type;
}
// 兼容旧的 i32* 类型,返回指向 i32 的指针类型
const std::shared_ptr<Type>& Type::GetPtrInt32Type() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::PtrInt32);
static const std::shared_ptr<Type> type = GetPointerType(GetInt32Type());
return type;
}
std::shared_ptr<Type> Type::GetPointerType(std::shared_ptr<Type> pointee) {
// 简单缓存:使用 pointee 的地址作为键(实际应使用更可靠的标识,但作为演示足够)
std::size_t key = reinterpret_cast<std::size_t>(pointee.get());
auto it = pointer_cache.find(key);
if (it != pointer_cache.end()) {
return it->second;
}
auto ptr_type = std::make_shared<PointerType>(pointee);
pointer_cache[key] = ptr_type;
return ptr_type;
}
std::shared_ptr<Type> Type::GetArrayType(std::shared_ptr<Type> elem, size_t size) {
// 使用元素类型指针和大小组合哈希
std::size_t seed = 0;
seed = hash_combine(seed, reinterpret_cast<std::size_t>(elem.get()));
seed = hash_combine(seed, size);
auto it = array_cache.find(seed);
if (it != array_cache.end()) {
return it->second;
}
auto arr_type = std::make_shared<ArrayType>(elem, size);
array_cache[seed] = arr_type;
return arr_type;
}
std::shared_ptr<Type> Type::GetFunctionType(std::shared_ptr<Type> ret,
std::vector<std::shared_ptr<Type>> params) {
// 哈希组合:返回类型 + 参数类型列表
std::size_t seed = reinterpret_cast<std::size_t>(ret.get());
for (const auto& p : params) {
seed = hash_combine(seed, reinterpret_cast<std::size_t>(p.get()));
}
auto it = function_cache.find(seed);
if (it != function_cache.end()) {
return it->second;
}
auto func_type = std::make_shared<FunctionType>(ret, std::move(params));
function_cache[seed] = func_type;
return func_type;
}
Type::Kind Type::GetKind() const { return kind_; }
bool Type::IsVoid() const { return kind_ == Kind::Void; }
bool Type::IsInt32() const { return kind_ == Kind::Int32; }
bool Type::IsPtrInt32() const { return kind_ == Kind::PtrInt32; }
bool Type::IsFloat32() const { return kind_ == Kind::Float32; }
bool Type::IsPointer() const { return kind_ == Kind::Pointer; }
bool Type::IsArray() const { return kind_ == Kind::Array; }
bool Type::IsFunction() const { return kind_ == Kind::Function; }
bool Type::IsLabel() const { return kind_ == Kind::Label; }
// 兼容旧代码,检查是否为 i32* 类型
bool Type::IsPtrInt32() const {
if (!IsPointer()) return false;
const auto* ptr_ty = static_cast<const PointerType*>(this);
return ptr_ty->GetPointeeType()->IsInt32();
}
// 检查是否为 float32* 类型
bool Type::IsPtrFloat32() const {
if (!IsPointer()) return false;
const auto* ptr_ty = static_cast<const PointerType*>(this);
return ptr_ty->GetPointeeType()->IsFloat32();
}
bool Type::operator==(const Type& other) const {
if (kind_ != other.kind_) return false;
switch (kind_) {
case Kind::Void:
case Kind::Int32:
case Kind::Float32:
case Kind::Label:
return true;
case Kind::Pointer: {
const auto* this_ptr = static_cast<const PointerType*>(this);
const auto* other_ptr = static_cast<const PointerType*>(&other);
return *this_ptr->GetPointeeType() == *other_ptr->GetPointeeType();
}
case Kind::Array: {
const auto* this_arr = static_cast<const ArrayType*>(this);
const auto* other_arr = static_cast<const ArrayType*>(&other);
return this_arr->GetSize() == other_arr->GetSize() &&
*this_arr->GetElementType() == *other_arr->GetElementType();
}
case Kind::Function: {
const auto* this_func = static_cast<const FunctionType*>(this);
const auto* other_func = static_cast<const FunctionType*>(&other);
if (*this_func->GetReturnType() != *other_func->GetReturnType()) return false;
const auto& this_params = this_func->GetParamTypes();
const auto& other_params = other_func->GetParamTypes();
if (this_params.size() != other_params.size()) return false;
for (size_t i = 0; i < this_params.size(); ++i) {
if (*this_params[i] != *other_params[i]) return false;
}
return true;
}
default:
return false;
}
}
bool Type::operator!=(const Type& other) const {
return !(*this == other);
}
} // namespace ir
} // namespace ir

@ -20,7 +20,19 @@ bool Value::IsVoid() const { return type_ && type_->IsVoid(); }
bool Value::IsInt32() const { return type_ && type_->IsInt32(); }
bool Value::IsPtrInt32() const { return type_ && type_->IsPtrInt32(); }
bool Value::IsPtrInt32() const {
if (!type_ || !type_->IsPointer()) return false;
const auto* ptr_ty = static_cast<const PointerType*>(type_.get());
return ptr_ty->GetPointeeType()->IsInt32();
}
bool Value::IsPtrFloat32() const {
if (!type_ || !type_->IsPointer()) return false;
const auto* ptr_ty = static_cast<const PointerType*>(type_.get());
return ptr_ty->GetPointeeType()->IsFloat32();
}
bool Value::IsFloat32() const { return type_ && type_->IsFloat32(); }
bool Value::IsConstant() const {
return dynamic_cast<const ConstantValue*>(this) != nullptr;
@ -38,6 +50,10 @@ bool Value::IsFunction() const {
return dynamic_cast<const Function*>(this) != nullptr;
}
bool Value::IsGlobalValue() const {
return dynamic_cast<const GlobalValue*>(this) != nullptr;
}
void Value::AddUse(User* user, size_t operand_index) {
if (!user) return;
uses_.push_back(Use(this, user, operand_index));
@ -80,4 +96,11 @@ ConstantValue::ConstantValue(std::shared_ptr<Type> ty, std::string name)
ConstantInt::ConstantInt(std::shared_ptr<Type> ty, int v)
: ConstantValue(std::move(ty), ""), value_(v) {}
ConstantFloat::ConstantFloat(std::shared_ptr<Type> ty, float v)
: ConstantValue(std::move(ty), ""), value_(v) {}
ConstantArray::ConstantArray(std::shared_ptr<Type> ty,
std::vector<ConstantValue*> elems)
: ConstantValue(std::move(ty), ""), elements_(std::move(elems)) {}
} // namespace ir

@ -6,25 +6,15 @@
#include "ir/IR.h"
#include "utils/Log.h"
namespace {
// helper functions removed; VarDef uses Ident() directly per current grammar.
std::string GetLValueName(SysYParser::LValueContext& lvalue) {
if (!lvalue.ID()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
return lvalue.ID()->getText();
}
} // namespace
std::any IRGenImpl::visitBlockStmt(SysYParser::BlockStmtContext* ctx) {
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
// 当前语法要求 return 为块内最后一条语句;命中后可停止生成。
break;
}
}
@ -63,15 +53,17 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
}
if (!ctx->btype() || !ctx->btype()->INT()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持局部 int 变量声明"));
}
auto* var_def = ctx->varDef();
if (!var_def) {
throw std::runtime_error(FormatError("irgen", "非法变量声明"));
if (ctx->varDecl()) {
auto* vdecl = ctx->varDecl();
if (!vdecl->bType() || vdecl->bType()->getText() != "int") {
throw std::runtime_error(FormatError("irgen", "当前仅支持局部 int 变量声明"));
}
for (auto* var_def : vdecl->varDef()) {
if (var_def) var_def->accept(this);
}
return {};
}
var_def->accept(this);
return {};
throw std::runtime_error(FormatError("irgen", "暂不支持的声明类型"));
}
@ -83,10 +75,9 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
}
if (!ctx->lValue()) {
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
GetLValueName(*ctx->lValue());
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
}
@ -94,7 +85,7 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
if (auto* init_value = ctx->initValue()) {
if (auto* init_value = ctx->initVal()) {
if (!init_value->exp()) {
throw std::runtime_error(FormatError("irgen", "当前不支持聚合初始化"));
}

@ -7,7 +7,7 @@
#include "utils/Log.h"
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema) {
IRGenContext& sema) {
auto module = std::make_unique<ir::Module>();
IRGenImpl gen(*module, sema);
tree.accept(&gen);

@ -25,20 +25,21 @@ ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
}
std::any IRGenImpl::visitParenExp(SysYParser::ParenExpContext* ctx) {
if (!ctx || !ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "非法括号表达式"));
}
return EvalExpr(*ctx->exp());
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法 primary 表达式"));
if (ctx->exp()) return EvalExpr(*ctx->exp());
if (ctx->lVal()) return ctx->lVal()->accept(this);
if (ctx->number()) return ctx->number()->accept(this);
throw std::runtime_error(FormatError("irgen", "不支持的 primary 表达式"));
}
std::any IRGenImpl::visitNumberExp(SysYParser::NumberExpContext* ctx) {
if (!ctx || !ctx->number() || !ctx->number()->ILITERAL()) {
std::any IRGenImpl::visitNumber(SysYParser::NumberContext* ctx) {
if (!ctx || !ctx->IntConst()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持整数字面量"));
}
return static_cast<ir::Value*>(
builder_.CreateConstInt(std::stoi(ctx->number()->getText())));
builder_.CreateConstInt(std::stoi(ctx->getText())));
}
// 变量使用的处理流程:
@ -47,33 +48,30 @@ std::any IRGenImpl::visitNumberExp(SysYParser::NumberExpContext* ctx) {
// 3. 最后生成 load把内存中的值读出来。
//
// 因此当前 IRGen 自己不再做名字查找,而是直接消费 Sema 的绑定结果。
std::any IRGenImpl::visitVarExp(SysYParser::VarExpContext* ctx) {
if (!ctx || !ctx->var() || !ctx->var()->ID()) {
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量"));
}
auto* decl = sema_.ResolveVarUse(ctx->var());
if (!decl) {
throw std::runtime_error(
FormatError("irgen",
"变量使用缺少语义绑定: " + ctx->var()->ID()->getText()));
}
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen",
"变量声明缺少存储槽位: " + ctx->var()->ID()->getText()));
// find storage by matching declaration node stored in Sema context
// Sema stores types/decl contexts in IRGenContext maps; here we search storage_map_ by name
std::string name = ctx->Ident()->getText();
for (auto& kv : storage_map_) {
// kv.first is VarDefContext*, try to get Ident text
if (kv.first && kv.first->Ident() && kv.first->Ident()->getText() == name) {
return static_cast<ir::Value*>(
builder_.CreateLoad(kv.second, module_.GetContext().NextTemp()));
}
}
return static_cast<ir::Value*>(
builder_.CreateLoad(it->second, module_.GetContext().NextTemp()));
throw std::runtime_error(FormatError("irgen", "变量声明缺少存储槽位: " + name));
}
std::any IRGenImpl::visitAdditiveExp(SysYParser::AdditiveExpContext* ctx) {
if (!ctx || !ctx->exp(0) || !ctx->exp(1)) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
ir::Value* lhs = EvalExpr(*ctx->exp(0));
ir::Value* rhs = EvalExpr(*ctx->exp(1));
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
// left-associative: evaluate first two mulExp as a simple binary add
if (ctx->mulExp().size() == 1) return ctx->mulExp(0)->accept(this);
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->mulExp(0)->accept(this));
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->mulExp(1)->accept(this));
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Add, lhs, rhs,
module_.GetContext().NextTemp()));

@ -21,7 +21,7 @@ void VerifyFunctionStructure(const ir::Function& func) {
} // namespace
IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
IRGenImpl::IRGenImpl(ir::Module& module, IRGenContext& sema)
: module_(module),
sema_(sema),
func_(nullptr),
@ -38,11 +38,11 @@ std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少编译单元"));
}
auto* func = ctx->funcDef();
if (!func) {
// for simplicity take first function definition
if (ctx->funcDef().empty()) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
}
func->accept(this);
ctx->funcDef(0)->accept(this);
return {};
}
@ -66,21 +66,21 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
}
if (!ctx->blockStmt()) {
if (!ctx->block()) {
throw std::runtime_error(FormatError("irgen", "函数体为空"));
}
if (!ctx->ID()) {
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "缺少函数名"));
}
if (!ctx->funcType() || !ctx->funcType()->INT()) {
if (!ctx->funcType() || ctx->funcType()->getText() != "int") {
throw std::runtime_error(FormatError("irgen", "当前仅支持无参 int 函数"));
}
func_ = module_.CreateFunction(ctx->ID()->getText(), ir::Type::GetInt32Type());
func_ = module_.CreateFunction(ctx->Ident()->getText(), ir::Type::GetInt32Type());
builder_.SetInsertPoint(func_->GetEntry());
storage_map_.clear();
ctx->blockStmt()->accept(this);
ctx->block()->accept(this);
// 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。
VerifyFunctionStructure(*func_);
return {};

@ -19,21 +19,16 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句"));
}
if (ctx->returnStmt()) {
return ctx->returnStmt()->accept(this);
// stmt can be many forms; handle return specifically
if (!ctx->getText().empty() && ctx->getText().find("return") != std::string::npos) {
if (ctx->exp()) {
ir::Value* v = EvalExpr(*ctx->exp());
builder_.CreateRet(v);
} else {
builder_.CreateRet(nullptr);
}
return BlockFlow::Terminated;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
std::any IRGenImpl::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
}
if (!ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "return 缺少表达式"));
}
ir::Value* v = EvalExpr(*ctx->exp());
builder_.CreateRet(v);
return BlockFlow::Terminated;
}

@ -1,5 +1,5 @@
#include "../../include/sem/Sema.h"
#include "../../generated/antlr4/SysYParser.h"
#include "SysYParser.h"
#include <stdexcept>
#include <algorithm>
#include <iostream>
@ -437,4 +437,10 @@ void RunSemanticAnalysis(SysYParser::CompUnitContext* ctx, IRGenContext& ir_ctx)
}
SemaVisitor visitor(ir_ctx);
visitor.visit(ctx);
}
IRGenContext RunSema(SysYParser::CompUnitContext& ctx) {
IRGenContext ctx_obj;
RunSemanticAnalysis(&ctx, ctx_obj);
return ctx_obj;
}
Loading…
Cancel
Save