ANTLRで生成したパーサーで構文解析

前回の続きです。


JavaParser.csとJavaLexer.csを使ってみましょう。
まずはVisualStudioでC#のコンソールアプリケーションプロジェクトを作成してください。


JavaParser.csと同じ階層に作成するとパーサを作り直したときeclipseに消されてしまうので気をつけてください。
今回はJavaParser.csのある階層に1つディレクトリを作りその中にプロジェクトを作成しました。


パースするにもANTLRのランタイムが必要なので以下のページのDOT-NET-runtime-3.1.3.zipをダウンロードしてください。
http://www.antlr.org/download/CSharp
zipを解凍しておきます。


次にこれをC#プロジェクトに追加します。
ソリューションエクスプローラの参照設定を右クリックし、参照の追加でzipに含まれていたすべてのdllを選択し追加してください。
Antlr3.Runtime.dll Antlr3.Utility.dll antlr.runtime.dll StringTemplate.dll


JavaParser.cs JavaLexer.csも追加します。
このとき次の手順を踏むとソースをコピーせずプロジェクトに追加できます。
プロジェクトを右クリックし[追加]、[既存の項目]と進み、先の2つの.csを選択し、追加ボタンの右の三角形をクリックし、リンクとして追加を選択します。
ソリューションエクスプローラ上で2つのファイルのアイコンに矢印が付いていればコピーでなく参照として追加されたことがわかります。



ここでパースするコードを書こうと思っていたのですが、いくつかコンパイルエラーになってしまいます。
.gファイルを修正しましょう。

上の方にある@lexer::membersを以下のように修正してください

@lexer::members{
  protected bool enumIsKeyword = true;
  protected bool assertIsKeyword = true;
}

これはJavaLexer.csクラスのメンバとしてそのまま出力されます。
ですのでjavaの組み込み型であるbooleanでなくC#の組み込み型であるboolへの直しておきましょう。


続いて、Treeの実装と.gに書かれたTreeを使ったコードがかみ合わずエラーとなるので修正します。

$t1.getLine()や$t2.getLine()などは$t1.Line $t2.Lineとします。
C#ではLineがメソッドでなくプロパティとして提供されています。
同様にgetCharPositionInLine()はCharPositionInLineに直します。


最後にパースするコードを書きましょう。

//ファイルの読み込み
string filename = @"test.java";
Antlr.Runtime.ANTLRFileStream fs = new Antlr.Runtime.ANTLRFileStream(filename);

もしくは

