/** \file
 *  This OBJC source file was generated by $ANTLR version ${project.version} ${buildNumber}
 *
 *     -  From the grammar source file : TreeRewrite.g
 *     -                            On : 2011-05-06 18:56:28
 *     -                for the parser : TreeRewriteParserParser
 *
 * Editing it, at least manually, is not wise.
 *
 * ObjC language generator and runtime by Alan Condit, acondit|hereisanat|ipns|dotgoeshere|com.
 *
 *
*/
// $ANTLR ${project.version} ${buildNumber} TreeRewrite.g 2011-05-06 18:56:28


/* -----------------------------------------
 * Include the ANTLR3 generated header file.
 */
#import "TreeRewriteParser.h"
/* ----------------------------------------- */


/* ============================================================================= */
/* =============================================================================
 * Start of recognizer
 */

#pragma mark Bitsets
static ANTLRBitSet *FOLLOW_INT_in_rule26;
static const unsigned long long FOLLOW_INT_in_rule26_data[] = { 0x0000000000000010LL};
static ANTLRBitSet *FOLLOW_subrule_in_rule28;
static const unsigned long long FOLLOW_subrule_in_rule28_data[] = { 0x0000000000000002LL};
static ANTLRBitSet *FOLLOW_INT_in_subrule53;
static const unsigned long long FOLLOW_INT_in_subrule53_data[] = { 0x0000000000000002LL};


#pragma mark Dynamic Global Scopes

#pragma mark Dynamic Rule Scopes

#pragma mark Rule Return Scopes start
@implementation TreeRewriteParser_rule_return /* returnScope */
/* AST returnScope.synthesize */
@synthesize tree; /* start of synthesize -- OBJC-Line 1837 */
+ (TreeRewriteParser_rule_return *)newTreeRewriteParser_rule_return
{
    return [[[TreeRewriteParser_rule_return alloc] init] retain];
}

- (id) init
{
    self = [super init];
    return self;
}

/* AST returnScope.methods */
- (ANTLRCommonTree *)getTree
{
    return tree;
}

- (void) setTree:(ANTLRCommonTree *)aTree
{
    if (tree != aTree) {
        if (tree != nil) [tree release];
        if (aTree != nil) [aTree retain];
        tree = aTree;
    }
}

- (void) dealloc
{
    self.tree = nil;
    [super dealloc];
}



@end /* end of returnScope implementation */


@implementation TreeRewriteParser_subrule_return /* returnScope */
/* AST returnScope.synthesize */
@synthesize tree; /* start of synthesize -- OBJC-Line 1837 */
+ (TreeRewriteParser_subrule_return *)newTreeRewriteParser_subrule_return
{
    return [[[TreeRewriteParser_subrule_return alloc] init] retain];
}

- (id) init
{
    self = [super init];
    return self;
}

/* AST returnScope.methods */
- (ANTLRCommonTree *)getTree
{
    return tree;
}

- (void) setTree:(ANTLRCommonTree *)aTree
{
    if (tree != aTree) {
        if (tree != nil) [tree release];
        if (aTree != nil) [aTree retain];
        tree = aTree;
    }
}

- (void) dealloc
{
    self.tree = nil;
    [super dealloc];
}



@end /* end of returnScope implementation */


//#pragma mark Rule return scopes start
//

#pragma mark Rule return scopes start

@implementation TreeRewriteParser  // line 637

/* ObjC start of ruleAttributeScope */
#pragma mark Dynamic Rule Scopes
/* ObjC end of ruleAttributeScope */
#pragma mark global Attribute Scopes
/* ObjC start globalAttributeScope */
/* ObjC end globalAttributeScope */
/* ObjC start actions.(actionScope).synthesize */
/* ObjC end actions.(actionScope).synthesize */
/* ObjC start synthesize() */
/* AST genericParser.synthesize */
/* AST parserProperties */
@synthesize treeAdaptor;
/* ObjC end synthesize() */

