/** \file
 *  This OBJC source file was generated by $ANTLR version 3.4
 *
 *     -  From the grammar source file : /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g
 *     -                            On : 2012-02-16 17:58:54
 *     -                for the parser : LangParserParser
 *
 * Editing it, at least manually, is not wise.
 *
 * ObjC language generator and runtime by Alan Condit, acondit|hereisanat|ipns|dotgoeshere|com.
 *
 *
*/
// $ANTLR 3.4 /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g 2012-02-16 17:58:54


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


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

#pragma mark Bitsets
static ANTLRBitSet *FOLLOW_decl_in_start41;
static const unsigned long long FOLLOW_decl_in_start41_data[] = { 0x0000000000000002LL};
static ANTLRBitSet *FOLLOW_type_in_decl50;
static const unsigned long long FOLLOW_type_in_decl50_data[] = { 0x0000000000000040LL};
static ANTLRBitSet *FOLLOW_ID_in_decl52;
static const unsigned long long FOLLOW_ID_in_decl52_data[] = { 0x0000000000000400LL};
static ANTLRBitSet *FOLLOW_10_in_decl54;
static const unsigned long long FOLLOW_10_in_decl54_data[] = { 0x0000000000000002LL};


#pragma mark Dynamic Global globalAttributeScopeImplementation

#pragma mark Dynamic Rule Scopes ruleAttributeScopeImplementation

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

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

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

- (void) setTree:(CommonTree *)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 LangParser_decl_return /* returnScopeImplementation */
/* AST returnScope.synthesize */
@synthesize tree; /* start of synthesize -- OBJC-Line 1837 */
+ (LangParser_decl_return *)newLangParser_decl_return
{
return [[[LangParser_decl_return alloc] init] retain];
}

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

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

- (void) setTree:(CommonTree *)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 LangParser_type_return /* returnScopeImplementation */
/* AST returnScope.synthesize */
@synthesize tree; /* start of synthesize -- OBJC-Line 1837 */
+ (LangParser_type_return *)newLangParser_type_return
{
return [[[LangParser_type_return alloc] init] retain];
}

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

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

- (void) setTree:(CommonTree *)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 LangParser  // line 637

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

+ (void) initialize
{
    #pragma mark Bitsets
    FOLLOW_decl_in_start41 = [[ANTLRBitSet newBitSetWithBits:(const unsigned long long *)FOLLOW_decl_in_start41_data Count:(NSUInteger)1] retain];
    FOLLOW_type_in_decl50 = [[ANTLRBitSet newBitSetWithBits:(const unsigned long long *)FOLLOW_type_in_decl50_data Count:(NSUInteger)1] retain];
    FOLLOW_ID_in_decl52 = [[ANTLRBitSet newBitSetWithBits:(const unsigned long long *)FOLLOW_ID_in_decl52_data Count:(NSUInteger)1] retain];
    FOLLOW_10_in_decl54 = [[ANTLRBitSet newBitSetWithBits:(const unsigned long long *)FOLLOW_10_in_decl54_data Count:(NSUInteger)1] retain];

    [BaseRecognizer setTokenNames:[[AMutableArray arrayWithObjects:@"<invalid>", @"<EOR>", @"<DOWN>", @"<UP>", 
 @"DECL", @"FLOATTYPE", @"ID", @"INT", @"INTTYPE", @"WS", @"';'", nil] retain]];
    [BaseRecognizer setGrammarFileName:@"/Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g"];
}

+ (LangParser *)newLangParser:(id<TokenStream>)aStream
{
    return [[LangParser alloc] initWithTokenStream:aStream];
}

- (id) initWithTokenStream:(id<TokenStream>)aStream
{
    self = [super initWithTokenStream:aStream State:[[RecognizerSharedState newRecognizerSharedStateWithRuleLen:3+1] retain]];
    if ( self != nil ) {
        /* start of actions-actionScope-init */
        /* start of init */
        /* AST genericParser.init */
        [self setTreeAdaptor:[[CommonTreeAdaptor newTreeAdaptor] retain]];
    }
    return self;
}

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

    [super dealloc];
}

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

- (void) setTreeAdaptor:(id<TreeAdaptor>)aTreeAdaptor
{
	if (aTreeAdaptor != treeAdaptor) {
		treeAdaptor = aTreeAdaptor;
	}
}
/* ObjC end methods() */
/* ObjC start rules */
/*
 * $ANTLR start start
 * /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:10:1: start : decl ;
 */
