[[構文解析の記事一覧]] *目次 [#l4fe96bb] #contents *動機 [#x50d3fc8] スニペットって、短いプログラムのようなものをコンパイルすることだとかんがえると、 構文解析器をつかったほうが、高機能なものをつくれるのではなかろうか。 そんなことを考えました。 だったら、antlrをつかってスニペットツールってつくれないものだろうか とおもって、チャレンジしてみることにしました。 だらだらとかいてあり、さらにわるいことにこの資料は未完成です。すいません。 *完成イメージ [#e9c4552a] スニペット用のキーワード(引数1、引数2) *解析ログ [#cbf0864a] 調べるまでの道筋をメモしながらやっていく。 とりあえず本家をみてみます。 http://www.antlr.org/ Getting started with ANTLR v3をみてみよう。 http://www.antlr.org/wiki/display/ANTLR3/FAQ+-+Getting+Started コマンドラインから動かす方法があるではないか。 http://www.antlr.org/wiki/pages/viewpage.action?pageId=729 ちかごろ、コマンドラインもいいかなーっておもってきたんだよね。 えっこんなんでいいの? java -jar antlr-3.1.2.jar mygrammar.g ためしに、サンプルを動かしてみる。 http://www.antlr.org/download/examples-v3.tar.gz クラスパスの設定いるじゃん。org/antlr/Toolが必要とかいうエラーだ。 よくわらないので、本家 http://www.antlr.org/download.html からダウンロード、おっと、ANTLRWorksをダウンロードしてしまった。 実行してから気がついた。 文法表現でよく使う、表現がチェックボックスで選択できるようになっているのはありがたい。 どうやらComplete ANTLR 3.4 Java binaries jarをダウンロードしてくるべきだったみたい。 あれ、JavaScript runtime distributionってのもあるぞ、Javascriptで動くバージョンかな? 展開すると4つのjsファイルがでてきましたよ。ソースみてみるとSafariで動作確認したと、コメントにかいてある。 これって、これがあればブラウザで構文解析可能になるっていうことだろうか?コンパイルとかの手順ってやっぱいらないんだろうか? いつか調べてみたいが、勝手にダウンロードしちゃいけない作業場所では、すでに、antlrは何らかの形で導入されていることがおおいから、こっちを先にしらべてみたい。 Sampleコードをダウンロードしてみることにした。 解凍してみると、Javaとか、Pythonとか、XMLとか、計算器とかの構文解析例が載っている。。。 見慣れないフォルダ名もあるが、inputってファイルをみると、解析対象がわかる。 たとえば、fuzzyのinputファイルを除くとこんなかんじ import org.antlr.runtime.*; public class Main { public static void main(String[] args) throws Exception { for (int i=0; i<args.length; i++) { CharStream input = new ANTLRFileStream(args[i]); FuzzyJava lex = new FuzzyJava(input); TokenStream tokens = new CommonTokenStream(lex); tokens.toString(); //System.out.println(tokens); } } } simplecTreeParserならばinputファイルは char c; int x; void bar(int x); int foo(int y, char d) { int i; for (i=0; i<3; i=i+1) { x=3; y=5; } } こんなかんじだ。 一番ちいさいのは、hoistedPredicatesフォルダのサンプルで、次は、importフォルダかな。 一番小さいのは、基本がよく分かるので大好きだ。だからこのサンプルから学んでいくことにした。 文法ファイルはT.gだとおもうので、なかをみてみる System.out.println()でくくられた中身をスニペットしたいものに置き換えればいいっておもった。 スニペットに反応させるキーワードは、 stat: identifier {System.out.println("enum is an ID");} | enumAsKeyword {System.out.println("enum is a keyword");} ; enumAsKeyword : {enableEnum}? 'enum' ; のenumAsKeywordに関連する箇所を自分で追加したい分だけ増やせばいいのではないかとおもった。 とりあえず、大体はあくしたから、動かしてみる。 *動かしてみる [#h828f2b9] T.gファイルをみると、コメントに Run "java org.antlr.Tool -dfa t.g" to generate DOT (graphviz) files. と、かいてある。org.antlr.Tool ってなんだ? antlr-3.4-complete-no-antlrv2.jarを拡張子をzipに変換して解凍してみる。あった、あった、classファイルがあった、つまり、コンパイルされている状態で格納されていました。 これを使うようにするには、同じディレクトリに置くとかすればいいのかな。 やってみたコマンド java -jar antlr-3.4-complete-no-antlrv2.jar t.g 結果 error(8): file t.g contains grammar T; names must be identical エラー orz こんな簡単なサンプルさえ動かせないなんて。。。 正解はこちら java -jar antlr-3.4-complete-no-antlrv2.jar T.g ファイルの大文字と小文字をきっちり合わせないとだめなんですね。 Javaのソースコードがでてきた。 -T.tokens -TLexer.java -TPaser.java *コンパイルしてみる。 [#n61e026f] javac -cp antlr-3.4-complete-no-antlrv2.jar Main.java TLexer.java TParser.java *実行してみる [#bb40ac7f] java -cp .;antlr-3.4-complete-no-antlrv2.jar Main input おおっenum is anIDって出た。 *前のバージョンantlr-2.7.2.jarでもやってみる [#a1b7acd0] ネットも外部ディスクも使えない作業場には、antlr-2.7.xがあるようなので、こやつをどうにか使えないものかということで、前のバージョンでもどうさするか確認してみる。 strutsとかにはいっているantlr-2.7.2.jar では動くかな だめだ、org.antlr.runtime.CharStreamが無いといわれた。 java -jar antlr-2.7.2.jar T.g ではどうか? Failed to load Main-Class manifest attribute ってでた。 java -classpath antlr-2.7.2.jar antlr.Tool T.g 動いたっぽいけど、文法が違うらしい。ちなみにこんなエラー T.g:9:1: unexpected token: grammar error: Token stream error reading grammar(s): T.g:11:1: unexpected char: '@' T.g:9:1: rule classDef trapped: T.g:9:1: unexpected token: grammar error: aborting grammar 'unknown grammar' due to errors TokenStreamException: unexpected char: '@' antlr-2.7.2のサンプルでやってみるべきだろう。 http://www.antlr2.org/ からGetting Startedをたどってt.gのサンプルをみる class P extends Parser; startRule : n:NAME {System.out.println("Hi there, "+n.getText());} ; class L extends Lexer; // one-or-more letters followed by a newline NAME: ( 'a'..'z'|'A'..'Z' )+ NEWLINE ; NEWLINE : '\r' '\n' // DOS | '\n' // UNIX ; 解説サイトには java antlr.Tool t.g とかいてあるが、実際には、 java -classpath antlr-2.7.2.jar antlr.Tool t.g で動く。 つくられたファイルは、 -L.java -P.java -PTokenTypes.java -PTokenTypes.txt である。 **実行用Main.java [#a6cfaf82] 実行用のメインクラスが掲載されていたのでつくる import java.io.*; class Main { public static void main(String[] args) { try { L lexer = new L(new DataInputStream(System.in)); P parser = new P(lexer); parser.startRule(); } catch(Exception e) { System.err.println("exception: "+e); } } } コンパイルする javac -classpath antlr-2.7.2.jar *.java 実行する java Main では、エラーになる。クラスパスがただしくないのだろう。 java -classpath .;antlr-2.7.2.jar Main で標準入力を受け付けているので、自分の名前を入力すると Hi there, hogehoge よし、サンプルの動作を確認した。 これで、前のバージョンをつかって、構文解析器をつくれるめどがたったな。 *ANTLR v2 to v3 converter [#c981a7e8] antlr2からantlr3への変換ツールがあるようだ。 http://www.antlr.org/download.html