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.tokens | lexerで使われているトークンの定義 |
HelloParser.java | 構文解析プログラム(パーサー;parser) |
HelloListener.java | リスナーのインタフェース定義 |
HelloBaseListener.java | HelloListenerを実装したクラス。このクラスを継承してリスナープログラムを作る。 |
このように文法ファイルからLexarとかParserを自動生成してくれる。Listenerも作ってくれるが、Visitorはオプションで指定しないと生成されない。あとこれらを起動するメインプログラムも作ってくれない。その代わり、ANTLRはここで生成したLexar/Parserの動作を確認するのに便利なTestRigというプログラムを用意している。これに引数として文法名、処理を開始する規則名、その他オプションを渡すといろいろな情報を表示してくれる。たとえば-tokensを渡すと認識したトークンの情報を表示する。
例えば
[@1,6:10='parrt',<2>,1:6]
の場合、
TestRigの出力 | 内容 |
---|---|
@1 | 2番目のトークン(先頭は0) |
6:10 | 6~10文字目(先頭は0) |
parrt | 文字列 |
<2> | トークンタイプ2(Hello.tokensでID=2と定義されている) |
1 | 入力の1行目(先頭は1) |
6 | 6文字目(先頭は0;tabは1文字扱い) |
を表している。
また-guiオプションを指定すると、以下の様なダイアログを表示する。これは構文解析木で、文法が入力をどのように解釈したか一目でわかる。と言っても、こんな単純な例ではイマイチ便利さがわからないけど、文法が複雑な場合で、意図した通り字句が認識されているか?規則がどのような順番で適用されたか?といった確認をするとき役立ちそう。
そのほかにも構文解析木を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:あるいは「受け入れる」というか、「文句を言わない」というか