+ (void) initialize
{
    #pragma mark Bitsets
    FOLLOW_INT_in_rule26 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_INT_in_rule26_data Count:(NSUInteger)1] retain];
    FOLLOW_subrule_in_rule28 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_subrule_in_rule28_data Count:(NSUInteger)1] retain];
    FOLLOW_INT_in_subrule53 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_INT_in_subrule53_data Count:(NSUInteger)1] retain];

    [ANTLRBaseRecognizer setTokenNames:[[AMutableArray arrayWithObjects:@"<invalid>", @"<EOR>", @"<DOWN>", @"<UP>", 
 @"INT", @"WS", nil] retain]];
    [ANTLRBaseRecognizer setGrammarFileName:@"TreeRewrite.g"];
}

+ (TreeRewriteParser *)newTreeRewriteParser:(id<ANTLRTokenStream>)aStream
{
    return [[TreeRewriteParser alloc] initWithTokenStream:aStream];


}

- (id) initWithTokenStream:(id<ANTLRTokenStream>)aStream
{
    self = [super initWithTokenStream:aStream State:[[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:2+1] retain]];
    if ( self != nil ) {


        /* start of actions-actionScope-init */
        /* start of init */
        /* AST genericParser.init */
        [self setTreeAdaptor:[[ANTLRCommonTreeAdaptor newTreeAdaptor] retain]];
    }
    return self;
}

- (void) dealloc
{
    /* AST genericParser.dealloc */
    [self setTreeAdaptor:nil];

    [super dealloc];
}

/* ObjC start members */
/* ObjC end members */
/* ObjC start actions.(actionScope).methods */
/* ObjC end actions.(actionScope).methods */
/* ObjC start methods() */
/* AST genericParser.methods */
/* AST parserMethods */
- (id<ANTLRTreeAdaptor>) getTreeAdaptor
{
	return treeAdaptor;
}

- (void) setTreeAdaptor:(id<ANTLRTreeAdaptor>)aTreeAdaptor
{
	if (aTreeAdaptor != treeAdaptor) {
		treeAdaptor = aTreeAdaptor;
	}
}
/* ObjC end methods() */
/* ObjC start rules */
/*
 * $ANTLR start rule
 * TreeRewrite.g:8:1: rule : INT subrule -> ^( subrule INT ) ;
 */
- (TreeRewriteParser_rule_return *) rule
{
    /* my ruleScopeSetUp */
    /* Terence's stuff */

    /* AST ruleDeclarations */
    TreeRewriteParser_rule_return * retval = [TreeRewriteParser_rule_return newTreeRewriteParser_rule_return];
    [retval setStart:[input LT:1]];


    ANTLRCommonTree *root_0 = nil;

    @try {
        /* AST ruleLabelDefs */
        ANTLRCommonToken *INT1 = nil;
         TreeRewriteParser_subrule_return * subrule2 = nil ;
         

        ANTLRCommonTree *INT1_tree=nil;
        ANTLRRewriteRuleTokenStream *stream_INT =
            [[ANTLRRewriteRuleTokenStream newANTLRRewriteRuleTokenStream:treeAdaptor
                                                             description:@"token INT"] retain];
        ANTLRRewriteRuleSubtreeStream *stream_subrule =
            [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor
                                                                description:@"rule subrule"] retain];
        // TreeRewrite.g:8:5: ( INT subrule -> ^( subrule INT ) ) // ruleBlockSingleAlt
        // TreeRewrite.g:8:7: INT subrule // alt
        {
        INT1=(ANTLRCommonToken *)[self match:input TokenType:INT Follow:FOLLOW_INT_in_rule26];  
            [stream_INT addElement:INT1];


        /* ruleRef */
        [self pushFollow:FOLLOW_subrule_in_rule28];
        subrule2 = [self subrule];

        [self popFollow];


        [stream_subrule addElement:[subrule2 getTree]];

        // AST REWRITE
        // elements: subrule, INT
        // token labels: 
        // rule labels: retval
        // token list labels: 
        // rule list labels: 
        // wildcard labels: 
        retval.tree = root_0;

        ANTLRRewriteRuleSubtreeStream *stream_retval =
            [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor
                description:@"token retval" element:retval!=nil?[retval getTree]:nil] retain];

        root_0 = (ANTLRCommonTree *)[[[treeAdaptor class] newEmptyTree] retain];

        // 8:19: -> ^( subrule INT )
        {
            // TreeRewrite.g:8:22: ^( subrule INT )
            {
                ANTLRCommonTree *root_1 = (ANTLRCommonTree *)[[[treeAdaptor class] newEmptyTree] retain];
                root_1 = (ANTLRCommonTree *)[treeAdaptor becomeRoot:(id<ANTLRTree>)[stream_subrule nextNode] old:root_1];

                 // TODO: args: 
                [treeAdaptor addChild:
                            [stream_INT nextNode]
                 toTree:root_1];

                [treeAdaptor addChild:root_1 toTree:root_0];
            }

        }


        retval.tree = root_0;


        }

        /* ASTParser ruleCleanUp */
        /* AST ruleCleanUp */
        // token+rule list labels
        [retval setStop:[input LT:-1]];


        [stream_INT release];
        [stream_subrule release];

            retval.tree = (ANTLRCommonTree *)[treeAdaptor rulePostProcessing:root_0];
            [treeAdaptor setTokenBoundaries:retval.tree From:retval.start To:retval.stopToken];

    }
    @catch (ANTLRRecognitionException *re) {
        [self reportError:re];
        [self recover:input Exception:re];
        /* ASTParser rule.setErrorReturnValue */
        retval.tree = (ANTLRCommonTree *)[treeAdaptor errorNode:input From:retval.start To:[input LT:-1] Exception:re];

    }

    @finally {
        /* Terence's stuff */

    }
    return retval;
}
/* $ANTLR end rule */

