diff --git a/README.md b/README.md index 3889d3f..aae4b33 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - [1.2 提交要求和评分标准](#12-提交要求和评分标准) ## 0. 前言 -本次实验分为3关,前2关是个人实验,第3关为组队实验。**本次实验请务必使用git提交**。 +本次实验分为3关,为组队实验。**本次实验请务必使用git提交**。 本次实验的目的是让大家熟悉生成中间代码所需要的相关知识: LLVM IR、 SysY IR(LLVM IR的轻量级C++接口),并实际实现一个IR Builder。 在开始实验之前,请确保LLVM的版本不低于10.0.1,且PATH环境变量配置正确。可以通过`lli --version`命令是否可以输出10.0.1的版本信息来验证。 @@ -17,7 +17,7 @@ 1. 第一部分: 了解LLVM IR。通过clang生成的.ll,了解LLVM IR与c代码的对应关系。相应文档见[phase1.md](./doc/phase1.md) 2. 第二部分: 了解SysY IR。通过助教提供的c++例子,了解SysY IR的c++接口及实现。相应文档见[phase2.md](./doc/phase2.md) 3. 第三部分: 使用SysY IR,实现一个IR Builder,使其可以通过抽象语法树生成LLVM兼容的IR代码。相应文档见[phase3.md](./doc/phase3.md) -4. 实验报告:在[report.md](./report.md)中撰写报告。 +4. 实验报告:在[report.md](./report/report.md)中撰写报告。 ## 1. 实验要求 @@ -27,14 +27,16 @@ . ├── CMakeLists.txt ├── README.md <- PW6实验文档说明(你在这里) -├── contribution.md <- PW6所需提交的组员贡献(队长提交即可) -├── report.md <- PW6所需提交的实验报告 ├── doc │   ├── AST.md -│   ├── phase1.md +│   ├── phase1.md <- 各阶段文档 │   ├── phase2.md │   ├── phase3.md +│   ├── SysYF语言定义.pdf | └── SysYIR.md <- SysY IR 相关文档 +├── report +│   ├── report.md <- PW6所需提交的实验报告 +│   └── contribution.md <- PW6所需提交的组员贡献(队长负责填写) ├── include <- 实验所需的头文件 │   ├── ... │   └── SysYIR @@ -88,29 +90,29 @@ * 需要完成 `./SysYF_Student/SysYF_Task1/student_ll`目录下的4个文件 * 需要完成 `./SysYF_Student/SysYF_Task2/student_cpp`目录下的4个文件 * 需要完成 `./src/SysYBuilder/SysYBuilder.cpp` - * 需要在 `./report.md` 中撰写实验报告 + * 需要在 `./report/report.md` 中撰写实验报告 * 实验报告内容包括: * 实验要求、问题回答、实验设计、实验难点及解决方案、实验总结、实验反馈、组间交流(具体参考[report.md](./report.md)) * 本次实验报告**参与**评分标准. * 提交规范: - * 不破坏目录结构(`report.md`如果需要放图片,请放在`./report_figs/`下) + * 不破坏目录结构(`report.md`如果需要放图片,请新建`figs`文件夹放在`./report`下) * 不上传临时文件(凡是自动生成的文件和临时文件请不要上传) * **组队实验要求** - * 由队长在 `contribution.md` 中解释每位队员的贡献,并说明贡献比例 - * 组队实验意味着合作,但是小组间的交流是受限的,且**严格禁止**代码的共享。除此之外,如果小组和其它组进行了交流,必须在 `report.md` 中记录交流的小组和你们之间交流内容 -* 评分标准: 本次实验分为3部分, 请注意前两部分为个人实验, 第三部分为组队实验, 个人实验需要各自完成, 组队实验的代码和报告我们只检查组长的仓库 + * 由队长在 `./report/contribution.md` 中解释每位队员的贡献,并说明贡献比例 + * 组队实验意味着合作,但是小组间的交流是受限的,且**严格禁止**代码的共享。除此之外,如果小组和其它组进行了交流,必须在 `./report/report.md` 中记录交流的小组和你们之间交流内容 +* 评分标准: 本次实验分为3部分, 为组队实验, 请合理安排分工, 我们会根据组长填写的贡献比进行分数分配,如果对贡献比有异议的组员可根据git的提交记录申请仲裁,建议利用好`git branch` * **禁止执行恶意代码,违者本次实验0分处理** * 第一部分10分: `.ll`运行结果正确(1个2分, 注释共2分) * 第二部分20分: `.cpp`运行结果正确(1个5分) * 第三部分70分: 该部分成绩由5部分组成(团队代码得分, 实验报告得分, 迟交天数, 组员贡献比, 组长奖励加分) * 实验检查 - * 线上: 助教会在educoder上检查前两部分, 该部分是每个人需要独自完成的 - * 线下: 线下检查只检查第三部分, 组长带组员到负责组长的助教处检查 + * 线上: 助教会在educoder上检查前两部分 + * 线下: 线下检查只检查第三部分, 组长带组员到负责组长的助教处检查, 选做部分请找本次实验负责助教检查 * 迟交规定 * 迟交需要邮件通知助教: * 邮箱: huangzq@mail.ustc.edu.cn * 邮件主题: PW6迟交-学号 - * 内容: 包括迟交原因、最后版本commitID、迟交时间等 + * 内容: 包括迟交原因、最后版本commit ID、迟交时间等 * 关于抄袭和雷同 经过助教和老师判定属于作业抄袭或雷同情况,所有参与方一律零分,不接受任何解释和反驳。 如有任何问题,欢迎提issue进行批判指正。 diff --git a/SysYF语言定义.pdf b/doc/SysYF语言定义.pdf similarity index 100% rename from SysYF语言定义.pdf rename to doc/SysYF语言定义.pdf diff --git a/doc/phase1.md b/doc/phase1.md index 6f1f9c6..9c8039f 100644 --- a/doc/phase1.md +++ b/doc/phase1.md @@ -1,33 +1,33 @@ # IR实验阶段一 本实验由黄庄湫、吴毓辰助教设计 -## 前言 +## 0 前言 本次实验的目的是让大家熟悉阶段三所需相关知识: LLVM IR -## 任务描述 +## 1 任务描述 [了解LLVM IR](#llvm-ir介绍) [通过clang生成的.ll,了解LLVM IR与c代码的对应关系](#例子-利用clang生成的ll) [根据c程序手写.ll文件实现相同功能](#你需要做-手动编写ll) -## 实验内容 -### LLVM IR介绍 +## 2 实验内容 +### 2.1 LLVM IR介绍 根据[维基百科](https://zh.wikipedia.org/zh-cn/LLVM)的介绍,LLVM是一个自由软件项目,它是一种编译器基础设施,以C++写成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。IR的全称是Intermediate Representation,即中间表示。LLVM IR是一种类似于汇编的底层语言。 LLVM IR的具体指令可以参考[Reference Manual](http://llvm.org/docs/LangRef.html)。但是你会发现其内容庞杂。虽然助教认为,高效地查阅官方文档及手册是非常必要的一项技能,但是由于其手册过于复杂,因此助教筛选了后续实验中将要用到的子集,总结为了[精简的IR Reference手册](./SysYIR.md)。 作为一开始的参考,你可以先阅读其中`IR Features`和`IR Format`两节,后续有需要再反复参考。 -### 例子: 利用clang生成的.ll +### 2.2 例子: 利用clang生成的.ll 阅读`SysYF_Student/SysYF_Task1/ta_demo/go_upstairs.c` 在对应文件夹内输入`clang -S -emit-llvm go_upstairs.c`指令,你可以得到对应的`go_upstairs.ll` 你需要结合`go_upstairs.c`阅读`go_upstairs.ll`,理解其中每条LLVM IR指令与c代码的对应情况。 通过`lli go_upstairs.ll; echo $?`指令,你可以测试`go_upstairs.ll`执行结果的正确性。 -### 你需要做: 手动编写.ll +### 2.3 你需要做: 手动编写.ll 助教在`SysYF_Student/SysYF_Task1/student_sy/`内提供了四个简单的sy程序:assign_test.sy,func_test.sy,if_test.sy,while_test.sy 你需要在`SysYF_Student/SysYF_Task1/student_ll/`内手工完成自己的assign_test.ll,func_test.ll,if_test.ll,while_test.ll文件,以实现与上述C程序相同的逻辑功能。你需要添加必要的注释,`.ll`文件的注释是以`;`开头的 必要的情况下,你可以参考`clang -S -emit-llvm`的输出,但是你提交的结果必须避免同此输出一字不差 注:`.sy`文件是我们定义的语言文件,`clang`无法直接识别 -### 运行.ll文件 +### 2.4 运行.ll文件 - `lli`会运行`*.ll`文件 - `$?`的内容是上一条命令所返回的结果,而`echo $?`可以将其输出到终端中 \ No newline at end of file diff --git a/doc/phase2.md b/doc/phase2.md index 6e92574..db646d7 100644 --- a/doc/phase2.md +++ b/doc/phase2.md @@ -1,28 +1,28 @@ # IR实验阶段二 本实验由黄庄湫、吴毓辰助教设计 -## 前言 +## 0 前言 本次实验的目的是让大家熟悉阶段三所需相关知识: SysY IR(由助教编写的LLVM IR的轻量级C++接口)。 -## 任务描述 +## 1 任务描述 [了解SysY IR](#sysy-ir---llvm-ir的c接口) [通过助教提供的C++例子,了解SysY IR的C++接口及实现](#例子-利用sysy-ir--cpp-生成ll) [根据c程序手写C++文件调用SysY IR的API生成相同功能的.ll文件](#你需要做-利用sysy-ir--c编写生成ll的程序) -## 实验内容 -### SysY IR - LLVM IR的C++接口 +## 2 实验内容 +### 2.1 SysY IR - LLVM IR的C++接口 由于LLVM IR官方的C++接口的文档同样过于冗长,助教提供了SysY IR这一C++接口库。你需要阅读[SysY IR核心类的介绍](./SysYIR.md)。 本关会要求大家通过SysY IR根据AST构建生成LLVM IR。所以你需要仔细阅读文档了解其接口的设计。 -### 例子: 利用SysY IR + C++ 生成.ll +### 2.2 例子: 利用SysY IR + C++ 生成.ll 为了让大家更直观地感受并学会LightIR接口的使用,助教提供了`SysYF_Student/SysYF_Task2/ta_demo/go_upstairs_gen.cpp`。 该C++程序会生成与go_upstairs.c逻辑相同的LLVM IR文件。助教提供了详尽的注释,一定要好好利用! -### 你需要做: 利用SysY IR + C++编写生成.ll的程序 +### 2.3 你需要做: 利用SysY IR + C++编写生成.ll的程序 你需要在`SysYF_Student/SysYF_Task2/student_cpp/`文件夹中,调用SysY IR接口,编写自己的assign_gen.cpp,func_gen.cpp,if_gen.cpp,while_gen.cpp程序,以生成与phase1的四个sy程序相同逻辑功能的`.ll`文件。 -### 编译、运行和验证 +### 2.4 编译、运行和验证 在 `SysYF_Student/SysYF_Task2/build/` 下执行: ``` shell # 如果存在 CMakeCache.txt 要先删除 diff --git a/doc/phase3.md b/doc/phase3.md index 5c5a5a4..7f41aaa 100644 --- a/doc/phase3.md +++ b/doc/phase3.md @@ -1,11 +1,11 @@ # IR实验阶段三 本实验由黄庄湫、吴毓辰助教设计 -## 前言 +## 0 前言 本次实验我们要使用访问者模式来实现 IR 自动生成。 对于产生的IR, 我们可以调用 clang 生成可执行文件,这样一个初级的 SysYF 编译器就完成啦! -## 任务描述 +## 1 任务描述 阅读[SysYF 的语义规则](../SysYF语言定义.pdf),注意本次实验必做部分语言可能与前几次实验有不同 阅读[SysY IR 核心类介绍](./SysYIR.md) @@ -14,9 +14,9 @@ 修改 `src/SysYBuilder/SysYBuilder.cpp` 来实现自动 IR 产生的算法,使得它能正确编译任何合法的 SysYF 程序 注: 本次实验不需要实现多维数组 -## 实验框架 +## 2 实验框架 -本次实验使用了由C++编写的 SysY IR 来生成 LLVM IR。为了便于大家进行实验,该框架自动完成了语法树到 C++ 上的抽象语法树的转换。 +本次实验使用了由 C++ 编写的 SysY IR 来生成 LLVM IR。为了便于大家进行实验,该框架自动完成了语法树到 C++ 上的抽象语法树的转换。 在SysYBuilder.hpp中,我们还定义了一个用于存储作用域的类`Scope`。它的作用是辅助我们在遍历语法树时,管理不同作用域中的变量。它提供了以下接口: ```cpp @@ -35,9 +35,9 @@ bool in_global(); ``` 你们需要根据语义合理调用`enter`与`exit`,并且在变量声明和使用时正确调用`push`与`find`。在类`SysYfBuilder`中,有一个`Scope`类型的成员变量`scope`,它在初始化时已经将特殊函数加入了作用域中。因此,你们在进行名字查找时不需要顾虑是否需要对特殊函数进行特殊操作。 -## 运行与调试 +## 3 运行与调试 -### 运行 SysYCompiler +### 3.1 运行 SysYCompiler ```sh mkdir build @@ -54,27 +54,43 @@ make SysYCompiler test.sy -emit-ir -o test.ll ``` -### 自动测试 +### 3.2 自动测试 助教提供了自动评测脚本, 在`SysYF_Student/SysYF_Task3/Test_H/`目录下执行`python3 test_H.py`, 即可得到评测信息 -### Bonus +## 4 选做 -对于学有余力的小组, 我们提供了Bonus环节, 若小组能完成Bonus部分, 将会有额外加分(仅针对本次实验的团队代码得分, 并且分数不能超过该部分得分上限) +对于学有余力的小组, 我们提供了选做环节, 若小组能完成选做部分, 将会有额外加分(仅针对本次实验的团队代码得分, 并且分数不能超过该部分得分上限) -Bonus部分说明如下: +选做部分验收方式为线下验收,你需要在线下检查时提供对应代码通过助教给出的选做部分测试样例,并且讲解你的代码 + +选做部分说明如下: - H班: - 多维数组 - 网安班: + - 多维数组 - 将一维数组指针作为参数 - 逻辑运算(\&\&, \|\|, \!), 重点考察短路计算 - - 多维数组 -Bonus部分得分标准: 每个部分单独给分, 每个部分需要通过全部对应测例并在线下检查时给助教讲清思路才能得分 +### 4.1 多维数组 + +目前给出的SysY IR接口并不支持多维数组的实现,因此你需要修改接口,以实现多维数组的声明、初始化和使用,你可以修改的内容为文件夹`include/SysYIR`,`include/SysYBuilder`,`src/SysYIR`,`src/SysYBuilder`内的所有内容 -若小组完成了Bonus部分, 需在线下检查时向助教提出, 并让助教当场检查. 若在统一线下检查过后自行找助教检查, 该Bonus不算分 +多维数组在目前的接口基础上,一般有两种做法: +- 直接实现,参考 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}}` + +### 4.2 数组指针参数 & 逻辑运算 + +目前给出的SysY IR接口支持数组指针参数和逻辑运算的短路计算,因此你不需要修改接口 +注意`pointer`和`array`的区别以及文法中`&&`和`||`的优先级 + +## 5 备注 测试样例并不止公开的20个样例, 助教准备了许多隐藏测例来考验大家:), 隐藏测例并不会放在平台上 -平台上第三部分的分数并不具有参考性, 第三部分的分数由助教线下检查后确定 + +平台上第三部分的评测只判断公开样例是否完全通过, 第三部分的分数由助教线下检查后根据公开样例和隐藏样例的通过情况确定, 因此请自行设计合法样例测试你们的代码,确保你们的代码考虑了足够多情况以通过尽可能多的隐藏样例 diff --git a/contribution.md b/report/contribution.md similarity index 100% rename from contribution.md rename to report/contribution.md diff --git a/report.md b/report/report.md similarity index 100% rename from report.md rename to report/report.md