[antlr-interest] Tree Grammars Conditional Execution

simon.pearson at e-magictrick.com simon.pearson at e-magictrick.com
Sun Nov 21 18:00:52 PST 2010


 Hello, a friend and I have been working on implementing an
interpreter for a small DSL using the ANTLR C-target.  He has
constructed an AST and is using a tree grammar to generate the code
for the walker.  Our problem can best be explained by way of example.
 Take the following snippet of code from our tree grammar:
 :    ^(IF iex=nexpr[defer] ^(THEN {iStart=INDEX()+1;}
blockstar[true]
 {
     if ( !defer )
     {
         if ( $iex.value.toBool() )
         {
             foundPath = true;
             Memory::getI()->enterScope(false);
             ANTLR3_MARKER next = INDEX();
             SEEK(iStart);
             ctx->blockstar(ctx,false);
             SEEK(next);
             Memory::getI()->exitScope();
     }
 }
 blockstar is a statement block that should only be executed if the
nexpr condition evaluates to true.  To avoid the walker performing
all of the code in blockstar regardless of whether or not the
condition evaluated to true or false we've added a defer parameter to
the blockstar rule, and when the walker is initially parsing blockstar
we pass defer==true.  This causes the walker to do a 'dummy' recursion
down through blockstar where no actions are actually executed because
all actions are inside an if (!defer) { ... } statement.  Having
recorded the start of blockstar in the token stream in the iStart
variable we then check if the condition has evaluated to true, and if
it has we position the walker at the start of blockstar and walk it
but this time with defer==false.
 I presume we could prevent the 'dummy' walk of the AST by inserting
action code immediately after the nexpr condition along the lines of
{executeBody==true;} and then put an if (executeBody) statement in
blockstar?
 We have used a similar pattern in our WHILE statement and even in
our FOR loop since the counting expression shouldn't be executed when
it's initially parsed.
 I'm sure we must have missed something and there must be a simpler
way to implement such common functionality.  I'd be most appreciative
if someone could suggest an alternative solution.
 Simon


More information about the antlr-interest mailing list