# IR实验阶段三 本实验由黄庄湫、吴毓辰助教设计 ## 前言 本次实验我们要使用访问者模式来实现 IR 自动生成。 对于产生的IR, 我们可以调用 clang 生成可执行文件,这样一个初级的 SysYF 编译器就完成啦! ## 任务描述 阅读[SysYF 的语义规则](../SysYF语言定义.pdf),注意本次实验必做部分语言可能与前几次实验有不同 阅读[SysY IR 核心类介绍](./SysYIR.md) 阅读[实验框架](#实验框架),理解如何使用框架以及注意事项 修改 `src/SysYBuilder/SysYBuilder.cpp` 来实现自动 IR 产生的算法,使得它能正确编译任何合法的 SysYF 程序 注: 本次实验不需要实现多维数组 ## 实验框架 本次实验使用了由C++编写的 SysY IR 来生成 LLVM IR。为了便于大家进行实验,该框架自动完成了语法树到 C++ 上的抽象语法树的转换。 在SysYBuilder.hpp中,我们还定义了一个用于存储作用域的类`Scope`。它的作用是辅助我们在遍历语法树时,管理不同作用域中的变量。它提供了以下接口: ```cpp // 进入一个新的作用域 void enter(); // 退出一个作用域 void exit(); // 往当前作用域插入新的名字->值映射 bool push(std::string name, Value *val); // 根据名字,以及是否为函数的bool值寻找到对应值 // isfunc 为 true 时为寻找函数,否则为寻找其他变量对应的值 // 思考:将函数单独处理的目的 Value* find(std::string name, bool isfunc); // 判断当前是否在全局作用域内 bool in_global(); ``` 你们需要根据语义合理调用`enter`与`exit`,并且在变量声明和使用时正确调用`push`与`find`。在类`SysYfBuilder`中,有一个`Scope`类型的成员变量`scope`,它在初始化时已经将特殊函数加入了作用域中。因此,你们在进行名字查找时不需要顾虑是否需要对特殊函数进行特殊操作。 ## 运行与调试 ### 运行 SysYCompiler ```sh mkdir build cd build cmake .. make ``` 编译后会产生 `SysYCompiler` 程序,它能将`.sy`文件输出为LLVM IR,可以利用clang将IR编译成二进制文件。 当需要对 `.sy` 文件测试时,可以这样使用: ```sh SysYCompiler test.sy -emit-ir -o test.ll ``` ### 自动测试 助教提供了自动评测脚本, 在`SysYF_Student/SysYF_Task3/Test_H/`目录下执行`python3 test_H.py`, 即可得到评测信息 ### Bonus 对于学有余力的小组, 我们提供了Bonus环节, 若小组能完成Bonus部分, 将会有额外加分(仅针对本次实验的团队代码得分, 并且分数不能超过该部分得分上限) Bonus部分说明如下: - H班: - 多维数组 - 网安班: - 将一维数组指针作为参数 - 逻辑运算(\&\&, \|\|, \!), 重点考察短路计算 - 多维数组 Bonus部分得分标准: 每个部分单独给分, 每个部分需要通过全部对应测例并在线下检查时给助教讲清思路才能得分 若小组完成了Bonus部分, 需在线下检查时向助教提出, 并让助教当场检查. 若在统一线下检查过后自行找助教检查, 该Bonus不算分 ### 备注 测试样例并不止公开的20个样例, 助教准备了许多隐藏测例来考验大家:), 隐藏测例并不会放在平台上 平台上第三部分的分数并不具有参考性, 第三部分的分数由助教线下检查后确定