/** \file
 *  This OBJC source file was generated by $ANTLR version ${project.version} ${buildNumber}
 *
 *     -  From the grammar source file : Lang.g
 *     -                            On : 2011-05-06 17:38:52
 *     -                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 ${project.version} ${buildNumber} Lang.g 2011-05-06 17:38:52


/* -----------------------------------------
 * 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 Scopes

#pragma mark Dynamic Rule Scopes

#pragma mark Rule Return Scopes start
@implementation LangParser_start_return /* returnScope */
/* 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 */
- (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 LangParser_decl_return /* returnScope */
/* 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 */
- (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 LangParser_type_return /* returnScope */
/* 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 */
- (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 LangParser  // 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_decl_in_start41 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_decl_in_start41_data Count:(NSUInteger)1] retain];
    FOLLOW_type_in_decl50 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_type_in_decl50_data Count:(NSUInteger)1] retain];
    FOLLOW_ID_in_decl52 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_ID_in_decl52_data Count:(NSUInteger)1] retain];
    FOLLOW_10_in_decl54 = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)FOLLOW_10_in_decl54_data Count:(NSUInteger)1] retain];

    [ANTLRBaseRecognizer setTokenNames:[[AMutableArray arrayWithObjects:@"<invalid>", @"<EOR>", @"<DOWN>", @"<UP>", 
 @"DECL", @"FLOATTYPE", @"ID", @"INT", @"INTTYPE", @"WS", @"';'", nil] retain]];
    [ANTLRBaseRecognizer setGrammarFileName:@"Lang.g"];
}

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


}

- (id) initWithTokenStream:(id<ANTLRTokenStream>)aStream
{
    self = [super initWithTokenStream:aStream State:[[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:3+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 start
 * Lang.g:10:1: start : decl ;
 */
- (LangParser_start_return *) start
{
    /* my ruleScopeSetUp */
    /* Terence's stuff */

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


    ANTLRCommonTree *root_0 = nil;

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


        // Lang.g:10:7: ( decl ) // ruleBlockSingleAlt
        // Lang.g:10:9: decl // alt
        {
        root_0 = (ANTLRCommonTree *)[[[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 = (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 start */

/*
 * $ANTLR start decl
 * Lang.g:12:1: decl : type ID ';' -> ^( DECL type ID ) ;
 */
- (LangParser_decl_return *) decl
{
    /* my ruleScopeSetUp */
    /* Terence's stuff */

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


    ANTLRCommonTree *root_0 = nil;

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

        ANTLRCommonTree *ID3_tree=nil;
        ANTLRCommonTree *char_literal4_tree=nil;
        ANTLRRewriteRuleTokenStream *stream_10 =
            [[ANTLRRewriteRuleTokenStream newANTLRRewriteRuleTokenStream:treeAdaptor
                                                             description:@"token 10"] retain];
        ANTLRRewriteRuleTokenStream *stream_ID =
            [[ANTLRRewriteRuleTokenStream newANTLRRewriteRuleTokenStream:treeAdaptor
                                                             description:@"token ID"] retain];
        ANTLRRewriteRuleSubtreeStream *stream_type =
            [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor
                                                                description:@"rule type"] retain];
        // Lang.g:12:6: ( type ID ';' -> ^( DECL type ID ) ) // ruleBlockSingleAlt
        // 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=(ANTLRCommonToken *)[self match:input TokenType:ID Follow:FOLLOW_ID_in_decl52];  
            [stream_ID addElement:ID3];


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


        // AST REWRITE
        // elements: ID, type
        // 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];

        // 12:20: -> ^( DECL type ID )
        {
            // Lang.g:12:23: ^( DECL type ID )
            {
                ANTLRCommonTree *root_1 = (ANTLRCommonTree *)[[[treeAdaptor class] newEmptyTree] retain];
                root_1 = (ANTLRCommonTree *)[treeAdaptor becomeRoot:
                        [treeAdaptor createTree:DECL Text:@"DECL"]
                 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 = (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 decl */

/*
 * $ANTLR start type
 * Lang.g:14:1: type : ( INTTYPE | FLOATTYPE );
 */
- (LangParser_type_return *) type
{
    /* my ruleScopeSetUp */
    /* Terence's stuff */

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


    ANTLRCommonTree *root_0 = nil;

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

        ANTLRCommonTree *set5_tree=nil;

        // Lang.g:14:6: ( INTTYPE | FLOATTYPE ) // ruleBlockSingleAlt
        // Lang.g: // alt
        {
        root_0 = (ANTLRCommonTree *)[[[treeAdaptor class] newEmptyTree] retain];


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

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


        }

        /* 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 type */
/* ObjC end rules */

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