2026BUAA编译原理期中考试题目回顾
Contents
题目
以下内容为回忆版
新增文法如下:
// 新增MatchExp
PrimaryExp -> '(' Exp ')' | LVal | Number | MatchExp
MatchExp -> 'match' '(' Cond ')' '{' { MatchArm } '}'
MatchArm -> 'when' Number '->' Exp ';' | 'otherwise' '->' Exp ';' // 保证otherwise只有一个
// 新增Unless语句
Stmt -> ...| 'unless' '(' Cond ')' Stmt |...新增Token如下:
| Token | Content |
|---|---|
| MATCHTK | match |
| WHENTK | when |
| OTHERWISETK | otherwise |
| UNLESSTK | unless |
| ARROW | -> |
一个可能的题解
以下内容基于本人的CPP实现,不代表通用情况
- 词法分析阶段,在Token列表中注册新增Token
- 语法分析阶段
- 注册新增类
MatchExp和MatchArm,新增解析函数parseMatchExp()和parseMatchArm(),在isExpStart()中新增MATCHTK,在parsePrimaryExp()中新增判断并调用parseMatchExp(),随后递归下降完成parseMatchExp()和parseMatchArm() - 扩展解析函数
parseStmt(),在isStmtStart()中新增UNLESSTK,在parseStmt()中新增判断并递归下降完成对unless语句的解析。
- 注册新增类
考场上写出来的Bug
- 在parsePrimaryExp()中判断类型时,只写了if(type == MatchExp),而没有在前面根据peek()的类型对type进行赋值(天知道我debug了多久……因为我的type默认是Number,我真的很奇怪他到底怎么跳转到parseNumber然后抛出异常没有Number的,反正终于在和clion没有许可证每过半小时就自动退出软件和为了跳过step into进入c++头文件而点击step over结果点过头直接跳到异常的斗争中定位到了bug啊啊啊啊啊)
- ‘->‘识别成’-’:我对两个字符的运算符的判断方法是在宏定义时就将他们写在前面,后面展开成数组时也在前面,匹配时就优先匹配了两个字符的运算符,但是我忘记了这个事情……这个bug还是比较好改的。
- 没有在isExpStart()中新增MATCHTK:这个在题干中有提示,但是貌似没有看到而且忘记改的不止我一个……而且令我百思不得其解的是我应该改了isStmtStart(),为什么能想起来一个而想不起来另一个,还是说这个我也没想起来但是侥幸测试点没有这个(不是没有可能,因为这个函数没有改只会影响switch case语句中case:和default:后面是一个unless语句),还是说我并没有通过全部的测试点而我以为我通过了……算了算了,洗洗睡吧。