How do I specify the AST as input when testing the tree grammar with ANTLRWorks?
You don't need to provide the AST yourself, only the parser that produces the AST.
Given the following grammar that produces an 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();};
The following would be a tree grammar for the AST produced by grammar above:
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
;
Be sure to put both ASTDemo.g
and ASTDemoWalker.g
in the same folder. Open both grammars in ANTLRWorks and generate the lexer & parser from ASTDemo.g
first by pressing CTRL+SHIFT+G and then generate the tree walker by opening ASTDemoWalker.g
and pressing CTRL+SHIFT+G.
Now, from the ASTDemoWalker.g
editor panel, fire up the debugger by pressing CTRL+D and paste the following source in the text area:
42 * ((a + 3) / -3.14)
and press OK.
You can now step through the debugging process and at the end, you can see both what AST the parser generated:
and how the tree walker walked over said AST:
If you now make an "accidental" mistake in the tree grammar, say, instead of ^('*' expression expression)
you define ^('*' expression)
. If you debug the tree grammar again, you will see it fail after passing the 42
node:
In the AST there is another node after the 42
node, while the tree walker expected only 1 single node (42
) after the *
root node.
Of course, this is an easy grammar, but even if you're familiar with ANTLR, it's sometimes a pain in the @$& to track down errors in a tree grammar! :)