Chapter 2. The Big Picture^4

2.4 Building Language Applications Using Pars Tree

言語アプリを作るには、入力したそれぞれの句に対して適切なコードを実行する必要がある。最も簡単な方法は、構文解析器によって自動的に作られた構文解析木を操作すること。構文解析木の操作で良いことは、慣れた親しんだJavaの領域へ戻れること。言語アプリを作るために、これ以上学ぶANTLR構文は無い。

ここまで学んできたように、字句解析器は字を処理して、トークンを構文チェックと構文解析木構築を交互に行う構文解析器へ渡す。これに対応するANTLRのクラスはLexer, CharStream, token, ParserとParseTree。字句解析器と構文解析器をつなぐ「パイプ」はTokenStreamと呼ばれている。下図はこれらがメモリ上でどのように接続しているかを示している。

<snip>diagram of RuleNode - TerminalNode - TokenStream - CharStream</snip>

これらのANTLRデータ構造は、メモリ要求を減らすため可能な限りデータを共有している。この図は構文解析木の葉(トークン)ノードが、トークンストリーム中でのトークンの位置を示すコンテナであることを表している。トークンは(部分文字列のコピーを作るのではなく)CharStreamの開始/終了文字位置を記録する。この字句解析器は、ホワイトスペースを捨てると仮定できるので、ホワイトスペース文字に関連付けられたトークンはない。

この図はまた、ParseTreeのサブクラスRuleNode,TerminalNodeが、部分木の根と葉ノードに対応することを表している。RuleNodeはgetChild()/getParent()のようなメソッドを持っているが、RuleNodeは特定の言語に限定していない。特定ノードの要素へのアクセスを良くするため、ANTLRは各規則ごとにRuleNodeサブクラスを生成する。下図は例として代入文の部分木の根をStatContext,AssignContext,ExprContextで表している。

<snip>diagram of Parse tree and Parse tree node class names</snip>

規則による句認識のすべてを記録するためcontextと呼ばれるオブジェクトがある。それぞれのcontextオブジェクトは、認識された句の開始/終了トークンを知っていて、その句のすべての要素へのアクセスを提供する。たとえばAssignContextは識別子ノードと式部分木へアクセスするためメソッドID(),expr()を提供する。

与えられたこの具体的な型の記述は、木の深さ優先走査を実行するために手で書いたコードをかもしれない。ノードを発見/終了した時のアクションであればなんでも実行できるだろう。典型的な操作は、結果の計算、データ構造の更新、あるいは出力の生成。それぞれのアプリのためにお決まりの同じ木走査コードを書くより、ANTLRが自動生成した木走査メカニズムを使える。

from The Definitive ANTLR4 Reference by Terence Parr