[antlr-interest] conditional tree jumping,

Bryan Ewbank ewbank at gmail.com
Mon Feb 20 08:28:26 PST 2006


On 2/19/06, Craig Main <craig at palantir.co.za> wrote:
> How would you eliminate the else with the statement list?
> I am not quite sure what you mean here - I am still trying to wrap my brain
> around the tree matching syntax.
>
> Would you be in a position to give me a small example? I assume that you
> eliminate the node in the parser.

It will come to you; drawing the silly things helped me to see the problems and
ambiguities.  Let's see...  I'll sketch what I do, more or less...

To produce a clean IF node in the parser:

	stmt
	:
		( r:TOK_IF^ LP! expr RP! stmt ( TOK_ELSE! stmt { r.setType(TOK_IFELSE); } )?
		| ... other statement types here ...
		| stmtlist
		)
	;

	stmtlist : LCB! ( stmt )* RCB! { ## = #( #[STMTLIST], ## ); } ;

The ()? around the TOK_ELSE will cause a warning in ANTLR.  Setting the option
"greedy=true" for the ()? construct will bind ELSE to closest IF.

This produces a tree of two shapes; one for "if" alone, and one for "if/else":

	#(TOK_IF e1 s1)
	#(TOK_IFELSE e1 s1 s2)
	// e1 is the expression
	// s1 is the "if-branch" of the tree
	// s2 is the "else-branch", if present.

Now, you can write the tree parser rules to process e1, then select s1 (or s2)
based on the results.

In a similar vein, if you are implementing short-circuit &&/|| and ?: operators
(as C does), you need to be aware of the related situation and code for it:

	// oversimplified by assuming only boolean-valued expressions
	expr
	:
		( ...
		| #( ANDAND res=expr
			( { res==true  }? expr | .)	// eval e2 only when e1==true
		| #( OROR res=expr
			( { res==false }? expr | .)	// eval e2 only when e1==false
		| #( QUEST res=expr
			( { res==true }? res=expr .	// eval only e2 when e1==true
			| . res=expr			// ... otherwise, eval only e3
	 		)
	;


More information about the antlr-interest mailing list