[antlr-interest] LIP pg. 285 11.4 Rewriter. How do you do it with ANLTR 3?
Stephen Tuttlebee
themightystephen at googlemail.com
Thu Mar 17 05:56:17 PDT 2011
Hi Eric
I don't know if I understand your question completely (I haven't read
the previous questions you mentioned), but are you simply asking how you
rewrite a tree using ANTLR? Or were you actually asking how ANTLR
actually IMPLEMENTS this rewriting under the hood (i.e. what code does
it generate to do the rewriting)? Or something else?
If you were asking the first question, then I can provide a fairly
simple example from a couple of grammars I have been working on recently
(I don't know if the example is too simple since it only alters the tree
in a very minor way, and maybe you're thinking along the lines of larger
and more substantial changes to the tree).
I have the 'phase 1 grammar' (JavaBPhase1Parser.g) that does the parsing
and has tree rewrite rules to build an AST. This grammar has the
following options:
options {
language = Java;
output = AST;
tokenVocab = JavaBLexer;
}
This grammar just builds a tree in the normal way.
My 'phase 2 grammar' (JavaBPhase2WalkerSem1.g) is a tree grammar that
reads that AST, performs some semantic analysis of the input and spits
out an almost identical AST. It has similar options as before but the
really important one here is the rewrite=true option:
options {
language = Java;
output = AST; // since we are performing a tree rewrite, as well as
reading in an AST, I will also be outputting an AST
rewrite = true; // <---- this is the key option here
tokenVocab = JavaBPhase1Parser;
ASTLabelType = CommonTree; // this option here because we're
reading in a tree and ANTLR would like to know the type of the nodes
}
The rewrite=true causes the tree to be spat out just the same as the
input tree except where you specify otherwise. For example, in one rule
I perform some semantic analysis that informs me on how to rewrite the tree:
compositionExpression
@init {
boolean compositionComponent = false; // this is only here rather
than further below where I would want to use it because in the code
generated by ANTLR the variable is out of scope if I declare it down there
}
: ... // other tree rule
| ... // other tree rule
| ^(PLAIN_OR_COMPOSITION_COMPONENT ^(IDENT IDENTIFIER))
{ .... some actions that perform semantic analysis (look up in
the symbol table) to decide if compositionComponent is true or false }
-> {compositionComponent}? ^(COMPOSITION_COMPONENT ^(IDENT
IDENTIFIER))
->
^(PLAIN_COMPONENT ^(IDENT IDENTIFIER))
In this example I am performing a very simple tree rewrite by simply
changing the imaginary token of a subtree's root node, but you could
change the entire subtree by changing the rewrite rule(s) to produce a
completely different subtree.
For larger, more 'structural' changes to the tree, I would imagine you
need to do a fair amount of passing subtrees around as parameters /
return values between rules so that you have access to the subtrees in
the rules that need them. p170 of the ANTLR reference book has an
example of this kind of thing (example is used in doing tree
construction in a *parser* grammar but you can do exactly the same in a
tree grammar).
You can also have semantic predicates (I think that's the proper name)
before multiple rewrite rules to rewrite the tree in different ways
depending on what the boolean expression in the semantic predicates
evaluates to. See page 181 of ANTLR reference for an example in the
variableDefinition rule:
variableDefinition
: modifiers type ID ('=' expression)? ';'
-> {inMethod}? ^(VARIABLE ID modifier* type expression?) //
semantic predicate used here
-> ^(FIELD ID modifier* type expression?)
;
Again, that example is used in doing tree construction in a parser
grammar but you can do exactly the same in a tree grammar.
Bear in mind though (at least I think this is the case...), that with
these semantic predicates you have to ensure that there is a default
case which specifies the tree to be built if all the other previous
semantic predicates evaluate to false.
Hope this helps.
Stephen
More information about the antlr-interest
mailing list