JavaParser
Javaのパーサを作り始めたのは、今回が2度目です。
前回は、BASIC風のインタプリタを仕事で作ったあとに、Javaのパーサを作りかけたのですが途中で頓挫していました。当時は、LISPみたいに全部をカッコ(java.util.ArrayList)に積み込んで解析していました。先頭にそれ以降を決める予約語を入れてしまい、先頭を見て個々に処理するようにしていました。それはそれでアプローチの仕方としては間違っていないです。
でも今回は別のアプローチでやっています。構文ごとにクラスを作っています。たとえば、クラス宣言は JavaClassDeclarationクラスで、If文は JavaIfStatementクラスで、みたいに。これ、やってみると結構しっくり来るのです。If文もFor文もすべて文(Statement)で、クラス本体はStatementの集まりです。このStatementをインターフェースにすると、実にしっくりくるのです。
class JavaIfStatemet implements JavaStatement { JavaExpression exp; // 式 JavaStatement stat1; // trueのとき実行する文 JavaStatement stat2; // falseのとき実行する文 ... }
このJavaExpressionもインターフェースで、リテラルのtrueとか、式の i<str.length とか、メソッド呼び出しの、in.ready()とか、なんでもOK。
言語って、なんだか宮大工のような(あるいはゼンマイ時計のマイスターのような)職人芸っぽいイメージがあるのですが、class, interface などのバリバリのオブジェクト指向が実にうまくマッチしていてミョーな感じです。セラミック・ギアとかレーザー・ノコギリみたいな「ハイテク爺」みたいな感じです。(なんだそりゃ)構文エラー時の大域脱出もExceptionでラクに実装。デザパタのInterpreterパターンにもぴったりハマり、イイ感じです。言語開発にこんな実装も「アリ」なのか?というぐらい面白い。