public final ANTLRv3TreeFilter.block_return block() throws RecognitionException {
        ANTLRv3TreeFilter.block_return retval = new ANTLRv3TreeFilter.block_return();
        retval.start = input.LT(1);

        ANTLRv3TreeFilter.alternative_return a = null;


        try {
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:145:3: ( ^( BLOCK ( optionsSpec )? (a= alternative rewrite )+ EOB ) -> {alts.size() == 1}? {alts.get(0)} -> or(alternative=alts))
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:145:5: ^( BLOCK ( optionsSpec )? (a= alternative rewrite )+ EOB )
            {
             List<StringTemplate> alts = new LinkedList<StringTemplate>(); 
            match(input,BLOCK,FOLLOW_BLOCK_in_block691); 

            match(input, Token.DOWN, null); 
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:147:14: ( optionsSpec )?
            int alt23=2;
            int LA23_0 = input.LA(1);

            if ( (LA23_0==OPTIONS) ) {
                alt23=1;
            }
            switch (alt23) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:147:14: optionsSpec
                    {
                    pushFollow(FOLLOW_optionsSpec_in_block693);
                    optionsSpec();

                    state._fsp--;


                    }
                    break;

            }

            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:148:8: (a= alternative rewrite )+
            int cnt24=0;
            loop24:
            do {
                int alt24=2;
                int LA24_0 = input.LA(1);

                if ( (LA24_0==ALT) ) {
                    alt24=1;
                }


                switch (alt24) {
            	case 1 :
            	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:148:10: a= alternative rewrite
            	    {
            	    pushFollow(FOLLOW_alternative_in_block707);
            	    a=alternative();

            	    state._fsp--;

            	    pushFollow(FOLLOW_rewrite_in_block709);
            	    rewrite();

            	    state._fsp--;

            	     if (!(a!=null?a.st:null).toString().equals("epsilon")) {
            	                 alts.add((a!=null?a.st:null));
            	               }
            	             

            	    }
            	    break;

            	default :
            	    if ( cnt24 >= 1 ) break loop24;
                        EarlyExitException eee =
                            new EarlyExitException(24, input);
                        throw eee;
                }
                cnt24++;
            } while (true);

            match(input,EOB,FOLLOW_EOB_in_block739); 

            match(input, Token.UP, null); 


            // TEMPLATE REWRITE
            // 157:5: -> {alts.size() == 1}? {alts.get(0)}
            if (alts.size() == 1) {
                retval.st = alts.get(0);
            }
            else // 158:5: -> or(alternative=alts)
            {
                retval.st = templateLib.getInstanceOf("or",
              new STAttrMap().put("alternative", alts));
            }


            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return retval;
    }