[antlr-interest] ANTLR3.0b5 - Embedding on parser within another one (Parser nesting)

Kay Roepke kroepke at classdump.org
Wed Nov 29 03:35:20 PST 2006


Moin Alex!

On 29. Nov 2006, at 8:28 , alexander.berger at finnova.ch wrote:

> Hi Kay
>
> Thank you for your answer. Of course you are right, but it is not  
> what I
> intended to do. The problem is not to force antlr to use the return  
> value
> of a rule as the resulting tree. The Problem is within the called  
> rule to
> force antlr to set the resulting tree to the one returned by the  
> embedded parser.

Oops, I missed that.

> My next approach was the following one:
[...]
> 	retval.tree = (Object)adaptor.rulePostProcessing(root_0);

Yes, the retval stuff is done last. Setting $tree only makes sense in  
@finally actions (I think, I might be wrong here).

> And horray it worked the way I expected it, but I think that using  
> "root_0" is very intrusive and not the way to go. So I am still  
> wondering if there
> is a way to do things like that in a non-intrusive way.

You're right, depending on root_0 is a bad idea. At some point this  
might get an '_' prefix.
Try this (I haven't actually tried to execute it, but the code looks  
good):

grammar Parent;

options {
	output=AST;
	ASTLabelType=CommonTree;
}

start
	:	s=subRule -> ^($s);
	
subRule
@init {
	CommonTree child = null;
}
	:	'do' {
			ChildParser p = new ChildParser(this.getTokenStream());
			p.setTreeAdaptor(this.getTreeAdaptor());
			child = (CommonTree)p.some_rule().getTree();
		}
		-> ^({child})
	;

generates this for start():

             retval.tree = root_0;
             root_0 = (CommonTree)adaptor.nil();
             // 9:14: -> ^( $s)
             {
                 // /Users/kroepke/test/Parent.g:9:17: ^( $s)
                 {
                 CommonTree root_1 = (CommonTree)adaptor.nil();
                 root_1 = (CommonTree)adaptor.becomeRoot(s.tree,  
root_1);

                 adaptor.addChild(root_0, root_1);
                 }

             }
and this for subRule():
             retval.tree = root_0;
             root_0 = (CommonTree)adaptor.nil();
             // 20:3: -> ^()
             {
                 // /Users/kroepke/test/Parent.g:20:6: ^()
                 {
                 CommonTree root_1 = (CommonTree)adaptor.nil();
                 root_1 = (CommonTree)adaptor.becomeRoot(child, root_1);

                 adaptor.addChild(root_0, root_1);
                 }

             }

Postprocessing at the end should get rid of the nil nodes, leaving  
you with 'child'.

HTH,
-k

-- 
Kay Röpke
http://classdump.org/






More information about the antlr-interest mailing list