Chapter1. Meet ANTLR^2

1.2 Executing ANTLR and Testing Recognizer

Hello.g4は"hello parrt"、"hello world"のようなフレーズを認識する*1簡単な文法

grammar Hello;
r  : 'hello' ID ;
ID : [a-z]+ ;
WS : [ \t\r\n]+ -> skip ;
  • grammarに続く"Hello"が文法名ANTLRでは文法を格納したファイル名は文法名+.g4"という決まりがあるので、このファイル名は"Hello.g4"とする。
  • 英小文字で始まるrは構文解析の規則。":"の右側がその定義。"hello"の後にIDが続く入力がこの規則とマッチする。
  • 英大文字で始まるID,WSは字句解析の規則。WSの"-> skip"は、マッチしたら読み飛ばすことを指示している。

これをANTLRコンパイルすると以下のファイルが生成される。

ファイル名内容
Hello.g4元になった文法ファイル
Hello.tokens文法で使われているトークンの定義
HelloLexer.java字句解析プログラム(レキサー;lexer)
HelloLexer.tokenslexerで使われているトークンの定義
HelloParser.java構文解析プログラム(パーサー;parser)
HelloListener.javaリスナーのインタフェース定義
HelloBaseListener.javaHelloListenerを実装したクラス。このクラスを継承してリスナープログラムを作る。

このように文法ファイルからLexarとかParserを自動生成してくれる。Listenerも作ってくれるが、Visitorはオプションで指定しないと生成されない。あとこれらを起動するメインプログラムも作ってくれない。その代わり、ANTLRはここで生成したLexar/Parserの動作を確認するのに便利なTestRigというプログラムを用意している。これに引数として文法名、処理を開始する規則名、その他オプションを渡すといろいろな情報を表示してくれる。たとえば-tokensを渡すと認識したトークンの情報を表示する。

例えば

[@1,6:10='parrt',<2>,1:6]

の場合、

TestRigの出力内容
@12番目のトークン(先頭は0)
6:106~10文字目(先頭は0)
parrt文字列
<2>トークンタイプ2(Hello.tokensでID=2と定義されている)
1入力の1行目(先頭は1)
66文字目(先頭は0;tabは1文字扱い)

を表している。

また-guiオプションを指定すると、以下の様なダイアログを表示する。これは構文解析木で、文法が入力をどのように解釈したか一目でわかる。と言っても、こんな単純な例ではイマイチ便利さがわからないけど、文法が複雑な場合で、意図した通り字句が認識されているか?規則がどのような順番で適用されたか?といった確認をするとき役立ちそう。

f:id:ooparts77:20150429205911p:image

そのほかにも構文解析木をLISP風にテキスト表示する-treeとかもある。どれを使うとしても、自分でテストプログラムを書かなくても、ある程度文法のが確認できるのでTestRigは便利。

ちなみに"hello world!"と入力すると、エラーメッセージが表示される。

line 1:11 token recognition error at: '!'

これはHello.g4でIDを英小文字[a-z]+としているから。[a-z!]+とすれば認識される。

from The Definitive ANTLR4 Reference by Terence Parr

*1:あるいは「受け入れる」というか、「文句を言わない」というか