[antlr-interest] Tree Rewrite Caveats
Terence Parr
parrt at cs.usfca.edu
Sat Jun 7 10:12:52 PDT 2008
which line is the exception? on the _last reference? hmm...must have
a problem with _last in this case.
Ter
On Jun 6, 2008, at 4:40 PM, Robin Hamilton-Pennell wrote:
> Terence,
>
> Not sure what you mean by "first one," but if you are referring to the
> "every (sub)rule that you are rewriting must match a tree node" thing,
> here's a little more info.
>
> I've been using the tree rewriting stuff for a bit now, so I
> understand it a little better. For my explanation, here's a section of
> my grammar that works fine (I've simplified it a lot, only the
> relevant portions included):
>
> statement
> : ^(EXPR_STATEMENT expr) -> ^(EXPR_STATEMENT expr)
> | ^(BLOCK_STATEMENT basicBlock) -> ^(BLOCK_STATEMENT basicBlock)
> | /* more statement rules... */
> ;
> expr : ^(TYPE expr typeParams) -> ^(TYPE expr typeParams)
> | /* more tree rewrite rules... */
> | literal
> | basicBlock
> | /* more rule references... */
> ;
> literal
> : IntLiteral -> IntLiteral
> | FloatLiteral -> FloatLiteral
> | BoolLiteral -> BoolLiteral
> | StringLiteral -> StringLiteral
> | 'null' -> 'null'
> | /* more token references... */
> ;
>
> This grammar works fine. Note that it's fine for me to rewrite lexer
> (token) references, and tree references, but I don't rewrite rule
> references.
>
> If, however, I change expr to rewrite a rule reference:
>
> expr : ^(TYPE expr typeParams) -> ^(TYPE expr typeParams)
> | /* more tree rewrite rules... */
> | literal -> literal
> | basicBlock
> | /* more rule references... */
> ;
>
> ... parsing will always fail with errors like the following:
> Exception in thread "main" java.lang.NullPointerException
> at
> org
> .antlr
> .runtime.tree.CommonTreeAdaptor.getChildIndex(CommonTreeAdaptor.java:
> 173)
> at CogTreeRewriter.expr(CogTreeRewriter.java:1469)
> at CogTreeRewriter.expr(CogTreeRewriter.java:1294)
> at CogTreeRewriter.statement(CogTreeRewriter.java:382)
> at CogTreeRewriter.basicBlock(CogTreeRewriter.java:2398)
> at CogTreeRewriter.statement(CogTreeRewriter.java:745)
> at CogTreeRewriter.program(CogTreeRewriter.java:210)
>
> The generated code from around line 1469 looks like this:
> // AST REWRITE
> // elements: literal
> // token labels:
> // rule labels: retval
> // token list labels:
> // rule list labels:
> retval.tree = root_0;
> RewriteRuleSubtreeStream stream_retval=new
> RewriteRuleSubtreeStream(adaptor,"token
> retval",retval!=null?retval.tree:null);
>
> root_0 = (CogTree)adaptor.nil();
> // 91:17: -> literal
> {
> adaptor.addChild(root_0,
> stream_literal.nextTree());
>
> }
>
> retval.tree =
> (CogTree)adaptor.rulePostProcessing(root_0);
>
> input.replaceChildren(adaptor.getParent(retval.start),
>
> adaptor.getChildIndex(retval.start),
> adaptor.getChildIndex(_last),
> retval.tree);
> }
> break;
>
> If you need any other information, please let me know. I'm happy to
> help out!
>
> Thanks,
> Robin
>
> On Fri, Jun 6, 2008 at 3:27 PM, Terence Parr <parrt at cs.usfca.edu>
> wrote:
>>
>> On May 23, 2008, at 8:21 PM, Robin Hamilton-Pennell wrote:
>>
>>> Hi all,
>>>
>>> Been playing around with the tree rewriting stuff in 3.1b1. It's
>>> much
>>> better than the previous test build was. I'm not through with my
>>> experimentation and likely will find more things, but I thought I'd
>>> make some notes on a few troubles I ran into, in case it helps
>>> anyone
>>> else.
>>>
>>> Firstly (this is probably true of tree parsers in general), if you
>>> use
>>> a custom class as your AST node and the Java target, you will
>>> probably
>>> need to add the method errorNode() in your TreeAdaptor class. This
>>> will also entail either adding error node utility methods to your
>>> AST
>>> node, or creating a custom subclass of CommonErrorNode. I could be
>>> completely misguided on this; please say so.
>>>
>>> Second, every (sub)rule that you are rewriting must match a tree
>>> node,
>>> I think. This seems obvious in retrospect, but it took me a while to
>>> figure out. That means that you can't do this:
>>>
>>> stmt:
>>> expr -> expr
>>> ;
>>
>> Really? Why not?
>>
>>> However, you can do either of the following (or change your AST
>>> generation code):
>>>
>>> stmt:
>>> expr // omit rewrite rule
>>> ;
>>>
>>> stmt:
>>> // (after changing your AST generation)
>>> ^(EXPR expr) -> ^(EXPR expr)
>>> ;
>>>
>>> I should mention that both of these issues involves the rewrite=true
>>> option. I haven't tested the effects of turning that off, actually.
>>
>> Can you tell me what goes wrong with the first one?
>> Ter
>>>
>>>
>>> Again, I could simply be completely misguided on this, in which
>>> case,
>>> please enlighten me.
>>>
>>> Thanks,
>>> Robin
>>
>>
More information about the antlr-interest
mailing list