Antlr.Runtime.ANTLRStringStream fs = new Antlr.Runtime.ANTLRStringStream(@"
class Main{
    public static void Main(String[] arg){
        int test = 0;
        System.out.println(test);
    }
}
");

として直接ソースを書きます。
ANTLRFileStreamもANTLRStringStreamもICharStreamのサブクラスですのでどちらでもかまいません。

残りのコードは以下のようになります。

JavaLexer lex = new JavaLexer(fs);
Antlr.Runtime.CommonTokenStream tokens = new Antlr.Runtime.CommonTokenStream(lex);
JavaParser parse = new JavaParser(tokens);
parse.compilationUnit();

ここでcompilationUnit()は構文のルールの中でももっとも最上位の物です。
このメソッドの戻り値から構文木を取得することが出来ます。

ここで意味でなく構文が無効となるソースを書いてどのようになるか試してみましょう。
たとえばclassをclasとすると構文解析に失敗します。
line 2:0 no viable alternative at input 'clas'
とコンソールに出力されると思います。

問題なく構文解析された場合はコンソールへの出力がありません。


今回は構文解析のみですのでここで終わりです。
コンパイラなどの作成には構文木を使用するようです。その辺はおいおい勉強して行こうと思います。

eclipseでANTLRを使うためのインストールメモとビルド

ANTLRとはパーサジェネレータです。

ANTLR - Wikipedia

yacc、bison、JavaCCの類のやつですね。
ANTLRはEBNFのような形式の文法ファイルから、
レキサー(スキャナー)とパーサーを生成します。


詳しくはWikipediaや後述するANTLR IDEのページを参照してください。


eclipseANTLRを利用するにはプラグインを導入すればよいですが、いくつか種類があります。
今回はANTLR IDEというのを入れます。
"新規ソフトウェアのインストール"でインストールするのですが、eclipse3.6のインストールもあわせてメモしておきます。

eclipse3.6 Helios ダウンロード

3.6はHeliosっていうらしいです。
Eclipse Downloads | The Eclipse Foundation
Eclipse IDE for Java Developersをダウンロードしましょう。
解凍するとeclipseというディレクトリが作成されます。

日本語化プラグイン ダウンロード

日本語化はEclipse 日本語化 | MergeDoc Project
"Pleiades 本体ダウンロード"から"安定版 1.3.2"をダウンロード。
中身をeclipseディレクトリへ。


eclipseディレクトリにあるeclipse.iniの最後に
-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
を追記します。
日本語化のプラグインを入れた直後は"eclipse.exe -clean.cmd"というファイルがあるのでダブルクリックしてeclipseを起動します。
それ以降はeclipse.exeを起動しても問題ないと思います。


Eclipse 日本語化 | MergeDoc Projectでは日本語化が済んだ状態のeclipseも配布されていますので、そちらを使用してもいいかもしれません。
"Eclipse 3.6 Helios Pleiades All in One"と書かれたボタンが上の方にあるのでそれをクリックし次のページの"Full All in One(JRE あり)"の"Java"のDownloadからダウンロードできます。(今回はこちらでは試していませんが多分一緒だと思います)

ANTLR IDE インストール

eclipseのヘルプの新規ソフトウェアのインストールで以下のアドレスを入力してインストールしてください。
http://antlrv3ide.sourceforge.net/updates

ANTLR ランタイム等 ダウンロード

Download ANTLRからComplete ANTLR 3.2 jar; all tools, runtime, etc...をクリックしantlr-3.2.jarをダウンロードしておきます。


さて、準備はこれくらい。
文法ファイルを用意しましょう。

Javaの文法ファイルをダウンロード

http://www.antlr.org/grammar/listからJava 1.5 grammar を落とします。(1.6はなんかうまくいかなかった)

プロジェクトの作成

適当にeclipseのプロジェクトを作成します。
先ほどダウンロードしたantlr-3.2.jarとJava.gをここに入れておきます。
右クリックしてメニューを出し、構成からConvert to ANTLR Project...でANTLRのプロジェクトへコンバートしましょう。

ビルド

eclipseJava.gをダブルクリックして開くとNo package definedというタイトルのダイアログが出るのではいを選択してください。
Installed Packagesの枠内の追加...を選択
ホームのディレクトリー...でantlr-3.2.jarのを置いたディレクトリを指定。OKします。


今回はC#でパーサを作成しようと思うので、Java.gを一部書き換えます。
optionsに以下の記述を加えます。

  language = CSharp;
  output = AST;
  ASTLabelType = CommonTree;

languageの指定はパーサを記述する言語です。
下の2つの指定は構文木を生成する指定です。


問題なくビルドできれば
Java.tokens[Java.g]
JavaLexer.cs[Java.g]
JavaParser.cs[Java.g]
これらが生成されていると思います。



次回、生成したパーサでソースコード構文解析します。
あくまで構文解析。意味解析をするわけでもましてコンパイルするわけでもありません。


続きを書きました

人類は衰退しました 4巻感想


また奇妙な生き物が出てきました。
妖精が作ったものではあるんですけど。
表情がわからなかったり、感情が読めない生き物は不気味です…
田中ロミオさんはそういう世界を作る人なんでしょうかね。この人がシナリオを書いたゲームはプレイしたことがないので作風はよくわかりませんけど。


工場の話は腑に落ちませんでした。問題視して調査に乗り出したのに最終的に解決もせず、それを許容してしまっているというか。
ま、死活問題だし特に害がないとなればそれで良いとされたのかもしれませんけど。


漂流のお話は良いですね。発想がすごいなと思いました。
本質はどうでもよく見た目や味がそれと認識できればそれになってしまうってことですよね。枝豆とかw
話の締めはもう少し妖精にとってハッピーエンドであってほしかったという気はしましたけどね。


5巻は半分以上読み進めているので近いうちに。

人類は衰退しました 4 (ガガガ文庫)

人類は衰退しました 4 (ガガガ文庫)

人類は衰退しました 3巻

昨日読み終わりました。


この娘…… むちゃしすぎです><
そんな3巻は1つのお話です。


2巻の初登場時と違って、助手さんのキャラクターが見えました。
得体の知れない存在から無口だけれど普通の男の子なんだなーという印象に変わりました。


主人公はとても強い子だなと思います。たくましすぎます。


まー そんな感じです。

人類は衰退しました 3 (ガガガ文庫)

人類は衰退しました 3 (ガガガ文庫)

えむえむっ! 1巻感想

言いたいことは大体あとがきに書いてありますww


(俺が)タイトルだけ知ってたシリーズのうちの一つえむえむっ!です。
10巻くらい出てるものだと書店で目に付くので覚えてたりします。
見本を読んでなかなかに主人公がぶっ飛んでいるのでその場で購入しました。


普通に変態でおもしろい作品だと思います。

人類は衰退しました 1巻 2巻感想

2週間くらい前に読了


タイトルが気になっていたので購入。とある知り合いは田中ロミオの作品はおもしろいと言っていました。AURAを勧められました。とりあえず積みました。


タイトルからイメージしたのは人類が自らの過失で絶滅の危機に追いやられ、残り少ない人々が細々と暮らす楽しさのかけらもなさそうな物語だったのですが、まったく違うものでした。
サイエンスフィクションファンタジー?というのかは知りませんが妖精が出てきます。
たくさん。


ちっちゃい!かわいい!おもしろい!


とは言うものの、1巻はそうでもないのですが、2巻のよくわからない犬の描写には言い知れぬ恐怖を感じました。
不思議な出来事が起こり最後には解決したのかしてないのかよくわからない終わりを迎えます。解決してますよ?ぼくのりかいりょくがたりないだけです?
今3巻を読んでいますが毎回舞台は異なります。楽しめます。

俺の妹がこんなに可愛いわけがない 6巻感想

ひと月くらい前に読了
ネタバレとかあるかも。


3巻あたりまでは普通におもしろいと、とある知り合いは言っていました。
それ以降の高坂京介はただのシスコンではないかと。


そんなことないのにと思っていたのは5巻まででした。
6巻の京介さんちょっと気持ち悪いですwww
というのも序盤だけでいつもと変わりありません。桐乃も戻ってきましたしね(海外にいたの5巻だよね…)
妹のことを嫌いだと言いつつも実は好きだという、なんかその辺の感じが化物語阿良々木暦に似てるといつも感じます。