docs: public final EventFilterParser.boolean_expr_return boolean_expr() throws RecognitionException {
          EventFilterParser.boolean_expr_return retval = new EventFilterParser.boolean_expr_return();
          retval.start = input.LT(1);
  
  
          CommonTree root_0 = null;
  
          Token AND3=null;
          EventFilterParser.boolean_factor_return a =null;
  
          EventFilterParser.boolean_factor_return b =null;
  
  
          CommonTree AND3_tree=null;
          RewriteRuleTokenStream stream_AND=new RewriteRuleTokenStream(adaptor,"token AND");
          RewriteRuleSubtreeStream stream_boolean_factor=new RewriteRuleSubtreeStream(adaptor,"rule boolean_factor");
          try {
              // EventFilter.g:107:2: ( (a= boolean_factor -> $a) ( AND b= boolean_factor -> ^( AND $boolean_expr $b) )* )
              // EventFilter.g:107:4: (a= boolean_factor -> $a) ( AND b= boolean_factor -> ^( AND $boolean_expr $b) )*
              {
              // EventFilter.g:107:4: (a= boolean_factor -> $a)
              // EventFilter.g:107:5: a= boolean_factor
              {
              pushFollow(FOLLOW_boolean_factor_in_boolean_expr370);
              a=boolean_factor();
  
              state._fsp--;
  
              stream_boolean_factor.add(a.getTree());
  
              // AST REWRITE
              // elements: a
              // token labels:
              // rule labels: retval, a
              // token list labels:
              // rule list labels:
              // wildcard labels:
              retval.tree = root_0;
              RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);
              RewriteRuleSubtreeStream stream_a=new RewriteRuleSubtreeStream(adaptor,"rule a",a!=null?a.tree:null);
  
              root_0 = (CommonTree)adaptor.nil();
              // 107:21: -> $a
              {
                  adaptor.addChild(root_0, stream_a.nextTree());
  
              }
  
  
              retval.tree = root_0;
  
              }
  
  
              // EventFilter.g:107:27: ( AND b= boolean_factor -> ^( AND $boolean_expr $b) )*
              loop3:
              do {
                  int alt3=2;
                  int LA3_0 = input.LA(1);
  
                  if ( (LA3_0==AND) ) {
                      alt3=1;
                  }
  
  
                  switch (alt3) {
              	case 1 :
              	    // EventFilter.g:107:28: AND b= boolean_factor
              	    {
              	    AND3=(Token)match(input,AND,FOLLOW_AND_in_boolean_expr377);
              	    stream_AND.add(AND3);
  
  
              	    pushFollow(FOLLOW_boolean_factor_in_boolean_expr381);
              	    b=boolean_factor();
  
              	    state._fsp--;
  
              	    stream_boolean_factor.add(b.getTree());
  
              	    // AST REWRITE
              	    // elements: b, boolean_expr, AND
              	    // token labels:
              	    // rule labels: retval, b
              	    // token list labels:
              	    // rule list labels:
              	    // wildcard labels:
              	    retval.tree = root_0;
              	    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);
              	    RewriteRuleSubtreeStream stream_b=new RewriteRuleSubtreeStream(adaptor,"rule b",b!=null?b.tree:null);
  
              	    root_0 = (CommonTree)adaptor.nil();
              	    // 107:49: -> ^( AND $boolean_expr $b)
              	    {
              	        // EventFilter.g:107:52: ^( AND $boolean_expr $b)
              	        {
              	        CommonTree root_1 = (CommonTree)adaptor.nil();
              	        root_1 = (CommonTree)adaptor.becomeRoot(
              	        new AndTreeNode(stream_AND.nextToken())
              	        , root_1);
  
              	        adaptor.addChild(root_1, stream_retval.nextTree());
  
              	        adaptor.addChild(root_1, stream_b.nextTree());
  
              	        adaptor.addChild(root_0, root_1);
              	        }
  
              	    }
  
  
              	    retval.tree = root_0;
  
              	    }
              	    break;
  
              	default :
              	    break loop3;
                  }
              } while (true);
  
  
              }
  
              retval.stop = input.LT(-1);
  
  
              retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
              adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
  
          }
          catch (RecognitionException re) {
              reportError(re);
              recover(input,re);
      	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);
  
          }
  
          finally {
          	// do for sure before leaving
          }
          return retval;
      }