シーマークすずきです。
antlr4について少しメモをまとめておく。
- antlr4とは
ANTLR (ANother Tool for Language Recognition)は強力なコンパイラコンパイラです。コンパイラとは、簡単に言えば、人が理解しやすい表現の記述から、目的に合わせてコンピュータが処理しやすい形式に変換することです。コンパイラは通常次のステップを行います。まず初めに、「元になるソースから構造を発見する」次に「目的に合わせて変換」します。後者の目的部分は、各コンパイラプログラムによって様々ですが、初めのステップは、一般的には更に次の処理に分割されます。
- ソースからトークン(token)に分割・分解し、トークンを発掘する(字句解析)
- 複数のトークンを構文に従って木構造に構造化(組み上げ)する(構文解析)
コンパイラコンパイラは、上記の字句解析と構文解析するコンパイラプログラム(別名パーサーと呼ばれています)を作成するためのコンパイラです。ANTLRを使い、構文定義(grammarファイル)を記述し、その定義に従って、つまり、grammarファイルをソースにして字句解析し構文解析するためのプログラムソースを生成してくれます。開発者は目的に応じて木構造を捜索したり、変換したりすれば良いのです。ANTLRをパーサージェネレーターと呼ぶ場合もあるようです。
- 何ができる?
たとえば、JavaやC++のソースをパースするプログラムを作成することも可能です。他にも、日本語で「式」を定義し、それを計算するというプログラムも作成できます。”(上底 + 下底) * 高さ / 2.0”などの式の文字列をパースして、意味のある単位の「変数」や「演算子」や「括弧」のトークンに分割し、定義した優先順位でトークンを組上げて、それを順番に変数を数値変換して計算を行うための計算機プログラムを作成することもできます。
- 使ってみる
パーサーは文法が定義できればほぼ何でも作成できます。HTML、JSONなどのデータファイルをパースするプログラムも面白いですが、ここでは、簡単なcsvのパーサーを作成してみましょう。まず初めに文法定義をします。以下に簡単なcsvのantlr4の文法定義です。CSV.gとファイル名を付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | grammar CSV; file: hdr row+ ; hdr : row ; row : field (',' field)* '\r'? '\n' ; field : TEXT | STRING | ; TEXT : ~[,\n\r"]+ ; STRING : '"' ('""'|~'"')* '"' ; // quote-quote is an escaped quote |
CSVファイルの構造の定義をしています。CSVファイルは、ヘッダー(hdr)と複数の行(row)でできている、としています。複数個(0個以上)の行である表現は’+’が付いているからです。次に、ヘッダー(hdr)は1行(row)で構成されると定義しています。行(row)の定義です。行はフィールド(fieldがカンマ(,)で区切られて複数あること、行の終端は’\r”\n’或は’\n’である、と定義しています。’*’は0回以上の繰り返しです。定義はまだ、続きます。フィールド(field)はTEXTかSTRINGのいずれかで構成されると宣言しています。TEXTは、カンマ(,)か(’\n’)か(‘\r’)の何れでもない文字の0個以上の繰り返しです、としています。つまりTEXTは数値や英数文字も全てです。STRINGは、ダブルクオートで囲われていて、連続する2つのダブルクオートか1つのダブルクオート以外の全ての文字です。
文法定義ファイルをantlr4コマンドに以下のようにわたします。
> antlr4 CSV.g
> ls
CSV.g CSV.tokens CSVBaseListener.java
CSVLexer.java CSVLexer.tokens CSVListener.java CSVParser.java
生成されたJavaソースをjavacでコンパイルします。早速、antlr4の検証ツールgrunで試してみましょう。
> grun CSV file -tree
user.name, user.age, *omit*user.gender
suzuki,50,male
ange,12,female
seamark,20,male
Control+Dで、以下がコンソールに出力されます。
(file (hdr (row (field user.name) , (field user.age) , (field *omit*user.gender) \n)) (row (field suzuki) , (field 50) , (field male) \n) (row (field ange) , (field 12) , (field female) \n) (row (field seamark) , (field 20) , (field male) \n))
階層をGUI表示させたい場合は、-treeを-guiとします。
> grun CSV file -gui
user.name, user.age, *omit*user.gender
suzuki,50,male
ange,12,female
seamark,20,male
Control+Dで以下の画面表示がされます。
- 今後
次回は、grunを使わずに、javaプログラムからantlr4で生成したソースを呼び出して利用してみます。