add file
This commit is contained in:
@@ -112,6 +112,8 @@ doxygen doc/Doxyfile
|
|||||||
|
|
||||||
上述命令执行完毕后,将在doxygen/html下找到生成的代码文档。
|
上述命令执行完毕后,将在doxygen/html下找到生成的代码文档。
|
||||||
|
|
||||||
|
该版本还未实现数组初始化定义等功能
|
||||||
|
|
||||||
## 实验3:从SysY IR 生成ARMv7汇编代码
|
## 实验3:从SysY IR 生成ARMv7汇编代码
|
||||||
|
|
||||||
### 后端相关源码
|
### 后端相关源码
|
||||||
|
|||||||
169
doc/markdowns/IR.md
Normal file
169
doc/markdowns/IR.md
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
这个头文件定义了一个用于生成中间表示(IR)的数据结构,主要用于编译器前端将抽象语法树(AST)转换为中间代码。以下是文件中定义的主要类和功能的整理和解释:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **1. 类型系统(Type System)**
|
||||||
|
#### **1.1 `Type` 类**
|
||||||
|
- **作用**:表示所有基本标量类型(如 `int`、`float`、`void` 等)以及指针类型和函数类型。
|
||||||
|
- **成员**:
|
||||||
|
- `Kind` 枚举:表示类型的种类(如 `kInt`、`kFloat`、`kPointer` 等)。
|
||||||
|
- `kind`:当前类型的种类。
|
||||||
|
- 构造函数:`Type(Kind kind)`,用于初始化类型。
|
||||||
|
- 静态方法:如 `getIntType()`、`getFloatType()` 等,用于获取特定类型的单例对象。
|
||||||
|
- 类型检查方法:如 `isInt()`、`isFloat()` 等,用于检查当前类型是否为某种类型。
|
||||||
|
- `getSize()`:获取类型的大小。
|
||||||
|
- `as<T>()`:将当前类型动态转换为派生类(如 `PointerType` 或 `FunctionType`)。
|
||||||
|
|
||||||
|
#### **1.2 `PointerType` 类**
|
||||||
|
- **作用**:表示指针类型,派生自 `Type`。
|
||||||
|
- **成员**:
|
||||||
|
- `baseType`:指针指向的基础类型。
|
||||||
|
- 静态方法:`get(Type *baseType)`,用于获取指向 `baseType` 的指针类型。
|
||||||
|
- `getBaseType()`:获取指针指向的基础类型。
|
||||||
|
|
||||||
|
#### **1.3 `FunctionType` 类**
|
||||||
|
- **作用**:表示函数类型,派生自 `Type`。
|
||||||
|
- **成员**:
|
||||||
|
- `returnType`:函数的返回类型。
|
||||||
|
- `paramTypes`:函数的参数类型列表。
|
||||||
|
- 静态方法:`get(Type *returnType, const std::vector<Type *> ¶mTypes)`,用于获取函数类型。
|
||||||
|
- `getReturnType()`:获取函数的返回类型。
|
||||||
|
- `getParamTypes()`:获取函数的参数类型列表。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **2. 中间表示(IR)**
|
||||||
|
#### **2.1 `Value` 类**
|
||||||
|
- **作用**:表示 IR 中的所有值(如指令、常量、参数等)。
|
||||||
|
- **成员**:
|
||||||
|
- `Kind` 枚举:表示值的种类(如 `kAdd`、`kSub`、`kConstant` 等)。
|
||||||
|
- `kind`:当前值的种类。
|
||||||
|
- `type`:值的类型。
|
||||||
|
- `name`:值的名称。
|
||||||
|
- `uses`:值的用途列表(表示哪些指令使用了该值)。
|
||||||
|
- 构造函数:`Value(Kind kind, Type *type, const std::string &name)`。
|
||||||
|
- 类型检查方法:如 `isInt()`、`isFloat()` 等。
|
||||||
|
- `getUses()`:获取值的用途列表。
|
||||||
|
- `replaceAllUsesWith(Value *value)`:将该值的所有用途替换为另一个值。
|
||||||
|
- `print(std::ostream &os)`:打印值的表示。
|
||||||
|
|
||||||
|
#### **2.2 `ConstantValue` 类**
|
||||||
|
- **作用**:表示编译时常量(如整数常量、浮点数常量)。
|
||||||
|
- **成员**:
|
||||||
|
- `iScalar` 和 `fScalar`:分别存储整数和浮点数常量的值。
|
||||||
|
- 静态方法:`get(int value)` 和 `get(float value)`,用于获取常量值。
|
||||||
|
- `getInt()` 和 `getFloat()`:获取常量的值。
|
||||||
|
|
||||||
|
#### **2.3 `Argument` 类**
|
||||||
|
- **作用**:表示函数或基本块的参数。
|
||||||
|
- **成员**:
|
||||||
|
- `block`:参数所属的基本块。
|
||||||
|
- `index`:参数的索引。
|
||||||
|
- 构造函数:`Argument(Type *type, BasicBlock *block, int index, const std::string &name)`。
|
||||||
|
- `getParent()`:获取参数所属的基本块。
|
||||||
|
- `getIndex()`:获取参数的索引。
|
||||||
|
|
||||||
|
#### **2.4 `BasicBlock` 类**
|
||||||
|
- **作用**:表示基本块,包含一系列指令。
|
||||||
|
- **成员**:
|
||||||
|
- `parent`:基本块所属的函数。
|
||||||
|
- `instructions`:基本块中的指令列表。
|
||||||
|
- `arguments`:基本块的参数列表。
|
||||||
|
- `successors` 和 `predecessors`:基本块的后继和前驱列表。
|
||||||
|
- 构造函数:`BasicBlock(Function *parent, const std::string &name)`。
|
||||||
|
- `getParent()`:获取基本块所属的函数。
|
||||||
|
- `getInstructions()`:获取基本块中的指令列表。
|
||||||
|
- `createArgument()`:为基本块创建一个参数。
|
||||||
|
|
||||||
|
#### **2.5 `Instruction` 类**
|
||||||
|
- **作用**:表示 IR 中的指令,派生自 `User`。
|
||||||
|
- **成员**:
|
||||||
|
- `Kind` 枚举:表示指令的种类(如 `kAdd`、`kSub`、`kLoad` 等)。
|
||||||
|
- `kind`:当前指令的种类。
|
||||||
|
- `parent`:指令所属的基本块。
|
||||||
|
- 构造函数:`Instruction(Kind kind, Type *type, BasicBlock *parent, const std::string &name)`。
|
||||||
|
- `getParent()`:获取指令所属的基本块。
|
||||||
|
- `getFunction()`:获取指令所属的函数。
|
||||||
|
- 指令分类方法:如 `isBinary()`、`isUnary()`、`isMemory()` 等。
|
||||||
|
|
||||||
|
#### **2.6 `User` 类**
|
||||||
|
- **作用**:表示使用其他值的指令或全局值,派生自 `Value`。
|
||||||
|
- **成员**:
|
||||||
|
- `operands`:指令的操作数列表。
|
||||||
|
- 构造函数:`User(Kind kind, Type *type, const std::string &name)`。
|
||||||
|
- `getOperand(int index)`:获取指定索引的操作数。
|
||||||
|
- `addOperand(Value *value)`:添加一个操作数。
|
||||||
|
- `replaceOperand(int index, Value *value)`:替换指定索引的操作数。
|
||||||
|
|
||||||
|
#### **2.7 具体指令类**
|
||||||
|
- **`CallInst`**:表示函数调用指令。
|
||||||
|
- **`UnaryInst`**:表示一元操作指令(如取反、类型转换)。
|
||||||
|
- **`BinaryInst`**:表示二元操作指令(如加法、减法)。
|
||||||
|
- **`ReturnInst`**:表示返回指令。
|
||||||
|
- **`UncondBrInst`**:表示无条件跳转指令。
|
||||||
|
- **`CondBrInst`**:表示条件跳转指令。
|
||||||
|
- **`AllocaInst`**:表示栈内存分配指令。
|
||||||
|
- **`LoadInst`**:表示从内存加载值的指令。
|
||||||
|
- **`StoreInst`**:表示将值存储到内存的指令。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **3. 模块和函数**
|
||||||
|
#### **3.1 `Function` 类**
|
||||||
|
- **作用**:表示函数,包含多个基本块。
|
||||||
|
- **成员**:
|
||||||
|
- `parent`:函数所属的模块。
|
||||||
|
- `blocks`:函数中的基本块列表。
|
||||||
|
- 构造函数:`Function(Module *parent, Type *type, const std::string &name)`。
|
||||||
|
- `getReturnType()`:获取函数的返回类型。
|
||||||
|
- `getParamTypes()`:获取函数的参数类型列表。
|
||||||
|
- `addBasicBlock()`:为函数添加一个基本块。
|
||||||
|
|
||||||
|
#### **3.2 `GlobalValue` 类**
|
||||||
|
- **作用**:表示全局变量或常量。
|
||||||
|
- **成员**:
|
||||||
|
- `parent`:全局值所属的模块。
|
||||||
|
- `hasInit`:是否有初始化值。
|
||||||
|
- `isConst`:是否是常量。
|
||||||
|
- 构造函数:`GlobalValue(Module *parent, Type *type, const std::string &name, const std::vector<Value *> &dims, Value *init)`。
|
||||||
|
- `init()`:获取全局值的初始化值。
|
||||||
|
|
||||||
|
#### **3.3 `Module` 类**
|
||||||
|
- **作用**:表示整个编译单元(如一个源文件)。
|
||||||
|
- **成员**:
|
||||||
|
- `children`:模块中的所有值(如函数、全局变量)。
|
||||||
|
- `functions`:模块中的函数列表。
|
||||||
|
- `globals`:模块中的全局变量列表。
|
||||||
|
- `createFunction()`:创建一个函数。
|
||||||
|
- `createGlobalValue()`:创建一个全局变量。
|
||||||
|
- `getFunction()`:获取指定名称的函数。
|
||||||
|
- `getGlobalValue()`:获取指定名称的全局变量。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **4. 工具类**
|
||||||
|
#### **4.1 `Use` 类**
|
||||||
|
- **作用**:表示值与其使用者之间的关系。
|
||||||
|
- **成员**:
|
||||||
|
- `index`:值在使用者操作数列表中的索引。
|
||||||
|
- `user`:使用者。
|
||||||
|
- `value`:被使用的值。
|
||||||
|
- 构造函数:`Use(int index, User *user, Value *value)`。
|
||||||
|
- `getValue()`:获取被使用的值。
|
||||||
|
|
||||||
|
#### **4.2 `range` 类**
|
||||||
|
- **作用**:封装迭代器对 `[begin, end)`,用于遍历容器。
|
||||||
|
- **成员**:
|
||||||
|
- `begin()` 和 `end()`:返回范围的起始和结束迭代器。
|
||||||
|
- `size()`:返回范围的大小。
|
||||||
|
- `empty()`:判断范围是否为空。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **5. 总结**
|
||||||
|
- **类型系统**:`Type`、`PointerType`、`FunctionType` 用于表示 IR 中的类型。
|
||||||
|
- **中间表示**:`Value`、`ConstantValue`、`Instruction` 等用于表示 IR 中的值和指令。
|
||||||
|
- **模块和函数**:`Module`、`Function`、`GlobalValue` 用于组织 IR 的结构。
|
||||||
|
- **工具类**:`Use` 和 `range` 用于辅助实现 IR 的数据结构和遍历。
|
||||||
|
|
||||||
|
这个头文件定义了一个完整的 IR 数据结构,适用于编译器前端将 AST 转换为中间代码,并支持后续的优化和目标代码生成。
|
||||||
156
doc/markdowns/IRbuilder.md
Normal file
156
doc/markdowns/IRbuilder.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
`IRBuilder.h` 文件定义了一个 `IRBuilder` 类,用于简化中间表示(IR)的构建过程。`IRBuilder` 提供了创建各种 IR 指令的便捷方法,并将这些指令插入到指定的基本块中。以下是对文件中主要内容的整理和解释:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **1. `IRBuilder` 类的作用**
|
||||||
|
`IRBuilder` 是一个工具类,用于在生成中间表示(IR)时简化指令的创建和插入操作。它的主要功能包括:
|
||||||
|
- 提供创建各种 IR 指令的工厂方法。
|
||||||
|
- 将创建的指令插入到指定的基本块中。
|
||||||
|
- 支持在基本块的任意位置插入指令。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **2. 主要成员**
|
||||||
|
|
||||||
|
#### **2.1 成员变量**
|
||||||
|
- **`block`**:当前操作的基本块。
|
||||||
|
- **`position`**:当前操作的插入位置(基本块中的迭代器)。
|
||||||
|
|
||||||
|
#### **2.2 构造函数**
|
||||||
|
- **默认构造函数**:`IRBuilder()`。
|
||||||
|
- **带参数的构造函数**:
|
||||||
|
- `IRBuilder(BasicBlock *block)`:初始化 `IRBuilder`,并设置当前基本块和插入位置(默认在基本块末尾)。
|
||||||
|
- `IRBuilder(BasicBlock *block, BasicBlock::iterator position)`:初始化 `IRBuilder`,并设置当前基本块和插入位置。
|
||||||
|
|
||||||
|
#### **2.3 设置方法**
|
||||||
|
- **`setPosition(BasicBlock *block, BasicBlock::iterator position)`**:设置当前基本块和插入位置。
|
||||||
|
- **`setPosition(BasicBlock::iterator position)`**:设置当前插入位置。
|
||||||
|
|
||||||
|
#### **2.4 获取方法**
|
||||||
|
- **`getBasicBlock()`**:获取当前基本块。
|
||||||
|
- **`getPosition()`**:获取当前插入位置。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **3. 指令创建方法**
|
||||||
|
`IRBuilder` 提供了多种工厂方法,用于创建不同类型的 IR 指令。这些方法会将创建的指令插入到当前基本块的指定位置。
|
||||||
|
|
||||||
|
#### **3.1 函数调用指令**
|
||||||
|
- **`createCallInst(Function *callee, const std::vector<Value *> &args, const std::string &name)`**:
|
||||||
|
- 创建一个函数调用指令。
|
||||||
|
- 参数:
|
||||||
|
- `callee`:被调用的函数。
|
||||||
|
- `args`:函数参数列表。
|
||||||
|
- `name`:指令的名称(可选)。
|
||||||
|
- 返回:`CallInst*`。
|
||||||
|
|
||||||
|
#### **3.2 一元操作指令**
|
||||||
|
- **`createUnaryInst(Instruction::Kind kind, Type *type, Value *operand, const std::string &name)`**:
|
||||||
|
- 创建一个一元操作指令(如取反、类型转换)。
|
||||||
|
- 参数:
|
||||||
|
- `kind`:指令的类型(如 `kNeg`、`kFtoI` 等)。
|
||||||
|
- `type`:指令的结果类型。
|
||||||
|
- `operand`:操作数。
|
||||||
|
- `name`:指令的名称(可选)。
|
||||||
|
- 返回:`UnaryInst*`。
|
||||||
|
|
||||||
|
- **具体一元操作指令**:
|
||||||
|
- `createNegInst(Value *operand, const std::string &name)`:创建整数取反指令。
|
||||||
|
- `createNotInst(Value *operand, const std::string &name)`:创建逻辑取反指令。
|
||||||
|
- `createFtoIInst(Value *operand, const std::string &name)`:创建浮点数转整数指令。
|
||||||
|
- `createFNegInst(Value *operand, const std::string &name)`:创建浮点数取反指令。
|
||||||
|
- `createIToFInst(Value *operand, const std::string &name)`:创建整数转浮点数指令。
|
||||||
|
|
||||||
|
#### **3.3 二元操作指令**
|
||||||
|
- **`createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs, Value *rhs, const std::string &name)`**:
|
||||||
|
- 创建一个二元操作指令(如加法、减法)。
|
||||||
|
- 参数:
|
||||||
|
- `kind`:指令的类型(如 `kAdd`、`kSub` 等)。
|
||||||
|
- `type`:指令的结果类型。
|
||||||
|
- `lhs` 和 `rhs`:左操作数和右操作数。
|
||||||
|
- `name`:指令的名称(可选)。
|
||||||
|
- 返回:`BinaryInst*`。
|
||||||
|
|
||||||
|
- **具体二元操作指令**:
|
||||||
|
- 整数运算:
|
||||||
|
- `createAddInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数加法指令。
|
||||||
|
- `createSubInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数减法指令。
|
||||||
|
- `createMulInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数乘法指令。
|
||||||
|
- `createDivInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数除法指令。
|
||||||
|
- `createRemInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数取余指令。
|
||||||
|
- 整数比较:
|
||||||
|
- `createICmpEQInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数相等比较指令。
|
||||||
|
- `createICmpNEInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数不等比较指令。
|
||||||
|
- `createICmpLTInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数小于比较指令。
|
||||||
|
- `createICmpLEInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数小于等于比较指令。
|
||||||
|
- `createICmpGTInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数大于比较指令。
|
||||||
|
- `createICmpGEInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数大于等于比较指令。
|
||||||
|
- 浮点数运算:
|
||||||
|
- `createFAddInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数加法指令。
|
||||||
|
- `createFSubInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数减法指令。
|
||||||
|
- `createFMulInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数乘法指令。
|
||||||
|
- `createFDivInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数除法指令。
|
||||||
|
- `createFRemInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数取余指令。
|
||||||
|
- 浮点数比较:
|
||||||
|
- `createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数相等比较指令。
|
||||||
|
- `createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数不等比较指令。
|
||||||
|
- `createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数小于比较指令。
|
||||||
|
- `createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数小于等于比较指令。
|
||||||
|
- `createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数大于比较指令。
|
||||||
|
- `createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数大于等于比较指令。
|
||||||
|
|
||||||
|
#### **3.4 控制流指令**
|
||||||
|
- **`createReturnInst(Value *value)`**:
|
||||||
|
- 创建返回指令。
|
||||||
|
- 参数:
|
||||||
|
- `value`:返回值(可选)。
|
||||||
|
- 返回:`ReturnInst*`。
|
||||||
|
|
||||||
|
- **`createUncondBrInst(BasicBlock *block, std::vector<Value *> args)`**:
|
||||||
|
- 创建无条件跳转指令。
|
||||||
|
- 参数:
|
||||||
|
- `block`:目标基本块。
|
||||||
|
- `args`:跳转参数(可选)。
|
||||||
|
- 返回:`UncondBrInst*`。
|
||||||
|
|
||||||
|
- **`createCondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock, const std::vector<Value *> &thenArgs, const std::vector<Value *> &elseArgs)`**:
|
||||||
|
- 创建条件跳转指令。
|
||||||
|
- 参数:
|
||||||
|
- `condition`:跳转条件。
|
||||||
|
- `thenBlock`:条件为真时的目标基本块。
|
||||||
|
- `elseBlock`:条件为假时的目标基本块。
|
||||||
|
- `thenArgs` 和 `elseArgs`:跳转参数(可选)。
|
||||||
|
- 返回:`CondBrInst*`。
|
||||||
|
|
||||||
|
#### **3.5 内存操作指令**
|
||||||
|
- **`createAllocaInst(Type *type, const std::vector<Value *> &dims, const std::string &name)`**:
|
||||||
|
- 创建栈内存分配指令。
|
||||||
|
- 参数:
|
||||||
|
- `type`:分配的类型。
|
||||||
|
- `dims`:数组维度(可选)。
|
||||||
|
- `name`:指令的名称(可选)。
|
||||||
|
- 返回:`AllocaInst*`。
|
||||||
|
|
||||||
|
- **`createLoadInst(Value *pointer, const std::vector<Value *> &indices, const std::string &name)`**:
|
||||||
|
- 创建加载指令。
|
||||||
|
- 参数:
|
||||||
|
- `pointer`:指针值。
|
||||||
|
- `indices`:数组索引(可选)。
|
||||||
|
- `name`:指令的名称(可选)。
|
||||||
|
- 返回:`LoadInst*`。
|
||||||
|
|
||||||
|
- **`createStoreInst(Value *value, Value *pointer, const std::vector<Value *> &indices, const std::string &name)`**:
|
||||||
|
- 创建存储指令。
|
||||||
|
- 参数:
|
||||||
|
- `value`:要存储的值。
|
||||||
|
- `pointer`:指针值。
|
||||||
|
- `indices`:数组索引(可选)。
|
||||||
|
- `name`:指令的名称(可选)。
|
||||||
|
- 返回:`StoreInst*`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **4. 总结**
|
||||||
|
- `IRBuilder` 是一个用于简化 IR 构建的工具类,提供了创建各种 IR 指令的工厂方法。
|
||||||
|
- 通过 `IRBuilder`,可以方便地在指定基本块的任意位置插入指令。
|
||||||
|
- 该类的设计使得 IR 的生成更加模块化和易于维护。
|
||||||
121
doc/markdowns/IRcpp.md
Normal file
121
doc/markdowns/IRcpp.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
这个 `IR.cpp` 文件实现了 `IR.h` 中定义的中间表示(IR)数据结构的功能。它包含了类型系统、值、指令、基本块、函数和模块的具体实现,以及一些辅助函数用于打印 IR 的内容。以下是对文件中主要内容的整理和解释:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **1. 辅助函数**
|
||||||
|
#### **1.1 `interleave` 函数**
|
||||||
|
- **作用**:用于在输出流中插入分隔符(如逗号)来打印容器中的元素。
|
||||||
|
- **示例**:
|
||||||
|
```cpp
|
||||||
|
interleave(os, container, ", ");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **1.2 打印函数**
|
||||||
|
- **`printVarName`**:打印变量名,全局变量以 `@` 开头,局部变量以 `%` 开头。
|
||||||
|
- **`printBlockName`**:打印基本块名,以 `^` 开头。
|
||||||
|
- **`printFunctionName`**:打印函数名,以 `@` 开头。
|
||||||
|
- **`printOperand`**:打印操作数,如果是常量则直接打印值,否则打印变量名。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **2. 类型系统**
|
||||||
|
#### **2.1 `Type` 类的实现**
|
||||||
|
- **静态方法**:
|
||||||
|
- `getIntType()`、`getFloatType()`、`getVoidType()`、`getLabelType()`:返回对应类型的单例对象。
|
||||||
|
- `getPointerType(Type *baseType)`:返回指向 `baseType` 的指针类型。
|
||||||
|
- `getFunctionType(Type *returnType, const vector<Type *> ¶mTypes)`:返回函数类型。
|
||||||
|
- **`getSize()`**:返回类型的大小(如 `int` 和 `float` 为 4 字节,指针为 8 字节)。
|
||||||
|
- **`print()`**:打印类型的表示。
|
||||||
|
|
||||||
|
#### **2.2 `PointerType` 类的实现**
|
||||||
|
- **静态方法**:
|
||||||
|
- `get(Type *baseType)`:返回指向 `baseType` 的指针类型,使用 `std::map` 缓存已创建的指针类型。
|
||||||
|
- **`getBaseType()`**:返回指针指向的基础类型。
|
||||||
|
|
||||||
|
#### **2.3 `FunctionType` 类的实现**
|
||||||
|
- **静态方法**:
|
||||||
|
- `get(Type *returnType, const vector<Type *> ¶mTypes)`:返回函数类型,使用 `std::set` 缓存已创建的函数类型。
|
||||||
|
- **`getReturnType()`** 和 `getParamTypes()`:分别返回函数的返回类型和参数类型列表。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **3. 值(Value)**
|
||||||
|
#### **3.1 `Value` 类的实现**
|
||||||
|
- **`replaceAllUsesWith(Value *value)`**:将该值的所有用途替换为另一个值。
|
||||||
|
- **`isConstant()`**:判断值是否为常量(包括常量值、全局值和函数)。
|
||||||
|
|
||||||
|
#### **3.2 `ConstantValue` 类的实现**
|
||||||
|
- **静态方法**:
|
||||||
|
- `get(int value)` 和 `get(float value)`:返回整数或浮点数常量,使用 `std::map` 缓存已创建的常量。
|
||||||
|
- **`getInt()` 和 `getFloat()`**:返回常量的值。
|
||||||
|
- **`print()`**:打印常量的值。
|
||||||
|
|
||||||
|
#### **3.3 `Argument` 类的实现**
|
||||||
|
- **构造函数**:初始化参数的类型、所属基本块和索引。
|
||||||
|
- **`print()`**:打印参数的表示。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **4. 基本块(BasicBlock)**
|
||||||
|
#### **4.1 `BasicBlock` 类的实现**
|
||||||
|
- **构造函数**:初始化基本块的名称和所属函数。
|
||||||
|
- **`print()`**:打印基本块的表示,包括参数和指令。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **5. 指令(Instruction)**
|
||||||
|
#### **5.1 `Instruction` 类的实现**
|
||||||
|
- **构造函数**:初始化指令的类型、所属基本块和名称。
|
||||||
|
- **`print()`**:由具体指令类实现。
|
||||||
|
|
||||||
|
#### **5.2 具体指令类的实现**
|
||||||
|
- **`CallInst`**:表示函数调用指令。
|
||||||
|
- **`print()`**:打印函数调用的表示。
|
||||||
|
- **`UnaryInst`**:表示一元操作指令(如取反、类型转换)。
|
||||||
|
- **`print()`**:打印一元操作的表示。
|
||||||
|
- **`BinaryInst`**:表示二元操作指令(如加法、减法)。
|
||||||
|
- **`print()`**:打印二元操作的表示。
|
||||||
|
- **`ReturnInst`**:表示返回指令。
|
||||||
|
- **`print()`**:打印返回指令的表示。
|
||||||
|
- **`UncondBrInst`**:表示无条件跳转指令。
|
||||||
|
- **`print()`**:打印无条件跳转的表示。
|
||||||
|
- **`CondBrInst`**:表示条件跳转指令。
|
||||||
|
- **`print()`**:打印条件跳转的表示。
|
||||||
|
- **`AllocaInst`**:表示栈内存分配指令。
|
||||||
|
- **`print()`**:打印内存分配的表示。
|
||||||
|
- **`LoadInst`**:表示从内存加载值的指令。
|
||||||
|
- **`print()`**:打印加载指令的表示。
|
||||||
|
- **`StoreInst`**:表示将值存储到内存的指令。
|
||||||
|
- **`print()`**:打印存储指令的表示。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **6. 函数(Function)**
|
||||||
|
#### **6.1 `Function` 类的实现**
|
||||||
|
- **构造函数**:初始化函数的名称、返回类型和参数类型。
|
||||||
|
- **`print()`**:打印函数的表示,包括基本块和指令。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **7. 模块(Module)**
|
||||||
|
#### **7.1 `Module` 类的实现**
|
||||||
|
- **`print()`**:打印模块的表示,包括所有函数和全局变量。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **8. 用户(User)**
|
||||||
|
#### **8.1 `User` 类的实现**
|
||||||
|
- **`setOperand(int index, Value *value)`**:设置指定索引的操作数。
|
||||||
|
- **`replaceOperand(int index, Value *value)`**:替换指定索引的操作数,并更新用途列表。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **9. 总结**
|
||||||
|
- **类型系统**:实现了 `Type`、`PointerType` 和 `FunctionType`,用于表示 IR 中的类型。
|
||||||
|
- **值**:实现了 `Value`、`ConstantValue` 和 `Argument`,用于表示 IR 中的值和参数。
|
||||||
|
- **基本块**:实现了 `BasicBlock`,用于组织指令。
|
||||||
|
- **指令**:实现了多种具体指令类(如 `CallInst`、`BinaryInst` 等),用于表示 IR 中的操作。
|
||||||
|
- **函数和模块**:实现了 `Function` 和 `Module`,用于组织 IR 的结构。
|
||||||
|
- **打印功能**:通过 `print()` 方法,可以将 IR 的内容输出为可读的文本格式。
|
||||||
|
|
||||||
|
这个文件是编译器中间表示的核心实现,能够将抽象语法树(AST)转换为中间代码,并支持后续的优化和目标代码生成。
|
||||||
@@ -133,69 +133,58 @@ std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){
|
|||||||
}
|
}
|
||||||
// std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx);
|
// std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx);
|
||||||
|
|
||||||
std::any ASTPrinter::visitStmt(SysYParser::StmtContext *ctx){
|
std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){
|
||||||
if(ctx->lValue()&& ctx->exp()) {
|
ctx->lValue()->accept(this);
|
||||||
cout << getIndent();
|
cout << ' ' << ctx->ASSIGN()->getText() << ' ';
|
||||||
ctx->lValue()->accept(this);
|
ctx->exp()->accept(this);
|
||||||
cout << ' ' << ctx->ASSIGN()->getText() <<' ';
|
cout << ctx->SEMICOLON()->getText() << '\n';
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitExpStmt(SysYParser::ExpStmtContext *ctx){
|
||||||
|
if (ctx->exp()) {
|
||||||
ctx->exp()->accept(this);
|
ctx->exp()->accept(this);
|
||||||
cout << ctx->SEMICOLON()->getText() << endl;
|
|
||||||
}
|
}
|
||||||
else if(ctx->blockStmt()){
|
cout << ctx->SEMICOLON()->getText() << '\n';
|
||||||
ctx->blockStmt()->accept(this);
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitIfStmt(SysYParser::IfStmtContext *ctx){
|
||||||
|
cout << getIndent() << ctx->IF()->getText() << ' ' << ctx->LPAREN()->getText();
|
||||||
|
ctx->cond()->accept(this);
|
||||||
|
cout << ctx->RPAREN()->getText() << ' ';
|
||||||
|
ctx->stmt(0)->accept(this);
|
||||||
|
if (ctx->ELSE()) {
|
||||||
|
cout << getIndent() << ctx->ELSE()->getText() << ' ';
|
||||||
|
ctx->stmt(1)->accept(this);
|
||||||
}
|
}
|
||||||
else if(ctx->IF()){
|
return nullptr;
|
||||||
cout << getIndent() << "if (";
|
}
|
||||||
ctx->cond()->accept(this);
|
|
||||||
cout << ")";
|
std::any ASTPrinter::visitWhileStmt(SysYParser::WhileStmtContext *ctx){
|
||||||
// visit ctx->stmt(0) to judge if it is a blockStmt or a Lvale=exp
|
cout << getIndent() << ctx->WHILE()->getText() << ' ' << ctx->LPAREN()->getText();
|
||||||
if(ctx->stmt(0)->blockStmt())ctx->stmt(0)->accept(this);
|
ctx->cond()->accept(this);
|
||||||
else{
|
cout << ctx->RPAREN()->getText() << ' ';
|
||||||
cout << " {"<< endl;
|
ctx->stmt()->accept(this);
|
||||||
indentLevel++;
|
return nullptr;
|
||||||
ctx->stmt(0)->accept(this);
|
}
|
||||||
indentLevel--;
|
|
||||||
cout << getIndent() << "}" << endl;
|
std::any ASTPrinter::visitBreakStmt(SysYParser::BreakStmtContext *ctx){
|
||||||
}
|
cout << getIndent() << ctx->BREAK()->getText() << ctx->SEMICOLON()->getText() << '\n';
|
||||||
if (ctx->stmt().size() > 1) {
|
return nullptr;
|
||||||
cout << getIndent() << "else";
|
}
|
||||||
if(ctx->stmt(1)->blockStmt())ctx->stmt(1)->accept(this);
|
|
||||||
else{
|
std::any ASTPrinter::visitContinueStmt(SysYParser::ContinueStmtContext *ctx){
|
||||||
cout << " {"<< endl;
|
cout << getIndent() << ctx->CONTINUE()->getText() << ctx->SEMICOLON()->getText() << '\n';
|
||||||
indentLevel++;
|
return nullptr;
|
||||||
ctx->stmt(1)->accept(this);
|
}
|
||||||
indentLevel--;
|
|
||||||
cout << getIndent() << "}" << endl;
|
std::any ASTPrinter::visitReturnStmt(SysYParser::ReturnStmtContext *ctx){
|
||||||
}
|
cout << getIndent() << ctx->RETURN()->getText() << ' ';
|
||||||
}
|
if (ctx->exp()) {
|
||||||
}
|
ctx->exp()->accept(this);
|
||||||
else if(ctx->WHILE()){
|
|
||||||
cout << getIndent() << "while (";
|
|
||||||
ctx->cond()->accept(this);
|
|
||||||
cout << ")";
|
|
||||||
if(ctx->stmt(0)->blockStmt())ctx->stmt(0)->accept(this);
|
|
||||||
else{
|
|
||||||
cout << " {"<< endl;
|
|
||||||
indentLevel++;
|
|
||||||
ctx->stmt(0)->accept(this);
|
|
||||||
indentLevel--;
|
|
||||||
cout << getIndent() << "}" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(ctx->BREAK()){
|
|
||||||
cout << getIndent() << "break;" << endl;
|
|
||||||
}
|
|
||||||
else if(ctx->CONTINUE()){
|
|
||||||
cout << getIndent() << "continue;" << endl;
|
|
||||||
}
|
|
||||||
else if(ctx->RETURN()){
|
|
||||||
cout << getIndent() << "return";
|
|
||||||
if(ctx->exp()){
|
|
||||||
cout << ' ';
|
|
||||||
ctx->exp()->accept(this);
|
|
||||||
}
|
|
||||||
cout << ctx->SEMICOLON()->getText() << endl;
|
|
||||||
}
|
}
|
||||||
|
cout << ctx->SEMICOLON()->getText() << '\n';
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,6 +200,12 @@ std::any ASTPrinter::visitLValue(SysYParser::LValueContext *ctx){
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// std::any ASTPrinter::visitPrimaryExp(SysYParser::PrimaryExpContext *ctx);
|
// std::any ASTPrinter::visitPrimaryExp(SysYParser::PrimaryExpContext *ctx);
|
||||||
|
std::any ASTPrinter::visitParenExp(SysYParser::ParenExpContext *ctx){
|
||||||
|
cout << ctx->LPAREN()->getText();
|
||||||
|
ctx->exp()->accept(this);
|
||||||
|
cout << ctx->RPAREN()->getText();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) {
|
std::any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) {
|
||||||
if(ctx->ILITERAL())cout << ctx->ILITERAL()->getText();
|
if(ctx->ILITERAL())cout << ctx->ILITERAL()->getText();
|
||||||
@@ -222,28 +217,15 @@ std::any ASTPrinter::visitString(SysYParser::StringContext *ctx) {
|
|||||||
cout << ctx->STRING()->getText();
|
cout << ctx->STRING()->getText();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx);
|
||||||
std::any ASTPrinter::visitUnaryExp(SysYParser::UnaryExpContext *ctx){
|
// std::any ASTPrinter::visitUnaryOp(SysYParser::UnaryOpContext *ctx);
|
||||||
if(ctx->primaryExp())
|
std::any ASTPrinter::visitCall(SysYParser::CallContext *ctx){
|
||||||
ctx->primaryExp()->accept(this);
|
cout << ctx->Ident()->getText() << ctx->LPAREN()->getText();
|
||||||
else if(ctx->Ident()){
|
if(ctx->funcRParams())
|
||||||
cout << ctx->Ident()->getText() << ctx->LPAREN()->getText();
|
ctx->funcRParams()->accept(this);
|
||||||
if(ctx->funcRParams())
|
cout << ctx->RPAREN()->getText();
|
||||||
ctx->funcRParams()->accept(this);
|
|
||||||
if (ctx->RPAREN())
|
|
||||||
cout << ctx->RPAREN()->getText();
|
|
||||||
else
|
|
||||||
cout << "<missing \')\'?>";
|
|
||||||
}
|
|
||||||
else if(ctx->unaryExp()){
|
|
||||||
cout << ctx->unaryOp()->getText();
|
|
||||||
ctx->unaryExp()->accept(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ctx->accept(this);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// std::any ASTPrinter::visitUnaryOp(SysYParser::UnaryOpContext *ctx);
|
|
||||||
|
|
||||||
any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
|
any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
|
||||||
if (ctx->exp().empty())
|
if (ctx->exp().empty())
|
||||||
|
|||||||
@@ -26,23 +26,27 @@ public:
|
|||||||
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
||||||
std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override;
|
std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override;
|
||||||
|
|
||||||
// std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
|
|
||||||
// std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override;
|
|
||||||
// std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
|
|
||||||
// std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
|
|
||||||
// std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
|
||||||
// std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
|
||||||
// std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
|
|
||||||
|
|
||||||
// std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override;
|
// std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override;
|
||||||
std::any visitStmt(SysYParser::StmtContext *ctx) override;
|
// std::any visitStmt(SysYParser::StmtContext *ctx) override;
|
||||||
|
|
||||||
|
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
|
||||||
|
std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override;
|
||||||
|
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
|
||||||
|
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
|
||||||
|
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
||||||
|
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
||||||
|
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
|
||||||
|
|
||||||
// std::any visitExp(SysYParser::ExpContext *ctx) override;
|
// std::any visitExp(SysYParser::ExpContext *ctx) override;
|
||||||
// std::any visitCond(SysYParser::CondContext *ctx) override;
|
// std::any visitCond(SysYParser::CondContext *ctx) override;
|
||||||
std::any visitLValue(SysYParser::LValueContext *ctx) override;
|
std::any visitLValue(SysYParser::LValueContext *ctx) override;
|
||||||
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
|
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
|
||||||
|
std::any visitParenExp(SysYParser::ParenExpContext *ctx) override;
|
||||||
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
||||||
std::any visitString(SysYParser::StringContext *ctx) override;
|
std::any visitString(SysYParser::StringContext *ctx) override;
|
||||||
std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
||||||
|
std::any visitCall(SysYParser::CallContext *ctx) override;
|
||||||
|
// std::any visitUnExpOp(SysYParser::UnExpContext *ctx) override;
|
||||||
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
|
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
|
||||||
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
||||||
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
|
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
|
||||||
|
|||||||
@@ -77,7 +77,9 @@ private:
|
|||||||
std::unique_ptr<Module> module;
|
std::unique_ptr<Module> module;
|
||||||
IRBuilder builder;
|
IRBuilder builder;
|
||||||
SymbolTable symbols_table;
|
SymbolTable symbols_table;
|
||||||
//array init use variables
|
|
||||||
|
static Type current_type;
|
||||||
|
|
||||||
int d = 0, n = 0;
|
int d = 0, n = 0;
|
||||||
vector<int> path;
|
vector<int> path;
|
||||||
bool isalloca;
|
bool isalloca;
|
||||||
@@ -94,39 +96,42 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
|
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
|
||||||
|
|
||||||
std::any visitDecl(SysYParser::DeclContext *ctx) override;
|
std::any visitDecl(SysYParser::DeclContext *ctx) override;
|
||||||
|
|
||||||
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
|
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
|
||||||
|
|
||||||
std::any visitBType(SysYParser::BTypeContext *ctx) override;
|
std::any visitBType(SysYParser::BTypeContext *ctx) override;
|
||||||
|
|
||||||
std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
|
std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
|
||||||
|
|
||||||
std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
|
std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
|
||||||
|
|
||||||
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
|
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
|
||||||
|
|
||||||
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
|
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
|
||||||
|
|
||||||
|
|
||||||
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
|
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
|
||||||
|
// std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
|
||||||
std::any visitVarDef(SysYParser::VarDefContext *ctx, Type* btype);
|
std::any visitInitVal(SysYParser::InitValContext *ctx) override;
|
||||||
|
|
||||||
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
||||||
|
|
||||||
std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
|
std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
|
||||||
|
|
||||||
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
|
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
|
||||||
|
// std::any visitStmt(SysYParser::StmtContext *ctx) override;
|
||||||
std::any visitStmt(SysYParser::StmtContext *ctx) override;
|
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
|
||||||
|
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
|
||||||
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
||||||
|
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
||||||
|
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
|
||||||
|
std::any visitExp(SysYParser::ExpContext *ctx) override;
|
||||||
|
std::any visitLValue(SysYParser::LValueContext *ctx) override;
|
||||||
|
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
|
||||||
|
std::any visitParenExp(SysYParser::ParenExpContext *ctx) override;
|
||||||
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
||||||
|
|
||||||
std::any visitString(SysYParser::StringContext *ctx) override;
|
std::any visitString(SysYParser::StringContext *ctx) override;
|
||||||
|
std::any visitCall(SysYParser::CallContext *ctx) override;
|
||||||
|
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
||||||
|
std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
|
||||||
|
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
||||||
|
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
|
||||||
|
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
|
||||||
|
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
|
||||||
|
std::any visitEqExp(SysYParser::EqExpContext *ctx) override;
|
||||||
|
std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override;
|
||||||
|
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
|
||||||
|
std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::any visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type);
|
std::any visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type);
|
||||||
|
|||||||
Reference in New Issue
Block a user