4.2 KiB
[TOC]
任务描述
本关任务:编写SysYBuilder.cpp
文件,以实现 IR 的自动生成
相关知识
实验框架
本次实验使用了由 C++ 编写的 SysY IR 来生成 LLVM IR。为了便于大家进行实验,该框架自动完成了语法树到 C++ 上的抽象语法树的转换。
在SysYBuilder.hpp
中,我们还定义了一个用于存储作用域的类Scope
。它的作用是辅助我们在遍历语法树时,管理不同作用域中的变量。它提供了以下接口:
// 进入一个新的作用域
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
,它在初始化时已经将特殊函数加入了作用域中。因此,你们在进行名字查找时不需要顾虑是否需要对特殊函数进行特殊操作。
本关具体任务
- 你需要在
src/SysYBuilder
文件夹中,调用SysY IR接口,填写SysYBuilder.cpp
文件,以实现 IR 的自动生成。 - 在
report.md
内回答思考题
编译、运行与验证
编译运行 SysYCompiler
mkdir build
cd build
cmake ..
make
编译后会产生 SysYCompiler
程序,它能将sy文件输出为LLVM IR。
当需要对 sy 文件测试时,可以这样使用:
SysYCompiler test.sy -emit-ir -o test.ll
得到对应的ll文件。
自动测试
助教提供了自动评测脚本, 在SysYF_Student/SysYF_Task3/Test_H/
目录下执行python3 test_H.py
, 即可得到评测信息
思考题
请在report/report.md
中详细回答下述思考题。
- 在
scope
内单独处理func
的好处有哪些。
选做
对于学有余力的小组, 我们提供了选做环节, 若小组能完成选做部分, 将会有额外加分(仅针对本次实验的团队代码得分, 并且分数不能超过该部分得分上限)
选做部分验收方式为线下验收,你需要在线下检查时提供对应代码通过助教给出的选做部分测试样例,并且讲解你的代码
选做部分说明如下:(每个班只展示一部分)
- H班:
- 多维数组
- 网安班:
- 多维数组
- 将一维数组指针作为参数
- 逻辑运算(&&, ||, !), 重点考察短路计算
多维数组
目前给出的SysY IR接口并不支持多维数组的实现,因此你需要修改接口,以实现多维数组的声明、初始化和使用,你可以修改的内容为文件夹include/SysYIR
,include/SysYBuilder
,src/SysYIR
,src/SysYBuilder
内的所有内容
多维数组在目前的接口基础上,一般有两种做法:
- 直接实现,参考 clang 生成的 LLVM IR,修改当前接口使其支持多维的数组类型
- 展平,把高维数组当成一维数组存储,修改当前接口使其能保存一些必要信息
在初始化多维数组时,与一维数组不同的是存在对齐问题,我们设定多维数组的初始化为完全对齐(在每个大括号处均对齐),以下两种初始化是等价的:
int a[5][2] = {1,{2,3},{4},{5,6,7}}
int a[5][2] = {{1,0},{2,3},{4,0},{5,6},{7,0}}
数组指针参数 & 逻辑运算
目前给出的SysY IR接口支持数组指针参数和逻辑运算的短路计算,因此你不需要修改接口
注意pointer
和array
的区别以及文法中&&
和||
的优先级
备注
测试样例并不止公开的20个样例, 助教准备了许多隐藏测例来考验大家:), 隐藏测例并不会放在平台上
平台上第三部分的评测只判断公开样例是否完全通过, 第三部分的分数由助教线下检查后根据公开样例和隐藏样例的通过情况确定, 因此请自行设计合法样例测试你们的代码,确保你们的代码考虑了足够多情况以通过尽可能多的隐藏样例