diff --git a/Reports/lab1/report.md b/Reports/lab1/report.md index cd75c3cb7094319b76160a5d65cf4e2f387a4f55..3c011615ac5b0d46843a0ff18e274b3c0525685b 100755 --- a/Reports/lab1/report.md +++ b/Reports/lab1/report.md @@ -1,8 +1,69 @@ # lab1实验报告 -学号 姓名 + +202108010307 林子钦 + ## 实验要求 + +​ 本次实验需要各位同学根据cminux-f的词法补全lexical_analyer.l文件,完成词法分析器,能够输出识别出的token,type ,line(刚出现的行数),pos_start(该行开始位置),pos_end(结束的位置,不包含)。如: +文本输入: + +![image-20231118001925953](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118001925953.png) + +则识别结果应为: + +![image-20231118001932628](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118001932628.png) + +具体的需识别token参考lexical_analyzer.h +特别说明对于部分token,我们只需要进行过滤,即只需被识别,但是不应该被输出到分析结果中。因为这些token对程序运行不起到任何作用。 + ## 实验难点 + +1.环境的搭建与配置,按照推荐的WSL的ubuntu20.04的方式搭建环境略麻烦。 +2.学习掌握cminus-f语法,以此构建正则表达式在该语言上的准确表达形式。这种语言与C语言有一定差别。例如注释方式的差别,以及浮点数可接受的范围与形式和C不相同,而整数不包含负整数。 + ## 实验设计 + +1.实验要求能够识别出所有的输入token,但并不是所有的内容都需要识别。具体需要识别的token在 lexical_analyzer.h 定义了,将token进行对应含义的注释后结果如图所示 + +![img](file:///C:\Users\Lenovo\AppData\Local\Temp\ksohtml7568\wps1.jpg)![img](file:///C:\Users\Lenovo\AppData\Local\Temp\ksohtml7568\wps2.jpg) + +2.以此为基础,写出C-Minus文法下对应的正则表达式与对应的动作。 +(1)根据实验文档给出的词法,构建各token的正则表达式。其中,对于运算符和关键字,分别为英文状态下的符号和小写;对于ID和NUM,[a-zA-Z]表示在a-z和A-Z选一个而多个为[a-zA-Z]+,[0-9]+表示一个或多个整数,[0-9]+\.[0-9]+这种拼凑起来的表示小数,\[\]表示数组(单独的则就只是符号,两个一起才是数组);对于其他符号,空白符可有多种表达方式,但别的不太清楚,暂以\s为对应的正则表达式,而注释符/* */最难解释,在\/\*之后结尾之前如果有*存在(如/***123***/)就不能直接跟\*\/而要用[^\*]表示中间部分(这里\可代表除*的所有字符),用或语句分割开来,后面不接*/,最终为\/\*([^\*]|(\*)*[^\*\/])*(\*)*\*\/。 +最终表示结果如图 + +![img](file:///C:\Users\Lenovo\AppData\Local\Temp\ksohtml7568\wps3.jpg)![img](file:///C:\Users\Lenovo\AppData\Local\Temp\ksohtml7568\wps4.jpg) + +(2)正则表达式对应的动作部分有两步,一步是更新lines、pos_start、pos_end等参数,首先将开始位置和结束位置设置成一样,代表当前识别的字符从上一识别完的字符的末尾开始。接着设置pos_end+=strlen(yytext) ,strlen(yytext)为这次识别到的长度;另一步是将当前识别的结果进行返回,即return。 +如图所示 + +![image-20231118002025837](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118002025837.png) + +3.补充C语言对应的代码analyzer + 在上一步的代码中,就已经实现了EOL换行、BLANK空格的动作,这里要完成的是COMMENT注释。将注释单独拿出来是因为由于注释可以分为多行,故需要在识别到注释时,进行额外分析,分析其内所含的换行符\n。遍历字符串,如果识别到换行符,则将lines加1,重置pos_end,如此循环。(在动作中处理了return的动作所以不需要做相关变化) +代码如图 + +![image-20231118002043143](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118002043143.png) + ## 实验结果验证 -请提供部分自己的测试样例 -## 实验反馈 \ No newline at end of file + +1.按照实验文档给的提示编译成功 + +![image-20231118002050767](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118002050767.png) + +2.输出结果和标准一致,通过了六个案例 + +![image-20231118002055157](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118002055157.png) + +3.将自己结果和助教结果比较,结果如图 + +![image-20231118002102286](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118002102286.png) + +4.用自己的测试案例进行测试,代码如图 + +![image-20231118002107204](C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231118002107204.png) + +该段代码成功跑通,分别对<=,>,>=,==,=,三种 [ ] token,变量名、嵌套的注释进行测试,结果无误。 + +## 实验反馈 + +​ 本次实验的实验收获很多,首先对于正则表达式在新文法中的各种写法有了深刻的认识,比如注释的写法就让人头痛过一会,而在理解了之后还是明白了;浮点数等的特殊方式以及不接受负数的整数也是让我印象深刻。说实话一开始尝试这个实验还是有些蒙的,一开始在win10上使用WSL,但唯命令行的界面和全部指令从零开始在折磨了一段时间之后还是将我劝退回到虚拟机镜像,发现对于已经有虚拟机的还是直接用虚拟机好用。最后测试样例通过了,成功完成了实验,有了一定的成就感。 \ No newline at end of file