- (LangParser_start_return *) start
{
    /* ruleScopeSetUp */

    /* AST ruleDeclarations */
    /* ruleDeclarations */
    LangParser_start_return * retval = [LangParser_start_return newLangParser_start_return];
    [retval setStart:[input LT:1]];


    CommonTree *root_0 = nil;

    @try {
        /* AST ruleLabelDefs */
        /* ruleLabelDefs entry */
        LangParser_decl_return * decl1 = nil ;



        // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:10:7: ( decl ) // ruleBlockSingleAlt
        // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:10:9: decl // alt
        {
        root_0 = (CommonTree *)[[[treeAdaptor class] newEmptyTree] retain];



        /* ASTParser ruleRef */
        /* ruleRef */
        [self pushFollow:FOLLOW_decl_in_start41];
        decl1 = [self decl];

        [self popFollow];


        [treeAdaptor addChild:[decl1 getTree] toTree:root_0];
         
        }

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



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

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

    }

    @finally {
        /* ruleScopeCleanUp */

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

/*
 * $ANTLR start decl
 * /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:12:1: decl : type ID ';' -> ^( DECL type ID ) ;
 */
- (LangParser_decl_return *) decl
{
    /* ruleScopeSetUp */

    /* AST ruleDeclarations */
    /* ruleDeclarations */
    LangParser_decl_return * retval = [LangParser_decl_return newLangParser_decl_return];
    [retval setStart:[input LT:1]];


    CommonTree *root_0 = nil;

    @try {
        /* AST ruleLabelDefs */
        /* ruleLabelDefs entry */
        CommonToken *ID3 = nil;
        CommonToken *char_literal4 = nil;LangParser_type_return * type2 = nil ;


        CommonTree *ID3_tree=nil;
        CommonTree *char_literal4_tree=nil;
        RewriteRuleTokenStream *stream_10 =
            [[RewriteRuleTokenStream newRewriteRuleTokenStream:treeAdaptor
                                                             description:@"token 10"] retain];
        RewriteRuleTokenStream *stream_ID =
            [[RewriteRuleTokenStream newRewriteRuleTokenStream:treeAdaptor
                                                             description:@"token ID"] retain];
        RewriteRuleSubtreeStream *stream_type =
            [[RewriteRuleSubtreeStream newRewriteRuleSubtreeStream:treeAdaptor
                                                                description:@"rule type"] retain];
        // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:12:6: ( type ID ';' -> ^( DECL type ID ) ) // ruleBlockSingleAlt
        // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:12:8: type ID ';' // alt
        {

        /* ruleRef */
        [self pushFollow:FOLLOW_type_in_decl50];
        type2 = [self type];

        [self popFollow];


        [stream_type addElement:[type2 getTree]];
         
        ID3=(CommonToken *)[self match:input TokenType:ID Follow:FOLLOW_ID_in_decl52];  
            [stream_ID addElement:ID3];

         
        char_literal4=(CommonToken *)[self match:input TokenType:10 Follow:FOLLOW_10_in_decl54];  
            [stream_10 addElement:char_literal4];

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

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

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

        // 12:20: -> ^( DECL type ID )
        {
            // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:12:23: ^( DECL type ID )
            {
                CommonTree *root_1 = (CommonTree *)[[[treeAdaptor class] newEmptyTree] retain];
                root_1 = (CommonTree *)[treeAdaptor becomeRoot:
                        [[treeAdaptor createTree:DECL Text:@"DECL"] retain]
                 old:root_1];

                [treeAdaptor addChild:[stream_type nextTree] toTree:root_1];

                 // TODO: args: 
                [treeAdaptor addChild:
                            [stream_ID 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_10 release];
        [stream_ID release];
        [stream_type release];

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

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

    }

    @finally {
        /* ruleScopeCleanUp */

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

/*
 * $ANTLR start type
 * /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:14:1: type : ( INTTYPE | FLOATTYPE );
 */
- (LangParser_type_return *) type
{
    /* ruleScopeSetUp */

    /* AST ruleDeclarations */
    /* ruleDeclarations */
    LangParser_type_return * retval = [LangParser_type_return newLangParser_type_return];
    [retval setStart:[input LT:1]];


    CommonTree *root_0 = nil;

    @try {
        /* AST ruleLabelDefs */
        /* ruleLabelDefs entry */
        CommonToken *set5 = nil;

        CommonTree *set5_tree=nil;

        // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g:14:6: ( INTTYPE | FLOATTYPE ) // ruleBlockSingleAlt
        // /Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/treeparser/Lang.g: // alt
        {
        root_0 = (CommonTree *)[[[treeAdaptor class] newEmptyTree] retain];



        /* ASTParser matchRuleBlockSet */
        /* ASTParser matchSet */
        set5 = (CommonToken *)[input LT:1]; /* matchSet */

        if ([input LA:1] == FLOATTYPE||[input LA:1] == INTTYPE) {
            [input consume];
            [treeAdaptor addChild:/* ASTParser createNodeFromToken */
            (CommonTree *)[[treeAdaptor create:set5] retain]
             toTree:root_0 ];
            [state setIsErrorRecovery:NO];
        } else {
            MismatchedSetException *mse = [MismatchedSetException newException:nil stream:input];
            @throw mse;
        }

         
        }

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



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

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

    }

    @finally {
        /* ruleScopeCleanUp */

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

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