プロジェクトライブラリ
授業・卒業制作Google · Software Engineering Intern · 2023

コンパイラの授業で作ったCのサブセット向けトイコンパイラのフロントエンド

投稿者:R. Nakamura · 元Google SWEインターン

共有者はGoogleのインターン面接でこのプロジェクトを説明し、その後内定を獲得しました。

この面接を練習する

実際の深掘り4問 · うち難問2 · 約12分

各質問に自分で答えると、本人の実際の答えが見られます。

本人はこう語った

コンパイラの授業のプロジェクトで、Cのサブセットを対象にlexerとparserを書きました。面接では1つの判断に焦点が絞られました。なぜrecursive descentなのか、そして私の文法がどこでこっそり手を抜いていたのか、です。

全文を読む

コンパイラの授業のプロジェクトでした。目標はCの小さなサブセットに対する動くフロントエンドを作ってASTまで到達することで、スタックベースのIRへのcodegenはパートナーが担当し、私はlexerとparserをやりました。lexerは手書きで、parserはrecursive descent(再帰下降)で書きました。パーサジェネレータではなくrecursive descentを選んだのは、主に自分が理解していてデバッグできたからで、文法も小さかったので問題になりませんでした。手を抜いたのは式の優先順位です。Cの優先順位表をきれいに全部エンコードする代わりに、いくつかのレベルをハードコードし、一部の演算子は単にサポートしませんでした。エラーメッセージもひどく、間違ったトークンを指していました。授業のテストケースで動かしてほとんど通りましたが、授業の外で使った人はいません。面接では深掘りが一気に具体的になり、特に演算子の優先順位と左再帰の扱いを突かれました。サポートしたレベルにはprecedence climbingを使い、時間がなかった演算子は単に省いた、完全にカバーしているとは主張しない、と正直に話しました。刺さったように見えたのは、parserが何を受理し何を受理しないかを正確に言えたことと、エラー処理が一番弱い部分だと認めたことでした。

実際に聞かれた質問

なぜyaccのようなパーサジェネレータではなくrecursive descentにしたのですか?

易しい

演算子の優先順位と結合性はどう扱いましたか?

難しい

recursive descentは左再帰を直接扱えません。どこで苦労しましたか?

難しい

一番弱かった部分と、最初に直すとしたら何ですか?

普通