Skip to content

Latest commit

 

History

History
44 lines (26 loc) · 2.73 KB

phase1.md

File metadata and controls

44 lines (26 loc) · 2.73 KB

根据project文档,基础功能部分不赘述,the code speaks。

基本样例说明

test_1:人畜无害的样例 test_2:人畜无害的样例 test_3:人畜无害的样例 test_4:Stmt后跟Def,认为是新的CompSt,但是前一个ComptSt没有右大括号闭合,报错 test_5:各种报错的样例

错误恢复

对于词法分析中遇到的错误,若为格式不合法的INT或ID等,我们选择打印报错信息后仍然向bison输出对应的终结符。若为无法匹配的字符,则打印报错信息,并把它和它之后的所有可打印字符(到第一个空格或不可打印字符为止)全部作为ID。

对于语法分析中的错误,我们简单对如下几种错误做了错误恢复:

  • 缺失}(这一条包括定义不在语句块开头的情况。当在上一个CompSt没有结束时遇到定义时,bison会认为这是下一个CompSt的开始,而CompSt中间应该有}{,所以会报出缺失}的错误。)
  • else没有对应if
  • 缺失分号

Bonus功能

单行注释与多行注释

YYSTATE为默认的INITIAL时,lexer读到//时,设置YYSTATESINGLE_LINE_COMMENT,指示单行注释状态,直到遇到换行符或EOF;读到/*时,设置YYSTATESINGLE_LINE_COMMENT,指示多行注释状态,直到遇到*/。注释结束时YYSTATE置为INITIAL

读到EOF时,如果YYSTATEMULTI_LINE_COMMENT,说明多行注释未闭合,报错。

在我们的设计中,出现注释相关的词法错误时不尝试任何错误恢复,立即终止程序。

样例输入输出见test-ex下的1-4组。

一点闲扯,此前考虑如何用input(cpp下是yyinput)和unput做多行注释(虽然最后没这么写有一个原因是觉得用start condition比较优雅),发现需要判一下读到EOF,遂用(c = input()) == -1,然后发现一个拉高血压的玩意,这里提到flex 2.6.4版本下input读到EOF居然是返回0,不知道为什么改成这样也没改回来,那么要判定读到EOF就要和0比,代价就是注释里不能放\x00虽然不会无聊到往里塞\x00,但不让放就是另一回事了

For循环

就,,加产生式。

样例输入输出见test-ex下的5-6组。

Include

Include的实现比较暴力,只是简单的匹配#include<,然后把下一个>之间的所有字符都当作文件名读入。读取文件后,把整个文件直接反向逐字符的用unput()放到flex里面。

这样做的效率应该不会很高,并且无法处理目录问题,但在flex里可能也只能这样了。更好的方式应该是单独写一个preprocessor处理include和宏定义,之后有时间可能会重写这一部分。