[antlr-interest] to stop walking into a subtree

Martijn Reuvers martijn.reuvers at gmail.com
Tue Apr 5 22:53:25 PDT 2011


Hello,

I personally prefer a manual tree-visitor (which walks the AST), that
way you can just evaluate a node and based on the result take
appropriate action, it also allows more control (e.g. multi-phases if
needed). The main reason I do it that way is I don't want any of my
grammars getting cluttered with hard to maintain code in between (Java
e.g..) Disadvantage is, if your grammar is large, your visitor may get
complex. So it both has its advantages and disadvantages.

Cheers!
Martijn

On Wed, Apr 6, 2011 at 3:13 AM, Gary Miller <miller.garym at gmail.com> wrote:
> Hi Porosh,
>
> One way to do this is to skip the walk of the second operand (op2) is
> the tree grammar and call some java code to continue the walk if
> necessary. See example (this is sample code and is not expected to
> compile as is) below.
>
> Question: Does anyone know and a way this can be done without needing
> to create a new TreeNodeStream? Maybe using a predicate to acess the
> op2 without changing the position in the TreeNodeStream?
>
> Regards
>
> Gary
>
>
> Sample code.
>
> @members {
>
>  boolean continueBooleanexpression(TreeParser walker, Tree op) throws
> RecognitionException {
>
>    // Save the current TreeNodeStream
>
>    TreeNodeStream tns = walker.getTreeNodeStream();
>
>    boolean result =
>    try {
>      CommonTreeNodeStream nodes = new CommonTreeNodeStream(op);
>      nodes.setTokenStream(walker.getTreeNodeStream().getTokenStream());
>
>      // Use the same walker so state (scope, member etc.) is preserved.
>      walker.setTreeNodeStream(nodes);
>
>      // Continue the walk
>
>      // Probably doesn't return a boolean,
>
>      // might need to be something like walker.booleanexpression().result;
>      result = walker.booleanexpression();
>    } finally {
>
>      // Resort original TreeNodeStream
>      walker.setTreeNodeStream(tns);
>    }
>    return result;
>
>  }
>
> }
>
> booleanexpression returns[boolean result]
> :  ^(AND op1=booleanexpression op2=.)
>    {
>      if( $op1 ) {
>        boolean op2Result = continueBooleanexpression(this, $op2);
>        if( op2Result ) {
>          result = true;
>        } else {
>          result =false;
>        }
>      } else {
>        result = false;
>      }
>    }
> ;
>
>> booleanexpression returns[boolean result]
>
>> :*  ^(AND op1 = booleanexpression op2 = booleanexpression) {if(op1&&op2) result = *> true; else result =false;}
>> ;
>>
>> My question:
>> I want to stop walking once I found op1 as false. In that case, I don't need to
>> evaluate op2 anymore, the result is false anyway.
>>
>> Is there any way to implement this?
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>


More information about the antlr-interest mailing list