Chapter 2. The Big Picture^5

2.5 Parse-Tree Listeners and Visitors

ANTLRは実行時ライブラリで2つの木走査メカニズムを提供する。デフォルトでは、ANTRLはビルトインの木走査器によって駆動されるイベントに反応する構文解析木のリスナーインタフェースを生成する。リスナー自身、XMLパーサーのSAXドキュメントハンドラーオブジェクトにとても似ている。SAXリスナーはstartDocument()/EndDocument()に似たイベント通知を受け取る。リスナーの中のメソッドは、GUIアプリでチェックボックスのクリックに応答するのに使うようなコールバックである。リスナーを見れば、ANTLRがvisitorパターンに従った木走査の生成もできることがわかる。

Parse-Tree Listners

木を走査してリスナーへの呼び出しを駆動するため、ANTLRのランタイムはクラスParseTreeWalkerを提供する。言語アプリを作るには、一般的には大きな周囲のアプリを呼び出すような、アプリ固有のコードを含んだParseTreeListenerを実装する。

ANTLRは、規則ごとのenter/exitメソッドを伴う文法特有のParseTreeListenerサブクラスを生成する。たとえば走査器が規則assignノードに出会った時、走査器はenterAssign()を起動し、AssignContext部分木を渡す。走査器がassignノードのすべての子ノードを訪問したら、exitAssign()を呼び出す。下図はParseTreeWalkerが実行する深さ優先走査を表している。これはまたParaseTreeWalkerが規則assignのために、enter/exitメソッドを呼び出すところを明らかにしている。

<snip>diagram</snip>

リスナーメカニズの美しさはすべて自動であること。構文解析木の走査器を書く必要がなく、リスナーメッソドは明示的に子供を回る必要がない。

Parse-Tree Visitors

しかしながら、子供を訪問するため明示的なメソッド呼び出しをコントロールしたい状況もある。オプション-visitorは、ANTLRに文法から規則毎のvisitメソッドと合わせてvisitorインタフェースの生成を要求する。以下は、構文解析木上での、普通のvisitorパターン操作である。

<snip>Figure1</snip>

太破線は木の深さ優先走査を表している。細破線はvisitorメソッド間の呼び出し順序を示している。木走査を始めるために、アプリ固有のコードはvisitorの実装を生成し、visit()を呼び出す。

ParseTree tree = ... ;	// tree is result of parsing
MyVisitor v = new MyVisitor();
v.visit(tree);

そのあと、ANTLRのvisitorをサポートするコードは、根ノードでvisitStat()を呼び出す。そこからvisitStat()の実装は、走査を続けるため、子を引数としてvisit()を呼び出す。あるいはvisitMethod()はvisitAsign()を明示的に呼び出すかもしれない、など。

ANTLRはvisitorインタフェースを生成し、visitorメソッドのデフォルト実装したクラスを提供することで支援する。これはインタフェースの各メソッドをオーバーライドする必要を避け、メソッドの関心事にフォーカスさせてくれる。

from The Definitive ANTLR4 Reference by Terence Parr