Eclipse/CDTでASTを使ってソースコードの構造を得る(最新版).

先日のTOPPERSハッカソンで青ざめ,乗り越えた顛末.

最初は,TOPPERS/JSP1.4.4 のリリースに向けた作業をしようかと思っていたのだけれど,参加者を見ていて,これはテストスイートの試作をしてみたほうが面白いのではないかと考え直した.

他の言語向け(特にLL向け)のテストスイートに比べてC言語のそれで一番面倒なのは,テストスイートの作成.Cutter では,共有ライブラリを使うことで面倒を解消しているけれども,TOPPERSのような規模で共有ライブラリは望めない.
そこで,ワタクシお得意CDTを使うべな,ということを思いついた.

CDT は,ソースコードを AST (Abstract Syntax Tree)に分解する機能を持っている.これを使えば関数名の抽出などはお手の物である.…ということは知っていた.

参考情報

グーグル先生にお伺いを立てると,情報が得られる.

日本語だと,例えば,
http://www.ibm.com/developerworks/jp/opensource/library/os-ecl-cdt3/
ここは難解だが,CDTの内部を知るためには必読

「CDTのパーサーを他の用途で使う」というエントリも見つかる.
http://munepi.cocolog-nifty.com/blog/2009/05/cdt-28c0.html
http://munepi.cocolog-nifty.com/blog/2009/05/cdt-daf0.html

なんとかなるもんねー,と思ったのだが,甘かった.

CDTの進化

結論から言うと,上記の「CDTのパーサーを他の用途で使う」は,古いCDT (おそらく3.x系)でのみ有効である.最近のCDTで使おうとすると,obsolete だったり internalパッケージだったりして使えない.


ハッカソン開始後に気づいて真っ青になった.

それへの追随

どう調べたとかいうのは端折って,結論だけ書く

	ITranslationUnit tu = (ITranslationUnit) CoreModel.getDefault().create((IFile)resource);
	IASTTranslationUnit ast = tu.getAST();
	ASTVisitor visitor = new ASTVisitor(true) {
		public int visit(IASTDeclarator decl) {
			/* do something */
			return ASTVisitor.PROCESS_CONTINUE;
		}
	};
	ast.accept(visitor);

以前は,IASTTranslationUnit が Java と微妙に違ったりしたのが,統一的になり割とスッキリしている.本来的には歓迎しなければならないところと思う.けれども現場技術者としては,壮大な仕様変更に,やるかたない気持ちがしなくもない.



builder の中なので,resource の型は,IResource.上の例に挙げた ASTVisitor.visit() の引数型は,IASTDeclarator なので,関数宣言があったときに呼び出される.他の要素で引っかけたいときには,ASTVisitor にある,大量の visit() を参照するとよい.

というわけで

一瞬,真っ青になったが,ハッカソン終了までには,なんとかソレっぽいものを仕上げることができた.CDT怖い.