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

        try {
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:139:2: ( ^( 'scope' ACTION ) | ^( 'scope' ACTION ( ID )+ ) | ^( 'scope' ( ID )+ ) )
            int alt22=3;
            int LA22_0 = input.LA(1);

            if ( (LA22_0==SCOPE) ) {
                int LA22_1 = input.LA(2);

                if ( (LA22_1==DOWN) ) {
                    int LA22_2 = input.LA(3);

                    if ( (LA22_2==ACTION) ) {
                        int LA22_3 = input.LA(4);

                        if ( (LA22_3==UP) ) {
                            alt22=1;
                        }
                        else if ( (LA22_3==ID) ) {
                            alt22=2;
                        }
                        else {
                            NoViableAltException nvae =
                                new NoViableAltException("", 22, 3, input);

                            throw nvae;
                        }
                    }
                    else if ( (LA22_2==ID) ) {
                        alt22=3;
                    }
                    else {
                        NoViableAltException nvae =
                            new NoViableAltException("", 22, 2, input);

                        throw nvae;
                    }
                }
                else {
                    NoViableAltException nvae =
                        new NoViableAltException("", 22, 1, input);

                    throw nvae;
                }
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 22, 0, input);

                throw nvae;
            }
            switch (alt22) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:139:4: ^( 'scope' ACTION )
                    {
                    match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec643); 

                    match(input, Token.DOWN, null); 
                    match(input,ACTION,FOLLOW_ACTION_in_ruleScopeSpec645); 

                    match(input, Token.UP, null); 

                    }
                    break;
                case 2 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:140:4: ^( 'scope' ACTION ( ID )+ )
                    {
                    match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec652); 

                    match(input, Token.DOWN, null); 
                    match(input,ACTION,FOLLOW_ACTION_in_ruleScopeSpec654); 
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:140:21: ( ID )+
                    int cnt20=0;
                    loop20:
                    do {
                        int alt20=2;
                        int LA20_0 = input.LA(1);

                        if ( (LA20_0==ID) ) {
                            alt20=1;
                        }


                        switch (alt20) {
                    	case 1 :
                    	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:140:21: ID
                    	    {
                    	    match(input,ID,FOLLOW_ID_in_ruleScopeSpec656); 

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt20 >= 1 ) break loop20;
                                EarlyExitException eee =
                                    new EarlyExitException(20, input);
                                throw eee;
                        }
                        cnt20++;
                    } while (true);


                    match(input, Token.UP, null); 

                    }
                    break;
                case 3 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:141:4: ^( 'scope' ( ID )+ )
                    {
                    match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec664); 

                    match(input, Token.DOWN, null); 
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:141:14: ( ID )+
                    int cnt21=0;
                    loop21:
                    do {
                        int alt21=2;
                        int LA21_0 = input.LA(1);

                        if ( (LA21_0==ID) ) {
                            alt21=1;
                        }


                        switch (alt21) {
                    	case 1 :
                    	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:141:14: ID
                    	    {
                    	    match(input,ID,FOLLOW_ID_in_ruleScopeSpec666); 

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt21 >= 1 ) break loop21;
                                EarlyExitException eee =
                                    new EarlyExitException(21, input);
                                throw eee;
                        }
                        cnt21++;
                    } while (true);


                    match(input, Token.UP, null); 

                    }
                    break;

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