構文解析の記事一覧

目次

動機

スニペットって、短いプログラムのようなものをコンパイルすることだとかんがえると、 構文解析器をつかったほうが、高機能なものをつくれるのではなかろうか。 そんなことを考えました。 だったら、antlrをつかってスニペットツールってつくれないものだろうか とおもって、チャレンジしてみることにしました。

だらだらとかいてあり、さらにわるいことにこの資料は未完成です。すいません。

完成イメージ

スニペット用のキーワード(引数1、引数2*、キーワード(引数))

仕様としては 引数を指定することが可能で *文字をいれるとスニペット挿入後のカーソル位置を指定できる

といったところかな。

入れ子条の関数を認識してスニペットを展開可能とする

なぜならば、スニペットする文字には、引数が必要なものが少なからずおおいからなのです。

挿入後のカーソルのポイントも指定できるようにもする。

解析ログ

調べるまでの道筋をメモしながらやっていく。

とりあえず本家をみてみます。

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?に関連する箇所を自分で追加したい分だけ増やせばいいのではないかとおもった。

とりあえず、大体はあくしたから、動かしてみる。

動かしてみる

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のソースコードがでてきた。

コンパイルしてみる。

javac -cp antlr-3.4-complete-no-antlrv2.jar Main.java TLexer.java TParser.java

実行してみる

java -cp .;antlr-3.4-complete-no-antlrv2.jar Main input

おおっenum is anIDって出た。

前のバージョンantlr-2.7.2.jarでもやってみる

ネットも外部ディスクも使えない作業場には、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

で動く。

つくられたファイルは、

である。

実行用Main.java

実行用のメインクラスが掲載されていたのでつくる

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

antlr2からantlr3への変換ツールがあるようだ。

http://www.antlr.org/download.html

文法的なことを知りたければ、

http://www.antlr.org/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3

をみてみることにする。

yasnippetってどんなつくり

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-11-26 (土) 07:41:30 (2795d)