项目库
课程 & 毕设Google · 软件工程实习生 · 2023
编译原理课上给 C 的一个子集写的玩具编译器前端
分享者:R. Nakamura · 前 Google 软件工程实习生
分享者在 Google 实习面试里讲了这个项目,后来拿到了 offer。
走进这场面试
4 个当年真实追问 · 2 个 hard · 约 12 分钟
答完每一题,才翻开当事人当年的接法。
他们当时是怎么讲的
我为编译原理课的项目写了词法分析器和语法分析器,目标语言是 C 的一个子集。面试聚焦到了一个决定上:为什么用递归下降,以及我的文法在哪儿悄悄耍了赖。
展开全文
这是我编译原理课的项目。目标是给 C 的一个小子集做一个能跑的前端,最终产出一棵 AST,搭档负责生成到基于栈的中间表示(IR)的代码,我做词法和语法分析。词法分析器我手写的,语法分析器写成了递归下降。我选递归下降而不是用生成器(parser generator),主要是因为我懂它、也能调它,而且文法够小,用哪个都无所谓。我偷懒的地方在于:表达式优先级。我没有把 C 完整的优先级表干净地编码进去,而是硬写了几个层级,有些运算符干脆就不支持;而且我的错误信息很烂,会指向错误的 token。我们拿课程的测试用例跑,大部分都过了;课外没人用它。面试里追问很快就具体了起来,尤其是我怎么处理运算符优先级和左递归。我很坦白地说,我支持的那些层级用的是优先级爬升(precedence climbing),没时间做的运算符就直接省掉了,没有硬说自己做了完整覆盖。真正让人买账的,似乎是我能精确说出这个分析器接受什么、不接受什么,并且承认错误处理是最弱的一环。
当年真实被问到的
为什么用递归下降,而不是像 yacc 那样的语法分析器生成器?
简单你是怎么处理运算符优先级和结合性的?
困难递归下降没法直接处理左递归。这一点在哪儿把你坑了?
困难最弱的地方是哪儿,你会最先修什么?
中等