public final ANTLRv3TreeFilter.grammarDef_return grammarDef(String pack) throws RecognitionException {
        ANTLRv3TreeFilter.grammarDef_return retval = new ANTLRv3TreeFilter.grammarDef_return();
        retval.start = input.LT(1);

        CommonTree ID1=null;
        List list_r=null;
        RuleReturnScope r = null;
        try {
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:50:3: ( ^( grammarType ID ( DOC_COMMENT )? ( optionsSpec )? ( tokensSpec )? ( attrScope )* ( action )* (r+= rule )+ ) -> filter(id=$IDrule=$rpack=pack))
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:50:5: ^( grammarType ID ( DOC_COMMENT )? ( optionsSpec )? ( tokensSpec )? ( attrScope )* ( action )* (r+= rule )+ )
            {
            pushFollow(FOLLOW_grammarType_in_grammarDef65);
            grammarType();

            state._fsp--;


            match(input, Token.DOWN, null); 
            ID1=(CommonTree)match(input,ID,FOLLOW_ID_in_grammarDef67); 
             scope = (ID1!=null?ID1.getText():null); 
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:8: ( DOC_COMMENT )?
            int alt1=2;
            int LA1_0 = input.LA(1);

            if ( (LA1_0==DOC_COMMENT) ) {
                alt1=1;
            }
            switch (alt1) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:8: DOC_COMMENT
                    {
                    match(input,DOC_COMMENT,FOLLOW_DOC_COMMENT_in_grammarDef101); 

                    }
                    break;

            }

            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:21: ( optionsSpec )?
            int alt2=2;
            int LA2_0 = input.LA(1);

            if ( (LA2_0==OPTIONS) ) {
                alt2=1;
            }
            switch (alt2) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:21: optionsSpec
                    {
                    pushFollow(FOLLOW_optionsSpec_in_grammarDef104);
                    optionsSpec();

                    state._fsp--;


                    }
                    break;

            }

            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:34: ( tokensSpec )?
            int alt3=2;
            int LA3_0 = input.LA(1);

            if ( (LA3_0==TOKENS) ) {
                alt3=1;
            }
            switch (alt3) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:34: tokensSpec
                    {
                    pushFollow(FOLLOW_tokensSpec_in_grammarDef107);
                    tokensSpec();

                    state._fsp--;


                    }
                    break;

            }

            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:46: ( attrScope )*
            loop4:
            do {
                int alt4=2;
                int LA4_0 = input.LA(1);

                if ( (LA4_0==SCOPE) ) {
                    alt4=1;
                }


                switch (alt4) {
            	case 1 :
            	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:46: attrScope
            	    {
            	    pushFollow(FOLLOW_attrScope_in_grammarDef110);
            	    attrScope();

            	    state._fsp--;


            	    }
            	    break;

            	default :
            	    break loop4;
                }
            } while (true);

            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:57: ( action )*
            loop5:
            do {
                int alt5=2;
                int LA5_0 = input.LA(1);

                if ( (LA5_0==72) ) {
                    alt5=1;
                }


                switch (alt5) {
            	case 1 :
            	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:57: action
            	    {
            	    pushFollow(FOLLOW_action_in_grammarDef113);
            	    action();

            	    state._fsp--;


            	    }
            	    break;

            	default :
            	    break loop5;
                }
            } while (true);

            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:65: (r+= rule )+
            int cnt6=0;
            loop6:
            do {
                int alt6=2;
                int LA6_0 = input.LA(1);

                if ( (LA6_0==RULE) ) {
                    alt6=1;
                }


                switch (alt6) {
            	case 1 :
            	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:54:66: r+= rule
            	    {
            	    pushFollow(FOLLOW_rule_in_grammarDef119);
            	    r=rule();

            	    state._fsp--;

            	    if (list_r==null) list_r=new ArrayList();
            	    list_r.add(r.getTemplate());


            	    }
            	    break;

            	default :
            	    if ( cnt6 >= 1 ) break loop6;
                        EarlyExitException eee =
                            new EarlyExitException(6, input);
                        throw eee;
                }
                cnt6++;
            } while (true);


            match(input, Token.UP, null); 


            // TEMPLATE REWRITE
            // 56:5: -> filter(id=$IDrule=$rpack=pack)
            {
                retval.st = templateLib.getInstanceOf("filter",
              new STAttrMap().put("id", ID1).put("rule", list_r).put("pack", pack));
            }


            }

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