[antlr-interest] LIP pg. 285 11.4 Rewriter. How do you do it with ANLTR 3?

The Researcher researcher0x00 at gmail.com
Sat Mar 19 08:08:32 PDT 2011


On Thu, Mar 17, 2011 at 5:54 PM, The Researcher <researcher0x00 at gmail.com>wrote:

>
>
>   On Thu, Mar 17, 2011 at 8:56 AM, Stephen Tuttlebee <
> themightystephen at googlemail.com> wrote:
>
>> 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,
>
> Thanks for the big road sign. I tried this originally but failed. I am
> working on it again but am sure to have more questions.
>
> Thanks, Eric
>
>
>>
>> Stephen
>>
>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>> Unsubscribe:
>> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>>
>
>
Stephen,

It now works. My problem was in my driver/test harness and not the rewrite
rules.

For others with similar problems; the best example of this can be found on
the tree construction wiki page which I just now read.
http://www.antlr.org/wiki/display/ANTLR3/Tree+construction

Yes I spent to much time focused on the books and just needed to look at the
wiki.

Thanks, Eric


More information about the antlr-interest mailing list