Adam Kennedy on PPI

blog.bulknews.netで知ってから(宮川さんに感謝)Perlcastというポッドキャストを聞いていて、その中の表題のインタビュー(25分間)を聞いた。Perlで書かれたPerlの文法解析(parsing)モジュールであるPPIの作者へのインタビューである。表題のリンク先ページの始めのほうの「interview」というリンクからMP3ファイルがダウンロードできる。
Perlには「only perl can parse Perl*1というモットーがあることもあって、Perlの字句解析および文法解析をPerlで記述したものは長らくなかった。PPIはそれをかなりの精度で実現している。インタビューの中で興味深いと思ったのは以下の点である。

現在のものは3つ目の実装

PPIは2回ほぼ一から書き直していて、今のものは最初から数えて3回目に書いたものである。最初の実装は正規表現をベースにしていたが、ある時点から作業が「蜂蜜の中を歩くように」(like walking through honey)非常に困難になり、全体の5%を実装したところでやめた。2回目に書いたものは、一応動いたがとても乱雑(messy)になってしまい、その上に何かを構築することができるとは思えなかった。3回目の実装も基本的に一から書き直したものである。2回目に書いたものを部分部分に分けて流用してはいるが。
これはよくあることで、マイクロソフトでも3回目にやっとまともになることがよくある。最初の実装ではどうやっていいか分からない。2回目の実装では何とか動くものになるが醜悪な実装になる。3回目の実装では依存関係や大きなフレームワークについて考えを及ぼすことができる。なぜなら、2回目の実装ですでにどうやって必要な処理を実装するかは分かっているから。

PPIPerlプログラムを文書として見ている

PPIを実装する上で鍵となったのはPerlプログラムを文書(document)として扱うことである。*2OSCONで会った人々と話をするうちにそういう見地を持つことができ、その結果、全体像が明確になり実装をおこなうことができた。

PPIを使えばPerlプログラムに対する様々な操作を簡単におこなえると思うかも知れないが、必ずしもそうとは言えない。PPIPerlプログラムをプログラムではなく文書ととらえて文法解析のみをおこなっているからである。最初Larry WallPPIをPerl5からPerl6への変換プログラムで使うことを考えていたが、そのためにはPerlプログラムを文書としてではなくプログラムとしてとらえる必要があり、PPIをベースにすることは得策でないことが分かった。

*1:小文字で始まるperlPerlインタープリタを指し、大文字で始まるPerlPerl言語を表わす。

*2:たとえばコンパイラはソースプログラムの文法解析だけをもとにしてコード生成をおこなっているわけではない。識別子の型を記録しておいて、識別子が使われているところのコード生成は、型に応じておこなう。また、定数のみで構成される式の値を計算してその結果を生成したコードに埋め込む。