ANTLRWorksでツリー文法をテストするときに入力としてASTを指定するにはどうすればよいですか?
自分でASTを提供する必要はなく、ASTを生成するパーサーのみを提供します。
ASTを生成する次の文法があるとします。
grammar ASTDemo;
options {
output=AST;
}
tokens {
ROOT;
U_MIN;
}
parse
: expression EOF -> ^(ROOT expression)
;
expression
: addition
;
addition
: multiplication (('+' | '-')^ multiplication)*
;
multiplication
: unary (('*' | '/')^ unary)*
;
unary
: '-' atom -> ^(U_MIN atom)
| atom
;
atom
: ID
| NUMBER
| '(' expression ')' -> expression
;
ID : ('a'..'z' | 'A'..'Z')+;
NUMBER : '0'..'9'+ ('.' '0'..'9'*)?;
SPACE : (' ' | '\t' | '\r' | '\n')+ {skip();};
以下は、上記の文法によって生成されたASTのツリー文法です。
tree grammar ASTDemoWalker;
options {
output=AST;
tokenVocab=ASTDemo;
ASTLabelType=CommonTree;
}
parse
: ^(ROOT expression)
;
expression
: ^('+' expression expression)
| ^('-' expression expression)
| ^('*' expression expression)
| ^('/' expression expression)
| ^(U_MIN expression)
| atom
;
atom
: ID
| NUMBER
;
必ず両方ASTDemo.g
とASTDemoWalker.g
同じフォルダに入れてください。ANTLRWorksで両方の文法を開き、最初に+ +をASTDemo.g
押してレクサーとパーサーを生成し、次にを開いて++を押してツリーウォーカーを生成します。CTRLSHIFTGASTDemoWalker.g
CTRLSHIFTG
次に、エディターパネルから、+をASTDemoWalker.g
押してデバッガーを起動し、次のソースをテキスト領域に貼り付けます。CTRLD
42 * ((a + 3) / -3.14)
を押しOKます。
これで、デバッグプロセスをステップ実行でき、最後に、パーサーが生成したASTの両方を確認できます。

そして、ツリーウォーカーがどのようにASTの上を歩いたか:

たとえば、ツリーの文法で「偶発的な」間違いを犯した場合は、^('*' expression expression)
を定義する代わりに^('*' expression)
。42
ツリー文法を再度デバッグすると、ノードを通過した後に失敗することがわかります。

ASTでは、ノードの後に別のノードがあり42
ますが、ツリーウォーカーはルートノード42
の後に1つの単一ノード()のみを予期していました。*
もちろん、これは簡単な文法ですが、ANTLRに精通している場合でも、ツリー文法のエラーを追跡するのは@ $&で苦痛になることがあります。:)