本项目的错误处理功能并不完善,仅仅做到了满足课设要求
| 错误类型 | 错误类别码 |
|---|---|
| 非法符号或不符合词法 | a |
| 名字重定义 | b |
| 未定义的名字 | c |
| 函数参数个数不匹配 | d |
| 函数参数类型不匹配 | e |
| 条件判断中出现不合法的类型 | f |
| 无返回值的函数存在不匹配的return语句 | g |
| 有返回值的函数缺少return语句或存在不匹配的return语句 | h |
| 数组元素的下标只能是整型表达式 | i |
| 不能改变常量的值 | j |
| 应为分号 | k |
| 应为右小括号’)’ | l |
| 应为右中括号’]’ | m |
| do-while语句中缺少while | n |
| 常量定义中=后面只能是整型或字符型常量 | o |
| 文件非法结束 | p |
更多的错误形式将以 assertion error 的形式给出。可以看出,上面列出的错误项都集中在前端,因此实现并不复杂。核心问题在于如何在遇到错误时进行正确的跳读,并继续检查源程序中的其他错误。因为课程组规定了一行源代码中最多只有一个错误,因此往往跳读到逗号或分号即可继续递归下降过程。
错误处理的另一个难点是输出错误行号。在最初的前端实现中,词法分析器直接从源程序中读取连续的字符串,完全无法分辨每个 Symbol 属于源程序的哪一行。为了解决这个问题,引入了包装类 InputFile 。包装类每次读入源程序的一行,由此记录行号。而词法分析器直接从包装类读入字符串,因此包装类需要提供输出接口。至此错误处理的全部问题就都被解决了。