/*
 * $ANTLR start subrule
 * TreeRewrite.g:11:1: subrule : INT ;
 */
- (TreeRewriteParser_subrule_return *) subrule
{
    /* my ruleScopeSetUp */
    /* Terence's stuff */

    /* AST ruleDeclarations */
    TreeRewriteParser_subrule_return * retval = [TreeRewriteParser_subrule_return newTreeRewriteParser_subrule_return];
    [retval setStart:[input LT:1]];


    ANTLRCommonTree *root_0 = nil;

    @try {
        /* AST ruleLabelDefs */
        ANTLRCommonToken *INT3 = nil;

        ANTLRCommonTree *INT3_tree=nil;

        // TreeRewrite.g:12:5: ( INT ) // ruleBlockSingleAlt
        // TreeRewrite.g:12:9: INT // alt
        {
        root_0 = (ANTLRCommonTree *)[[[treeAdaptor class] newEmptyTree] retain];


        /* ASTParser tokenRef */
        INT3=(ANTLRCommonToken *)[self match:input TokenType:INT Follow:FOLLOW_INT_in_subrule53]; 
        INT3_tree = /* ASTParser createNodeFromToken */
        (ANTLRCommonTree *)[[treeAdaptor create:INT3] retain]
        ;
        [treeAdaptor addChild:INT3_tree  toTree:root_0];


        }

        /* ASTParser ruleCleanUp */
        /* AST ruleCleanUp */
        // token+rule list labels
        [retval setStop:[input LT:-1]];



            retval.tree = (ANTLRCommonTree *)[treeAdaptor rulePostProcessing:root_0];
            [treeAdaptor setTokenBoundaries:retval.tree From:retval.start To:retval.stopToken];

    }
    @catch (ANTLRRecognitionException *re) {
        [self reportError:re];
        [self recover:input Exception:re];
        /* ASTParser rule.setErrorReturnValue */
        retval.tree = (ANTLRCommonTree *)[treeAdaptor errorNode:input From:retval.start To:[input LT:-1] Exception:re];

    }

    @finally {
        /* Terence's stuff */

    }
    return retval;
}
/* $ANTLR end subrule */
/* ObjC end rules */

@end /* end of TreeRewriteParser implementation line 692 */
