/*
 [The "BSD license"]
 Copyright (c) 2006, 2007 Kay Roepke 2010 Alan Condit
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
 *  Template group file for the Objective C code generator.
 *  Heavily based on Java.stg
 *
 *  Written by Kay Roepke <kroepke(at)classdump.org>
 *  Modified by Alan Condit <acondit(at)ipns.com>
 *
 *  This file is part of ANTLR and subject to the same license as ANTLR itself.
 */

objcTypeInitMap ::= [
    "int"           : "0",              // Integers     start out being 0
    "long"          : "0",              // Longs        start out being 0
    "float"         : "0.0",            // Floats       start out being 0
    "double"        : "0.0",            // Doubles      start out being 0
    "BOOL"          : "NO",             // Booleans     start out being Antlr ObjC for false
    "byte"          : "0",              // Bytes        start out being 0
    "short"         : "0",              // Shorts       start out being 0
    "char"          : "0",              // Chars        start out being 0
    "id"            : "nil",            // ids          start out being nil
    default         : "nil"             // anything other than an atomic type
]

className() ::= "<name><!<if(LEXER)>Lexer<else><if(TREE_PARSER)>Tree<endif>Parser<endif>!>"
leadIn(type) ::=
<<
/** \file
 *  This <type> file was generated by $ANTLR version <ANTLRVersion>
 *
 *     -  From the grammar source file : <fileName>
 *     -                            On : <generatedTimestamp>
<if(LEXER)>
 *     -                 for the lexer : <name>Lexer
<endif>
<if(PARSER)>
 *     -                for the parser : <name>Parser
<endif>
<if(TREE_PARSER)>
 *     -           for the tree parser : <name>TreeParser
<endif>
 *
 * Editing it, at least manually, is not wise.
 *
 * ObjC language generator and runtime by Alan Condit, acondit|hereisanat|ipns|dotgoeshere|com.
 *
 *
>>

/** The overall file structure of a recognizer; stores methods for rules
 *  and cyclic DFAs plus support code.
 */
outputFile( LEXER,
            PARSER,
            TREE_PARSER,
            actionScope,
            actions,
            docComment,
            recognizer,
            name,
            tokens,
            tokenNames,
            rules,
            cyclicDFAs,
            bitsets,
            buildTemplate,
            buildAST,
            rewriteMode,
            profile,
            backtracking,
            synpreds,
            memoize,
            numRules,
            fileName,
            ANTLRVersion,
            generatedTimestamp,
            trace,
            scopes,
            superClass,
            literals
            ) ::=
<<
<leadIn("OBJC source")>
*/
// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>

<! <if(actions.(actionScope).header)>
/* =============================================================================
 * This is what the grammar programmer asked us to put at the top of every file.
 */
<actions.(actionScope).header>
/* End of Header action.
 * =============================================================================
 */
<endif> !>

/* -----------------------------------------
 * Include the ANTLR3 generated header file.
 */
#import "<name><!<if(LEXER)>Lexer<else><if(TREE_PARSER)>Tree<endif>Parser<endif>!>.h"
<actions.(actionScope).postinclude>
/* ----------------------------------------- */

<docComment>

<if(literals)>
/** String literals used by <name> that we must do things like MATCHS() with.
 *  C will normally just lay down 8 bit characters, and you can use L"xxx" to
 *  get wchar_t, but wchar_t is 16 bits on Windows, which is not UTF32 and so
 *  we perform this little trick of defining the literals as arrays of UINT32
 *  and passing in the address of these.
 */
<literals:{it | static ANTLR3_UCHAR  lit_<i>[]  = <it>;}; separator="\n">

<endif>

/* ============================================================================= */
/* =============================================================================
 * Start of recognizer
 */
<recognizer>
>>
headerFileExtension() ::= ".h"

headerFile( LEXER,
            PARSER,
            TREE_PARSER,
            actionScope,
            actions,
            docComment,
            recognizer,
            name,
            tokens,
            tokenNames,
            rules,
            cyclicDFAs,
            bitsets,
            buildTemplate,
            buildAST,
            rewriteMode,
            profile,
            backtracking,
            synpreds,
            memoize,
            numRules,
            fileName,
            ANTLRVersion,
            generatedTimestamp,
            trace,
            scopes,
            superClass,
            literals
          ) ::=
<<
// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>

<@imports>
<actions.(actionScope).preincludes>
/* =============================================================================
 * Standard antlr3 OBJC runtime definitions
 */
#import \<Foundation/Foundation.h>
#import \<ANTLR/ANTLR.h>
/* End of standard antlr3 runtime definitions
 * =============================================================================
 */
<actions.(actionScope).includes>
<@end>

<if(LEXER)>
<lexerHeaderFile(...)>
<endif>
<if(PARSER)>
<parserHeaderFile(...)>
<endif>
<if(TREE_PARSER)>
<treeParserHeaderFile(...)>
<endif>
<docComment>
>>

lexerHeaderFile( LEXER,
            PARSER,
            TREE_PARSER,
            actionScope,
            actions,
            docComment,
            recognizer,
            name,
            tokens,
            tokenNames,
            rules,
            cyclicDFAs,
            bitsets,
            buildTemplate,
            profile,
            backtracking,
            synpreds,
            memoize,
            numRules,
            fileName,
            ANTLRVersion,
            generatedTimestamp,
            trace,
            scopes,
            superClass="ANTLRLexer"
            ) ::=
<<

<if(actions.(actionScope).header)>
/* =============================================================================
 * This is what the grammar programmer asked us to put at the top of every file.
 */
<actions.(actionScope).header>
/* End of Header action.
 * =============================================================================
 */
<endif>

/* Start cyclicDFAInterface */
<cyclicDFAs:cyclicDFAInterface()>

#pragma mark Rule return scopes Interface start
<rules:{rule |
<rule.ruleDescriptor:{ruleDescriptor | <returnScopeInterface(scope=ruleDescriptor.returnScope)>}>}>
#pragma mark Rule return scopes Interface end
#pragma mark Tokens
#ifdef EOF
#undef EOF
#endif
<tokens:{it | #define <it.name> <it.type>}; separator="\n">
/* interface lexer class */
@interface <className()> <@superClassName>: <superClass><@end> { // line 283
<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> *dfa<dfa.decisionNumber>;}; separator="\n">
<synpreds:{pred | SEL <pred>Selector;}; separator="\n">
/* ObjC start of actions.lexer.memVars */
<actions.lexer.memVars>
/* ObjC end of actions.lexer.memVars */
}
+ (void) initialize;
+ (<className()> *)new<className()>WithCharStream:(id\<ANTLRCharStream>)anInput;
/* ObjC start actions.lexer.methodsDecl */
<actions.lexer.methodsDecl>
/* ObjC end actions.lexer.methodsDecl */
<rules:{rule |
- (<rule.ruleDescriptor:{ruleDescriptor|<returnType()>}>) <if(!rule.ruleDescriptor.isSynPred)>m<rule.ruleName><else><rule.ruleName>_fragment<endif> <if(rule.ruleDescriptor.parameterScope)><rule.ruleDescriptor.parameterScope:parameterScope()><endif>; }; separator="\n"><\n>
@end /* end of <className()> interface */<\n>
>>

headerReturnScope(ruleDescriptor) ::= "<returnScopeInterface(...)>"
headerReturnType(ruleDescriptor) ::= <<
<if(LEXER)>
<if(!r.ruleDescriptor.isSynPred)>
 void
<else>
 <ruleDescriptor:returnType()>
<endif>
<else>
 <ruleDescriptor:returnType()>
<endif>
>>
// Produce the lexer output
lexer(  grammar,
        name,
        tokens,
        scopes,
        rules,
        numRules,
        filterMode,
        labelType="ANTLRCommonToken",
        superClass="ANTLRLexer"
        ) ::= <<
<cyclicDFAs:cyclicDFA()>

/** As per Terence: No returns for lexer rules! */
<!
#pragma mark Rule return scopes start
<rules:{rule | <rule.ruleDescriptor:{ruleDescriptor | 
<returnScopeImplementation(scope=ruleDescriptor.returnScope)>}>
}>
#pragma mark Rule return scopes end
!>
@implementation <grammar.recognizerName> // line 330

+ (void) initialize
{
    [ANTLRBaseRecognizer setGrammarFileName:@"<fileName>"];
}

+ (NSString *) tokenNameForType:(NSInteger)aTokenType
{
    return [[self getTokenNames] objectAtIndex:aTokenType];
}

+ (<grammar.recognizerName> *)new<grammar.recognizerName>WithCharStream:(id\<ANTLRCharStream>)anInput
{
    return [[<grammar.recognizerName> alloc] initWithCharStream:anInput];
}

- (id) initWithCharStream:(id\<ANTLRCharStream>)anInput
{
    self = [super initWithCharStream:anInput State:[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:<numRules>+1]];
    if ( self != nil ) {
<if(memoize)>
        if ( state.ruleMemo == nil ) {
            state.ruleMemo = [[ANTLRRuleStack newANTLRRuleStackWithSize:<numRules>+1] retain];
        }
        if ( [state.ruleMemo count] == 0 ) {
            // initialize the memoization cache - the indices are 1-based in the runtime code!
            <! [state.ruleMemo addObject:[NSNull null]];     /* dummy entry to ensure 1-basedness. */ !>
            for (NSInteger i = 0; i \< <numRules>; i++) {
                [state.ruleMemo addObject:[ANTLRHashRule newANTLRHashRuleWithLen:17]];
            }
        }
<endif>
        <synpreds:{pred | <lexerSynpred(name=pred)>};separator="\n">
        <cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = [DFA<dfa.decisionNumber> newDFA<dfa.decisionNumber>WithRecognizer:self];}; separator="\n">
        <actions.lexer.init>
    }
    return self;
}

- (void) dealloc
{
    <cyclicDFAs:{dfa | [dfa<dfa.decisionNumber> release];}; separator="\n">
<actions.lexer.dealloc>
    [super dealloc];
}

/* ObjC Start of actions.lexer.methods */
<actions.lexer.methods>
/* ObjC end of actions.lexer.methods */
/* ObjC start methods() */
<@methods()>
/* ObjC end methods() */

<if(actions.lexer.reset)>
- (void) reset
{
    <actions.lexer.reset>
    [super reset];
}
<endif>

<if(filterMode)>
<filteringNextToken()>
<endif>
/* Start of Rules */
<rules; separator="\n">

@end /* end of <grammar.recognizerName> implementation line 397 */
>>

/** A override of Lexer.nextToken() that backtracks over mTokens() looking
 *  for matches.  No error can be generated upon error; just rewind, consume
 *  a token and then try again.  backtracking needs to be set as well.
 *  Make rule memoization happen only at levels above 1 as we start mTokens
 *  at backtracking==1.
 */
filteringNextToken() ::= <<
- (id\<ANTLRToken>) nextToken
{
    while (YES) {
        if ( [input LA:1] == ANTLRCharStreamEOF ) {
            return [<labelType> eofToken];
        }
        state.token = nil;
        state.channel = ANTLRTokenChannelDefault;
        state.tokenStartCharIndex = input.index;
        state.tokenStartCharPositionInLine = input.charPositionInLine;
        state.tokenStartLine = input.line;
        state.text = nil;
        @try {
            NSInteger m = [input mark];
            state.backtracking = 1; /* means we won't throw slow exception */
            state.failed = NO;
            [self mTokens];
            state.backtracking = 0;
            /* mTokens backtracks with synpred at backtracking==2
               and we set the synpredgate to allow actions at level 1. */
            if ( state.failed ) {
                [input rewind:m];
                [input consume]; /* advance one char and try again */
            } else {
                [self emit];
                return state.token;
            }
        }
        @catch (ANTLRRecognitionException *re) {
            // shouldn't happen in backtracking mode, but...
            [self reportError:re];
            [self recover:re];
        }
    }
}

- (void)memoize:(id\<ANTLRIntStream\>)anInput
      RuleIndex:(NSInteger)ruleIndex
     StartIndex:(NSInteger)ruleStartIndex
{
    if ( state.backtracking > 1 ) [super memoize:anInput RuleIndex:ruleIndex StartIndex:ruleStartIndex];
}

- (BOOL)alreadyParsedRule:(id\<ANTLRIntStream\>)anInput RuleIndex:(NSInteger)ruleIndex
{
    if ( state.backtracking > 1 ) return [super alreadyParsedRule:anInput RuleIndex:ruleIndex];
    return NO;
}
>>

actionGate() ::= "state.backtracking == 0"

filteringActionGate() ::= "state.backtracking == 1"

parserHeaderFile( LEXER,
            PARSER,
            TREE_PARSER,
            actionScope,
            actions,
            docComment,
            recognizer,
            name,
            tokens,
            tokenNames,
            rules,
            cyclicDFAs,
            bitsets,
            buildTemplate,
            profile,
            backtracking,
            synpreds,
            memoize,
            numRules,
            fileName,
            ANTLRVersion,
            generatedTimestamp,
            trace,
            scopes,
            literals,
            superClass="ANTLRParser"
            ) ::= <<
/* parserHeaderFile */
<genericParserHeaderFile(inputStreamType="id\<ANTLRTokenStream>",...)>
>>

treeParserHeaderFile( LEXER,
            PARSER,
            TREE_PARSER,
            actionScope,
            actions,
            docComment,
            recognizer,
            name,
            tokens,
            tokenNames,
            rules,
            cyclicDFAs,
            bitsets,
            buildTemplate,
            profile,
            backtracking,
            synpreds,
            memoize,
            numRules,
            fileName,
            ANTLRVersion,
            generatedTimestamp,
            trace,
            scopes,
            literals,
            superClass="ANTLRTreeParser"
            ) ::= <<
/* treeParserHeaderFile */
<genericParserHeaderFile(inputStreamType="id\<ANTLRTreeNodeStream>",...)>
>>

genericParserHeaderFile( LEXER,
            PARSER,
            TREE_PARSER,
            actionScope,
            actions,
            docComment,
            recognizer,
            name,
            tokens,
            tokenNames,
            rules,
            cyclicDFAs,
            bitsets,
            buildTemplate,
            profile,
            backtracking,
            synpreds,
            memoize,
            numRules,
            fileName,
            ANTLRVersion,
            generatedTimestamp,
            trace,
            scopes,
            superClass,
            literals,
            inputStreamType
            ) ::=
<<
<if(actions.(actionScope).header)>
/* =============================================================================
 * This is what the grammar programmer asked us to put at the top of every file.
 */
<actions.(actionScope).header>
/* End of Header action.
 * =============================================================================
 */
<endif>

#ifndef ANTLR3TokenTypeAlreadyDefined
#define ANTLR3TokenTypeAlreadyDefined
typedef enum {
    ANTLR_EOF = -1,
    INVALID,
    EOR,
    DOWN,
    UP,
    MIN
} ANTLR3TokenType;
#endif

<cyclicDFAs:cyclicDFAInterface()>
#pragma mark Tokens
#ifdef EOF
#undef EOF
#endif
<tokens:{it | #define <it.name> <it.type>}; separator="\n">
#pragma mark Dynamic Global Scopes globalAttributeScopeInterface
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeInterface(scope=it)><endif>}>
#pragma mark Dynamic Rule Scopes ruleAttributeScopeInterface
<rules:{rule |
<rule.ruleDescriptor:{ ruleDescriptor | <ruleAttributeScopeInterface(scope=ruleDescriptor.ruleScope)>}>}>
#pragma mark Rule Return Scopes returnScopeInterface
<rules:{rule |<rule.ruleDescriptor:{ ruleDescriptor | <returnScopeInterface(scope=ruleDescriptor.returnScope)>}>}>

/* Interface grammar class */
@interface <className()> <@superClassName> : <superClass><@end> { /* line 572 */
#pragma mark Dynamic Rule Scopes ruleAttributeScopeDecl
<rules:{rule | <rule.ruleDescriptor.ruleScope:ruleAttributeScopeDecl(scope=rule.ruleDescriptor.ruleScope)>}>
#pragma mark Dynamic Global Rule Scopes globalAttributeScopeMemVar
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeMemVar(scope=it)><endif>}><\n>
/* ObjC start of actions.(actionScope).memVars */
<actions.(actionScope).memVars>
/* ObjC end of actions.(actionScope).memVars */
/* ObjC start of memVars */
<@memVars()>
/* ObjC end of memVars */

<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> *dfa<dfa.decisionNumber>;}; separator="\n">
<synpreds:{pred | SEL <pred>Selector;}; separator="\n">
 }

/* ObjC start of actions.(actionScope).properties */
<actions.(actionScope).properties>
/* ObjC end of actions.(actionScope).properties */
/* ObjC start of properties */
<@properties()>
/* ObjC end of properties */

+ (void) initialize;
+ (id) new<className()>:(<inputStreamType>)aStream;
/* ObjC start of actions.(actionScope).methodsDecl */
<actions.(actionScope).methodsDecl>
/* ObjC end of actions.(actionScope).methodsDecl */

/* ObjC start of methodsDecl */
<@methodsDecl()>
/* ObjC end of methodsDecl */

<rules:{rule |
- (<rule.ruleDescriptor:{ruleDescriptor|<returnType()>}>)<if(!rule.ruleDescriptor.isSynPred)><rule.ruleName><else><rule.ruleName>_fragment<endif><if(rule.ruleDescriptor.parameterScope)><rule.ruleDescriptor.parameterScope:parameterScope()><endif>; }; separator="\n"><\n>

@end /* end of <className()> interface */<\n>
>>

parser( grammar,
        name,
        scopes,
        tokens,
        tokenNames,
        rules,
        numRules,
        bitsets,
        ASTLabelType="ANTLRCommonTree",
        superClass="ANTLRParser",
        labelType="ANTLRCommonToken",
        members={<actions.parser.members>}
        ) ::= <<
<genericParser(inputStreamType="id\<ANTLRTokenStream>", rewriteElementType="Token", ...)>
>>

/** How to generate a tree parser; same as parser except the input
 *  stream is a different type.
 */
treeParser( grammar,
        name,
        scopes,
        tokens,
        tokenNames,
        globalAction,
        rules,
        numRules,
        bitsets,
        filterMode,
        labelType={<ASTLabelType>},
        ASTLabelType="ANTLRCommonTree",
        superClass={<if(filterMode)><if(buildAST)>ANTLRTreeRewriter<else>ANTLRTreeFilter<endif><else>ANTLRTreeParser<endif>},
        members={<actions.treeparser.members>}
        ) ::= <<
<genericParser(inputStreamType="id\<ANTLRTreeNodeStream>", rewriteElementType="Node", ...)>
>>

/** How to generate a parser */
genericParser(  grammar,
        name,
        scopes,
        tokens,
        tokenNames,
        rules,
        numRules,
        cyclicDFAs,          // parser init -- initializes the DFAs
        bitsets,
        labelType,
        ASTLabelType,
        superClass,
        members,
        filterMode,
        rewriteElementType,
        inputStreamType
        ) ::= <<
<cyclicDFAs:cyclicDFA()>

#pragma mark Bitsets
<bitsets:{it | <bitset(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}>

#pragma mark Dynamic Global globalAttributeScopeImplementation
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeImplementation(scope=it)><endif>}>

#pragma mark Dynamic Rule Scopes ruleAttributeScopeImplementation
<rules:{rule |
<rule.ruleDescriptor:{ ruleDescriptor | <ruleAttributeScopeImplementation(scope=ruleDescriptor.ruleScope)>}>}>

#pragma mark Rule Return Scopes returnScopeImplementation
<rules:{rule | <rule.ruleDescriptor:{ ruleDescriptor | <returnScopeImplementation(scope=ruleDescriptor.returnScope)>}>}>

@implementation <grammar.recognizerName>  // line 637

#pragma mark Dynamic Rule Scopes ruleAttributeScope
<rules:{rule | <rule.ruleDescriptor.ruleScope:ruleAttributeScope()>}>
#pragma mark global Attribute Scopes globalAttributeScope
<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScope()><endif>}>
/* ObjC start actions.(actionScope).synthesize */
<actions.(actionScope).synthesize>
/* ObjC start synthesize() */
<@synthesize()>

+ (void) initialize
{
    #pragma mark Bitsets
    <bitsets:{it | <bitsetInit(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}>
    [ANTLRBaseRecognizer setTokenNames:[[AMutableArray arrayWithObjects:@"\<invalid>", @"\<EOR>", @"\<DOWN>", @"\<UP>", <tokenNames:{it | @<it>}; separator=", ", wrap="\n ">, nil] retain]];
    [ANTLRBaseRecognizer setGrammarFileName:@"<fileName>"];
    <synpreds:{pred | <synpred(pred)>}>
}

+ (<grammar.recognizerName> *)new<grammar.recognizerName>:(<inputStreamType>)aStream
{
<if(PARSER)>
    return [[<grammar.recognizerName> alloc] initWithTokenStream:aStream];
<else><! TREE_PARSER !>
    return [[<grammar.recognizerName> alloc] initWithStream:aStream];
<endif>
}

<if(PARSER)>
- (id) initWithTokenStream:(<inputStreamType>)aStream
{
    self = [super initWithTokenStream:aStream State:[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:<numRules>+1]];
    if ( self != nil ) {
<else><! TREE_PARSER !>
- (id) initWithStream:(<inputStreamType>)aStream
{
    self = [super initWithStream:aStream State:[[ANTLRRecognizerSharedState newANTLRRecognizerSharedStateWithRuleLen:<numRules>+1] retain]];
    if ( self != nil ) {
<endif>
        <! <parserCtorBody()> !>
        <cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = [DFA<dfa.decisionNumber> newDFA<dfa.decisionNumber>WithRecognizer:self];}; separator="\n">
        <scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeInit(scope=it)><endif>}>
        <rules:{rule | <rule.ruleDescriptor.ruleScope:ruleAttributeScopeInit()>}>
        /* start of actions-actionScope-init */
        <actions.(actionScope).init>
        /* start of init */
        <@init()>
    }
    return self;
}

- (void) dealloc
{
    <cyclicDFAs:{dfa | [dfa<dfa.decisionNumber> release];}; separator="\n">
    <scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeDealloc(scope=it)><endif>}>
    <actions.(actionScope).dealloc>
    <@dealloc()>
    [super dealloc];
}

/* ObjC start actions.(actionScope).methods */
<actions.(actionScope).methods>
/* ObjC end actions.(actionScope).methods */
/* ObjC start methods() */
<@methods()>
/* ObjC end methods() */
/* ObjC start rules */
<rules; separator="\n">
/* ObjC end rules */

@end /* end of <grammar.recognizerName> implementation line 692 */<\n>
>>

parserCtorBody() ::= <<
<if(memoize)> /* parserCtorBody */
<if(grammar.grammarIsRoot)>
state.ruleMemo = [[ANTLRRuleStack newANTLRRuleStack:<numRules>+1] retain];<\n> <! index from 1..n !>
<endif>
<endif>
<grammar.delegators:
 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
>>

/** A simpler version of a rule template that is specific to the imaginary
 *  rules created for syntactic predicates.  As they never have return values
 *  nor parameters etc..., just give simplest possible method.  Don't do
 *  any of the normal memoization stuff in here either; it's a waste.
 *  As predicates cannot be inlined into the invoking rule, they need to
 *  be in a rule by themselves.
 */
synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::=
<<
// $ANTLR start <ruleName>_fragment
- (void) <ruleName>_fragment
{
    <ruleLabelDefs()>
    <if(trace)>
        [self traceIn:\@"<ruleName>_fragment" Index:<ruleDescriptor.index>];
    @try {
        <block>
    }
    @finally {
        [self traceOut:\@"<ruleName>_fragment" Index:<ruleDescriptor.index>];
    }
<else>
    <block>
<endif>
} // $ANTLR end <ruleName>_fragment
>>

synpred(name) ::= <<
SEL <name>Selector = @selector(<name>_fragment);
<! // $ANTLR start <name>
- (BOOL) <name>
{
    state.backtracking++;
    <@start()>
    NSInteger start = [input mark];
    @try {
        [self <name>_fragment]; // can never throw exception
    }
    @catch (ANTLRRecognitionException *re) {
        NSLog(@"impossible: %@\n", re.name);
    }
    BOOL success = (state.failed == NO);
    [input rewind:start];
    <@stop()>
    state.backtracking--;
    state.failed=NO;
    return success;
} // $ANTLR end <name> <\n> !>
>>

lexerSynpred(name) ::= <<
<synpred(name)>
>>

ruleMemoization(name) ::= <<
<if(memoize)>
if ( state.backtracking > 0 && [self alreadyParsedRule:input RuleIndex:<ruleDescriptor.index>] ) { return <ruleReturnValue()>; }
<endif>
>>

/** How to test for failure and return from rule */
checkRuleBacktrackFailure() ::= <<
<if (backtracking)>if ( state.failed ) return <ruleReturnValue()>;<endif>
>>

/** This rule has failed, exit indicating failure during backtrack */
ruleBacktrackFailure() ::= <<
<if(backtracking)>if ( state.backtracking > 0 ) { state.failed = YES; return <ruleReturnValue()>; }<\n><endif>
>>

/** How to generate code for a rule.
 *  The return type aggregates are declared in the header file (headerFile template)
 */
rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<

/*
 * $ANTLR start <ruleName>
 * <fileName>:<description>
 */
- (<returnType()>) <ruleName><ruleDescriptor.parameterScope:parameterScope()>
{
    <if(trace)>[self traceIn:\@"<ruleName>" Index:<ruleDescriptor.index>];<endif>
    <if(trace)>NSLog(@"enter <ruleName> %@ failed=%@ backtracking=%d", [input LT:1], (state.failed==YES)?@"YES":@"NO", state.backtracking);<endif>
    <ruleScopeSetUp()>
    <ruleDeclarations()>
    <ruleDescriptor.actions.init>
    <@preamble()>
    @try {
        <ruleMemoization(name=ruleName)>
        <ruleLabelDefs()>
        <block>
        <ruleCleanUp()>
        <(ruleDescriptor.actions.after):execAction()>
    }
<if(exceptions)>
    <exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
<else><if(!emptyRule)><if(actions.(actionScope).rulecatch)>
    <actions.(actionScope).rulecatch>
<else>
    @catch (ANTLRRecognitionException *re) {
        [self reportError:re];
        [self recover:input Exception:re];
        <@setErrorReturnValue()>
    }<\n>
<endif><endif><endif>
    @finally {
        <if(trace)>[self traceOut:@"<ruleName>" Index:<ruleDescriptor.index>];<endif>
        <memoize()>
        <ruleScopeCleanUp()>
        <finally>
    }
    <@postamble()>
    return <ruleReturnValue()>;
}
/* $ANTLR end <ruleName> */
>>

finalCode(finalBlock) ::= <<
{
    <finalBlock>
}
>>

catch(decl,action) ::= <<
@catch (<e.decl>) {
    <e.action>
}
>>

ruleDeclarations() ::= <<
/* ruleDeclarations */
<if(ruleDescriptor.hasMultipleReturnValues)>
<returnType()> retval = [<ruleDescriptor:returnStructName()> new<ruleDescriptor:returnStructName()>];
[retval setStart:[input LT:1]];<\n>
<else>
<ruleDescriptor.returnScope.attributes:{ a |
<a.type> <a.name> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
}>
<endif>
<if(memoize)>
NSInteger <ruleDescriptor.name>_StartIndex = input.index;
<endif>
>>

ruleScopeSetUp() ::= <<
/* ruleScopeSetUp */
<ruleDescriptor.useScopes:{it | [<it>_stack push:[<it>_Scope new<it>_Scope]];}>
<ruleDescriptor.ruleScope:{it | [<it.name>_stack push:[<it.name>_Scope new<it.name>_Scope]];}>
>>

ruleScopeCleanUp() ::= <<
/* ruleScopeCleanUp */
<ruleDescriptor.useScopes:{it | [<it>_stack pop];}; separator="\n">
<ruleDescriptor.ruleScope:{it | [<it.name>_stack pop];}; separator="\n">
>>

ruleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels, ruleDescriptor.tokenListLabels,
  ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels]
    :{it | <labelType> *<it.label.text> = nil;}; separator="\n">
<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels,ruleDescriptor.wildcardTreeListLabels]
    :{it | AMutableArray *list_<it.label.text> = nil;}; separator="\n"
>
<ruleDescriptor.ruleLabels:ruleLabelDef(); separator="\n">
<ruleDescriptor.ruleListLabels:{ll|ANTLRParserRuleReturnScope *<ll.label.text> = nil;}; separator="\n">
>>

lexerRuleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,
  ruleDescriptor.tokenListLabels,
  ruleDescriptor.ruleLabels]
    :{it | <labelType> *<it.label.text>=nil;}; separator="\n"
>
<ruleDescriptor.charLabels:{it | NSInteger <it.label.text>;}; separator="\n">
<[ruleDescriptor.tokenListLabels,
  ruleDescriptor.ruleListLabels]:{it | AMutableArray *list_<it.label.text>=nil; }; separator="\n">
>>

ruleReturnValue() ::= <%
<if(!ruleDescriptor.isSynPred)>
<if(ruleDescriptor.hasReturnValue)>
<if(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnName>
<else>
retval
<endif>
<endif>
<endif>
%>

ruleCleanUp() ::= <<
/* token+rule list labels */
<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]:{it | [list_<it.label.text> release];}; separator="\n">
<if(ruleDescriptor.hasMultipleReturnValues)>
<if(!TREE_PARSER)>
[retval setStop:[input LT:-1]];<\n>
<endif><endif>
>>

memoize() ::= <<
<if(memoize)>
<if(backtracking)>
if (state.backtracking > 0) [self memoize:input RuleIndex:<ruleDescriptor.index> StartIndex:<ruleDescriptor.name>_StartIndex];
<endif><endif>
>>

/** How to generate a rule in the lexer; naked blocks are used for
 *  fragment rules.
 */
lexerRule(ruleName, nakedBlock, ruleDescriptor, block, memoize) ::= <<
// $ANTLR start "<ruleName>"
- (void) m<ruleName><if(ruleDescriptor.parameterScope)><ruleDescriptor.parameterScope:parameterScope(scope=it)><endif>
{
    //<if(trace)>[self traceIn:\@"<ruleName>" Index:<ruleDescriptor.index>];<endif>
    <if(trace)>NSLog(@"enter <ruleName> %C line=%d:%d failed=%@ backtracking=%d",
        [input LA:1],
        self.line,
        self.charPositionInLine,
        (state.failed==YES) ? @"YES" : @"NO",
        state.backtracking);
    <endif>
    <ruleScopeSetUp()>
    <ruleDeclarations()>
    @try {
<if(nakedBlock)>
        <ruleMemoization(name=ruleName)>
        <lexerRuleLabelDefs()>
        <ruleDescriptor.actions.init>
        <block><\n>
<else>
        NSInteger _type = <ruleName>;
        NSInteger _channel = ANTLRTokenChannelDefault;
        <ruleMemoization(name=ruleName)>
        <lexerRuleLabelDefs()>
        <ruleDescriptor.actions.init>
        <block>
        <ruleCleanUp()>
        state.type = _type;
        state.channel = _channel;
        <(ruleDescriptor.actions.after):execAction()>
<endif>
    }
    @finally {
        //<if(trace)>[self traceOut:[NSString stringWithFormat:@"<ruleName> %d\n", <ruleDescriptor.index>]];<endif>
        <if(trace)>NSLog(@"exit <ruleName> %C line=%d:%d failed=%@ backtracking=%d",
                    [input LA:1], self.line, self.charPositionInLine,
                    (state.failed==YES) ? @"YES" : @"NO", state.backtracking);<endif>
        <ruleScopeCleanUp()>
        <memoize()>
    }
    return;
}
/* $ANTLR end "<ruleName>" */
>>

/** How to generate code for the implicitly-defined lexer grammar rule
 *  that chooses between lexer rules.
 */
tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
- (void) mTokens
{
    <block><\n>
}
>>

// S U B R U L E S

/** A (...) subrule with multiple alternatives */
block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description> // block
NSInteger alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
<@prebranch()>
switch (alt<decisionNumber>) {
    <alts:{a | <altSwitchCase(i, a)>}>
}
<@postbranch()>
>>

/** A rule block with multiple alternatives */
ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description> //ruleblock
NSInteger alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
switch (alt<decisionNumber>) {
    <alts:{a | <altSwitchCase(i, a)>}>
}
>>

ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// <fileName>:<description> // ruleBlockSingleAlt
<decls>
<@prealt()>
<alts>
<@postalt()>
>>

/** A special case of a (...) subrule with a single alternative */
blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// <fileName>:<description> // blockSingleAlt
<decls>
<@prealt()>
<alts>
<@postalt()>
>>

/** A (..)+ block with 1 or more alternatives */
positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description> // positiveClosureBlock
NSInteger cnt<decisionNumber> = 0;
<decls>
<@preloop()>
do {
    NSInteger alt<decisionNumber> = <maxAlt>;
    <@predecision()>
    <decision>
    <@postdecision()>
    switch (alt<decisionNumber>) {
        <alts:{a | <altSwitchCase(i, a)>}>
        default :
            if ( cnt<decisionNumber> >= 1 )
                goto loop<decisionNumber>;
            <ruleBacktrackFailure()>
            ANTLREarlyExitException *eee =
                [ANTLREarlyExitException newException:input decisionNumber:<decisionNumber>];
            <@earlyExitException()>
            @throw eee;
    }
    cnt<decisionNumber>++;
} while (YES);
loop<decisionNumber>: ;
<@postloop()>
>>

positiveClosureBlockSingleAlt ::= positiveClosureBlock

/** A (..)* block with 0 or more alternatives */
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
<decls>
<@preloop()>
do {
    NSInteger alt<decisionNumber>=<maxAlt>;
    <@predecision()>
    <decision>
    <@postdecision()>
    switch (alt<decisionNumber>) {
        <alts:{a | <altSwitchCase(i, a)>}>
        default :
            goto loop<decisionNumber>;
    }
} while (YES);
loop<decisionNumber>: ;
<@postloop()>
>>

closureBlockSingleAlt ::= closureBlock

/** Optional blocks (x)? are translated to (x|) by before code generation
 *  so we can just use the normal block template
 */
optionalBlock ::= block

optionalBlockSingleAlt ::= block

/** A case in a switch that jumps to an alternative given the alternative
 *  number.  A DFA predicts the alternative and then a simple switch
 *  does the jump to the code that actually matches that alternative.
 */
altSwitchCase(altNum, alt) ::= <<
case <altNum> : ;
    <@prealt()>
    <alt>
    break;<\n>
>>

/** An alternative is just a list of elements; at outermost level */
alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
// <fileName>:<description> // alt
{
<@declarations()>
<elements:element()>
<rew>
<@cleanup()>
}
>>

/** What to emit when there is no rewrite.  For auto build
 *  mode, does nothing.
 */
noRewrite(rewriteBlockLevel, treeLevel) ::= ""

// E L E M E N T S

/** Dump the elements one per line */
element(e) ::= << <@prematch()><\n><e.el><\n> >>

/** match a token optionally with a label in front */
tokenRef(token,label,elementIndex,terminalOptions) ::= <<
<if(label)><label>=(<labelType> *)<endif>[self match:input TokenType:<token> Follow:FOLLOW_<token>_in_<ruleName><elementIndex>]; <checkRuleBacktrackFailure()>
>>

/** ids+=ID */
tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
<tokenRef(...)>
<listLabel(elem=label,...)>
>>

listLabel(label,elem) ::= <<
if (list_<label> == nil) list_<label> = [[AMutableArray arrayWithCapacity:5] retain];
[list_<label> addObject:<elem>];<\n>
>>

/** match a character */
charRef(char,label) ::= <<
<if(label)>NSInteger <label> = [input LA:1];<\n><endif>
[self matchChar:<char>]; <checkRuleBacktrackFailure()><\n>
>>

/** match a character range */
charRangeRef(a,b,label) ::= <<
<if(label)><label> = [input LA:1];<\n><endif>
[self matchRangeFromChar:<a> to:<b>]; <checkRuleBacktrackFailure()>
>>

/** For now, sets are interval tests and must be tested inline */
matchSet(s,label,elementIndex,terminalOptions,postmatchCode="") ::= <<
<if(label)>
<if(LEXER)>
<label> = [input LA:1];<\n>
<else>
<label> = (<labelType> *)[input LT:1]; /* matchSet */<\n>
<endif><endif>
if (<s>) {
    [input consume];
    <postmatchCode>
<if(!LEXER)>
    [state setIsErrorRecovery:NO];
<endif>
    <if(backtracking)>state.failed = NO;<\n><endif>
} else {
    <ruleBacktrackFailure()>
    ANTLRMismatchedSetException *mse = [ANTLRMismatchedSetException newException:nil stream:input];
    <@mismatchedSetException()>
<if(LEXER)>
<if(label)>
    mse.c = <label>;
<endif>
    [self recover:mse];
    @throw mse;
<else>
    @throw mse;
    <! use following code to make it recover inline; remove throw mse;
    [self recoverFromMismatchedSet:input exception:mse follow:FOLLOW_set_in_<ruleName><elementIndex>]; !>
<endif>
}<\n>
>>

matchRuleBlockSet ::= matchSet

matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
<matchSet(...)>
<listLabel(elem=label,...)>
>>

/** Match a string literal */
lexerStringRef(string,label,elementIndex="0") ::= <<
<if(label)>
NSInteger <label>Start = input.index;
[self matchString:<string>]; <checkRuleBacktrackFailure()>
NSInteger StartLine<elementIndex> = self.line;
NSInteger <label>StartCharPos<elementIndex> = self.charPositionInLine;
<label> = [[<labelType> newToken:input Type:ANTLRTokenTypeInvalid Channel:ANTLRTokenChannelDefault Start:<label>Start Stop:input.index] retain];
[self setLine:<label>StartLine<elementIndex>];
[self setCharPositionInLine:<label>StartCharPos<elementIndex>];
<else>
[self matchString:<string>]; <checkRuleBacktrackFailure()><\n>
<endif>
>>

wildcard(token,label,elementIndex,terminalOptions) ::= <<
<if(label)>
<label> = (<labelType> *)[input LT:1];<\n>
<endif>
[self matchAny:input]; <checkRuleBacktrackFailure()>
>>

wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
<wildcard(...)>
<listLabel(elem=label,...)>
>>

/** Match . wildcard in lexer */
wildcardChar(label, elementIndex) ::= <<
<if(label)>
NSInteger <label> = [input LA:1];<\n>
<endif>
[self matchAny]; <checkRuleBacktrackFailure()><\n>
>>

wildcardCharListLabel(label, elementIndex) ::= <<
<wildcardChar(...)>
<listLabel(elem=label,...)>
>>

/** Match a rule reference by invoking it possibly with arguments
 *  and a return value or values.  The 'rule' argument was the
 *  target rule name, but now is type Rule, whose toString is
 *  same: the rule name.  Now though you can access full rule
 *  descriptor stuff.
 */
ruleRef(rule,label,elementIndex,args,scope) ::= <<
/* ruleRef */
[self pushFollow:FOLLOW_<rule.name>_in_<ruleName><elementIndex>];
<if(label)><label> = <endif>[self <if(scope)><scope:delegateName()>.<endif><rule.name><if(args)>:<first(args)> <rest(args):{ a | arg<i>:<rest(args)>}; separator=" "><endif>];<\n>
[self popFollow];
<checkRuleBacktrackFailure()><\n>
>>

/** ids+=r */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRef(...)>
<listLabel(elem=label,...)>
>>

/** A lexer rule reference.
 *
 *  The 'rule' argument was the target rule name, but now
 *  is type Rule, whose toString is same: the rule name.
 *  Now though you can access full rule descriptor stuff.
 */
lexerRuleRef(rule,label,args,elementIndex,scope) ::= <<
<if(label)>
NSInteger <label>Start<elementIndex> = input.index;
[self m<rule.name><if(args)>:<args; separator=" :"><endif>]; <checkRuleBacktrackFailure()><\n>
<label> = [[<labelType> newToken:input Type:ANTLRTokenTypeInvalid Channel:ANTLRTokenChannelDefault Start:<label>Start<elementIndex> Stop:input.index-1] retain];
<label>.line = self.line;
<else>
[self <if(scope)><scope:delegateName()>.<endif>m<rule.name><if(args)>:<args; separator=" :"><endif>]; <checkRuleBacktrackFailure()><\n>
<endif>
>>

/** i+=INT in lexer */
lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
<lexerRuleRef(...)>
<listLabel(elem=label,...)>
>>

/** EOF in the lexer */
lexerMatchEOF(label,elementIndex) ::= <<
<if(label)>
NSInteger <label>Start<elementIndex> = input.index;
[self matchChar:ANTLRCharStreamEOF]; <checkRuleBacktrackFailure()><\n>
<labelType> <label> = [[<labelType> newToken:input Type:ANTLRTokenTypeEOF Channel:ANTLRTokenChannelDefault Start:<label>Start<elementIndex> Stop:input.index-1] retain];
<label>.line = self.line;
<else>
[self matchChar:ANTLRCharStreamEOF]; <checkRuleBacktrackFailure()><\n>
<endif>
>>

// used for left-recursive rules
recRuleDefArg()                       ::= "int <recRuleArg()>"
recRuleArg()                          ::= "_p"
recRuleAltPredicate(ruleName,opPrec)  ::= "<recRuleArg()> \<= <opPrec>"
recRuleSetResultAction()              ::= "root_0=$<ruleName>_primary.tree;"
recRuleSetReturnAction(src,name)      ::= "$<name>=$<src>.<name>;"

/** match ^(root children) in tree parser */
tree(root, actionsAfterRoot, children, nullableChildList, enclosingTreeLevel, treeLevel) ::= <<
<root:element()>
<actionsAfterRoot:element()>
<if(nullableChildList)>
if ( [input LA:1] == DOWN ) {
    [self match:input TokenType:DOWN Follow:nil]; <checkRuleBacktrackFailure()>
    <children:element()>
    [self match:input TokenType:UP Follow:nil]; <checkRuleBacktrackFailure()>
}
<else>
    [self match:input TokenType:DOWN Follow:nil]; <checkRuleBacktrackFailure()>
    <children:element()>
    [self match:input TokenType:UP Follow:nil]; <checkRuleBacktrackFailure()>
<endif>
>>

/** Every predicate is used as a validating predicate (even when it is
 *  also hoisted into a prediction expression).
 */
validateSemanticPredicate(pred,description) ::= <<
if ( !(<evalPredicate(...)>) ) {
    <ruleBacktrackFailure()>
    @throw [ANTLRFailedPredicateException newException:@"<ruleName>" predicate:@"<description>" stream:input];
}
>>

// F i x e d  D F A  (if-then-else)

dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:<k>];<\n>
<edges; separator="\nelse ">
else {
<if(eotPredictsAlt)>
    alt<decisionNumber> = <eotPredictsAlt>;
<else>
    <ruleBacktrackFailure()>
    ANTLRNoViableAltException *nvae = [ANTLRNoViableAltException newException:<decisionNumber> state:<stateNumber> stream:input];
    nvae.c = LA<decisionNumber>_<stateNumber>;
    <@noViableAltException()>
    @throw nvae;<\n>
<endif>
}
>>

/** Same as a normal DFA state except that we don't examine lookahead
 *  for the bypass alternative.  It delays error detection but this
 *  is faster, smaller, and more what people expect.  For (X)? people
 *  expect "if ( LA(1)==X ) match(X);" and that's it.
 */
dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:<k>];<\n>
<edges; separator="\nelse ">
>>

/** A DFA state that is actually the loopback decision of a closure
 *  loop.  If end-of-token (EOT) predicts any of the targets then it
 *  should act like a default clause (i.e., no error can be generated).
 *  This is used only in the lexer so that for ('a')* on the end of a rule
 *  anything other than 'a' predicts exiting.
 */
dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:<k>];
<edges; separator="\nelse "><\n>
<if(eotPredictsAlt)>
<if(!edges)>
alt<decisionNumber>=<eotPredictsAlt>; <! if no edges, don't gen ELSE !>
<else>
else {
    alt<decisionNumber> = <eotPredictsAlt>;
}<\n>
<endif><endif>
>>

/** An accept state indicates a unique alternative has been predicted */
dfaAcceptState(alt) ::= "alt<decisionNumber>=<alt>;"

/** A simple edge with an expression.  If the expression is satisfied,
 *  enter to the target state.  To handle gated productions, we may
 *  have to evaluate some predicates for this edge.
 */
dfaEdge(labelExpr, targetState, predicates) ::= <<
if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>) {
    <targetState>
}
>>

// F i x e d  D F A  (switch case)

/** A DFA state where a SWITCH may be generated.  The code generator
 *  decides if this is possible: CodeGenerator.canGenerateSwitch().
 */
dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
unichar charLA<decisionNumber> = [input LA:<k>];
switch (charLA<decisionNumber>) {
    <edges; separator="\n"><\n>
default: ;
<if(eotPredictsAlt)>
    alt<decisionNumber> = <eotPredictsAlt>;
<else>
    <ruleBacktrackFailure()>
    ANTLRNoViableAltException *nvae = [ANTLRNoViableAltException newException:<decisionNumber> state:<stateNumber> stream:input];
    nvae.c = charLA<decisionNumber>;
    <@noViableAltException()>
    @throw nvae;<\n>
<endif>
}<\n>
>>

dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch ([input LA:<k>]) { // dfaOptionalBlockStateSwitch
    <edges; separator="\n"><\n>
}<\n>
>>

dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch ([input LA:<k>]) { // dfaLoopbackStateSwitch
    <edges; separator="\n"><\n>
<if(eotPredictsAlt)>
default:
    alt<decisionNumber> = <eotPredictsAlt>;
    break;<\n>
<endif>
}<\n>
>>

dfaEdgeSwitch(labels, targetState) ::= <<
<labels:{it | case <it>: ;}; separator="\n">
    {
    <targetState>
    }
    break;
>>

// C y c l i c  D F A

/** The code to initiate execution of a cyclic DFA; this is used
 *  in the rule to predict an alt just like the fixed DFA case.
 *  The <name> attribute is inherited via the parser, lexer, ...
 */
dfaDecision(decisionNumber,description) ::= <<
alt<decisionNumber> = [dfa<decisionNumber> predict:input];
>>

/** Used in headerFile */
cyclicDFAInterface(dfa) ::= <<
#pragma mark Cyclic DFA interface start DFA<dfa.decisionNumber>
@interface DFA<dfa.decisionNumber> : ANTLRDFA {
}
+ newDFA<dfa.decisionNumber>WithRecognizer:(ANTLRBaseRecognizer *)theRecognizer;
- initWithRecognizer:(ANTLRBaseRecognizer *)recognizer;
@end /* end of DFA<dfa.decisionNumber> interface  */<\n>
#pragma mark Cyclic DFA interface end DFA<dfa.decisionNumber><\n>
>>

/** Used in lexer/parser implementation files */
/* Dump DFA tables as run-length-encoded Strings of octal values.
 * Can't use hex as compiler translates them before compilation.
 * These strings are split into multiple, concatenated strings.
 * Java puts them back together at compile time thankfully.
 * Java cannot handle large static arrays, so we're stuck with this
 * encode/decode approach.  See analysis and runtime DFA for
 * the encoding methods.
 */
cyclicDFA(dfa) ::= <<
#pragma mark Cyclic DFA implementation start DFA<dfa.decisionNumber>
@implementation DFA<dfa.decisionNumber>
const static NSInteger dfa<dfa.decisionNumber>_eot[<dfa.numberOfStates>] =
    {<dfa.eot; wrap="\n     ", separator=",", null="-1">};
const static NSInteger dfa<dfa.decisionNumber>_eof[<dfa.numberOfStates>] =
    {<dfa.eof; wrap="\n     ", separator=",", null="-1">};
const static unichar dfa<dfa.decisionNumber>_min[<dfa.numberOfStates>] =
    {<dfa.min; wrap="\n     ", separator=",", null="0">};
const static unichar dfa<dfa.decisionNumber>_max[<dfa.numberOfStates>] =
    {<dfa.max; wrap="\n     ", separator=",", null="0">};
const static NSInteger dfa<dfa.decisionNumber>_accept[<dfa.numberOfStates>] =
    {<dfa.accept; wrap="\n     ", separator=",", null="-1">};
const static NSInteger dfa<dfa.decisionNumber>_special[<dfa.numberOfStates>] =
    {<dfa.special; wrap="\n     ", separator=",", null="-1">};
const static NSInteger dfa<dfa.decisionNumber>_transition[] = {};
<dfa.edgeTransitionClassMap.keys:{ table |
const static NSInteger dfa<dfa.decisionNumber>_transition<i0>[] = {<table; separator=", ", wrap="\n ", null="-1">\};
}; null="">

+ (id) newDFA<dfa.decisionNumber>WithRecognizer:(ANTLRBaseRecognizer *)aRecognizer
{
    return [[[DFA<dfa.decisionNumber> alloc] initWithRecognizer:aRecognizer] retain];
}

- (id) initWithRecognizer:(ANTLRBaseRecognizer *) theRecognizer
{
    self = [super initWithRecognizer:theRecognizer];
    if ( self != nil ) {
        decisionNumber = <dfa.decisionNumber>;
        eot = dfa<dfa.decisionNumber>_eot;
        eof = dfa<dfa.decisionNumber>_eof;
        min = dfa<dfa.decisionNumber>_min;
        max = dfa<dfa.decisionNumber>_max;
        accept = dfa<dfa.decisionNumber>_accept;
        special = dfa<dfa.decisionNumber>_special;
        if (!(transition = calloc(<dfa.numberOfStates>, sizeof(void*)))) {
            [self release];
            return nil;
        }
        len = <dfa.numberOfStates>;
        <dfa.transitionEdgeTables:{whichTable|transition[<i0>] = dfa<dfa.decisionNumber>_transition<whichTable>;}; separator="\n", null="">
    }
    return self;
}

<if(dfa.specialStateSTs)>
/* start dfa.specialStateSTs */
- (NSInteger) specialStateTransition:(NSInteger)s Stream:(id\<ANTLRIntStream\>)anInput
{
<if(LEXER)>
    id\<ANTLRIntStream\> input = anInput;<\n>
<endif>
<if(PARSER)>
    id\<ANTLRTokenStream\> input = (id\<ANTLRTokenStream\>)anInput;<\n>
<endif>
<if(TREE_PARSER)>
    id\<ANTLRTreeNodeStream\> input = (id\<ANTLRTreeNodeStream\>)anInput;<\n>
<endif>
    switch (s) {
        <dfa.specialStateSTs:{state |
        case <i0> : ;<! compressed special state numbers 0..n-1 !>
            <state>}; separator="\n">
    }
<if(backtracking)>
    if ( [recognizer getBacktrackingLevel] > 0 ) { [recognizer setFailed:YES]; return -1; }<\n>
<endif>
    ANTLRNoViableAltException *nvae = [ANTLRNoViableAltException newException:<dfa.decisionNumber> state:s stream:recognizer.input];
    // nvae.c = s;
    /* [self error:nvae]; */ <! for debugger - do later !>
    @throw nvae;
}<\n>
/* end dfa.specialStateSTs */
<endif>

- (void) dealloc
{
    free(transition);
    [super dealloc];
}

- (NSString *) description
{
    return @"<dfa.description>";
}

<@errorMethod()>

@end /* end DFA<dfa.decisionNumber> implementation */<\n>
#pragma mark Cyclic DFA implementation end DFA<dfa.decisionNumber>
<\n>
>>
/** A state in a cyclic DFA; it's a special state and part of a big switch on
 *  state.
 */
cyclicDFAState(decisionNumber, stateNumber, edges, needErrorClause, semPredState) ::= <<
/* cyclicDFAState */
NSInteger LA<decisionNumber>_<stateNumber> = [input LA:1];<\n>
<if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>
NSInteger index<decisionNumber>_<stateNumber> = input.index;
[input rewind];<\n>
<endif>
s = -1;
<edges; separator="\nelse ">
<if(semPredState)> <! return input cursor to state before we rewound !>
[input seek:index<decisionNumber>_<stateNumber>];<\n>
<endif>
if ( s >= 0 )
    return s;
 break;
>>

/** Just like a fixed DFA edge, test the lookahead and indicate what
 *  state to jump to next if successful.
 */
cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
/* cyclicDFAEdge */
if (<labelExpr><if(predicates)> && (<predicates>)<endif>) { s = <targetStateNumber>;}<\n>
>>

/** An edge pointing at end-of-token; essentially matches any char;
 *  always jump to the target.
 */
eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= <<
s = <targetStateNumber>;<\n> /* eotDFAEdge */
>>

// D F A  E X P R E S S I O N S

andPredicates(left,right) ::= "(<left>&&<right>)"

orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)"

notPredicate(pred) ::= "!(<evalPredicate(pred, \"\")>)"

evalPredicate(pred,description) ::= "(<pred>)"

/*
 * evalSynPredicate(pred,description) ::= "<pred>()"
 *
 * synpreds are broken in cyclic DFA special states
 *  Damn! For now, work around with using the selectors directly, and by providing a trampoline evalSynPred method in
 *  ANTLRDFA
 */
/* evalSynPredicate(pred,description) ::= "[self evaluateSyntacticPredicate:<pred>Selector stream:input]" */
evalSynPredicate(pred,description) ::= "[self evaluateSyntacticPredicate:@selector(<pred>_fragment)]"
/* evalSynPredicate(pred,description) ::= "[recognizer <pred>]" */

lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>"

/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
 *  somewhere.  Must ask for the lookahead directly.
 */
isolatedLookaheadTest(atom,k,atomAsInt) ::= "[input LA:<k>] == <atom>"

lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <%
(LA<decisionNumber>_<stateNumber> >= <lower> && LA<decisionNumber>_<stateNumber> \<= <upper>)
%>

isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(([input LA:<k>] >= <lower>) && ([input LA:<k>] \<= <upper>))"

setTest(ranges) ::= "<ranges; separator=\"||\">"

// A T T R I B U T E S

memVars(scope) ::= << <scope.attributes:{a|<a.type> <a.name>;<\n>}; separator="\n"> >>

properties(scope) ::= <<
<scope.attributes:{a|@property (assign, getter=get<a.name>, setter=set<a.name>:) <a.type> <a.name>;<\n>}; separator="\n">
>>

methodsDecl(scope) ::= <<
<scope.attributes:{a|- (<a.type>)get<a.name>;<\n>- (void)set<a.name>:(<a.type>)aVal;<\n>}; separator="\n">
>>

synthesize(scope) ::= << <scope.attributes:{a|@synthesize <a.name>;}; separator="\n"> >>

methods(scope) ::= <%
<scope.attributes:{a|
- (<a.type>)get<a.name> { return( <a.name> ); \}<\n>
- (void)set<a.name>:(<a.type>)aVal { <a.name> = aVal; \}<\n>}; separator="\n">
%>

globalAttributeScopeInterface(scope) ::= <%
/* globalAttributeScopeInterface */<\n>
@interface <scope.name>_Scope : ANTLRSymbolsScope {<\n>
<if(scope.attributes)>
<memVars(scope)>
<endif>
}<\n>
<if(scope.attributes)>
/* start of globalAttributeScopeInterface properties */<\n>
<properties(scope)>
/* end globalAttributeScopeInterface properties */<\n>
<endif>

+ (<scope.name>_Scope *)new<scope.name>_Scope;<\n>
- (id) init;<\n>
<if(scope.attributes)>
/* start of globalAttributeScopeInterface methodsDecl */<\n>
<methodsDecl(scope)>
/* End of globalAttributeScopeInterface methodsDecl */<\n>
<endif>
@end /* end of <scope.name>_Scope interface */<\n>
%>

globalAttributeScopeMemVar(scope) ::= <%
/* globalAttributeScopeMemVar */<\n>
ANTLRSymbolStack *<scope.name>_stack;<\n>
<scope.name>_Scope *<scope.name>_scope;<\n>
%>

globalAttributeScopeImplementation(scope) ::= <%
@implementation <scope.name>_Scope  /* globalAttributeScopeImplementation */<\n>
<if(scope.attributes)>
/* start of synthesize -- OBJC-Line 1750 */<\n>
<synthesize(scope)><\n>
<endif>
<\n>
+ (<scope.name>_Scope *)new<scope.name>_Scope<\n>
{<\n>
    return [[<scope.name>_Scope alloc] init];<\n>
}<\n>
<\n>
- (id) init<\n>
{<\n>
    self = [super init];<\n>
    return self;<\n>
}<\n>
<\n>
<if(scope.attributes)>
/* start of iterate get and set functions */<\n>
<methods(scope)><\n>
/* End of iterate get and set functions */<\n>
<endif>
@end /* end of <scope.name>_Scope implementation */<\n><\n>
%>

globalAttributeScopeInit(scope) ::= <<
/* globalAttributeScopeInit */<\n>
<scope.name>_scope = [<scope.name>_Scope new<scope.name>_Scope];<\n>
<scope.name>_stack = [ANTLRSymbolStack newANTLRSymbolStackWithLen:30];<\n>
>>

globalAttributeScopeDealloc(scope) ::= << [<scope.name>_stack release];<\n> >>

globalAttributeScope(scope) ::= << static <scope.name>_stack;<\n> >>

ruleAttributeScopeMemVar(scope) ::= <%
/* ObjC ruleAttributeScopeMemVar */<\n>
<if(scope.attributes)>
<scope.name>_Scope *<scope.name>_scope; /* ObjC ruleAttributeScopeMemVar */<\n>
<endif>
%>

ruleAttributeScopeInterface(scope) ::= <%
<if(scope.attributes)>
/* start of ruleAttributeScopeInterface */<\n>
@interface <scope.name>_Scope : ANTLRSymbolsScope {<\n>
    <memVars(scope)><\n>
}<\n>
<\n>
/* start property declarations */<\n>
<properties(scope)><\n>
/* start method declarations */<\n>
+ (<scope.name>_Scope *)new<scope.name>_Scope;<\n>
- (id) init;<\n>
<methodsDecl(scope)><\n>
@end /* end of ruleAttributeScopeInterface */<\n><\n>
<endif>
%>

ruleAttributeScopeImplementation(scope) ::= <%
<if(scope.attributes)>
@implementation <scope.name>_Scope  /* start of ruleAttributeScopeImplementation */<\n>
<synthesize(scope)><\n>
<\n>
+ (<scope.name>_Scope *)new<scope.name>_Scope<\n>
{<\n>
    return [[<scope.name>_Scope alloc] init];<\n>
}<\n>
<\n>
- (id) init<\n>
{<\n>
    self = [super init];<\n>
    return self;<\n>
}<\n>
<\n>
/* start of <scope.name>_Scope get and set functions */<\n>
<methods(scope)><\n>
/* End of <scope.name>_Scope get and set functions */<\n>
@end /* end of ruleAttributeScopeImplementation */<\n><\n>
<endif>
%>

ruleAttributeScopeInit(scope) ::= <%
/* ruleAttributeScopeInit */<\n>
<scope.name>_scope = [<scope.name>_Scope new<scope.name>_Scope];<\n>
<scope.name>_stack = [ANTLRSymbolStack newANTLRSymbolStackWithLen:30];<\n>
%>

ruleAttributeScopeDealloc(scope) ::= <% [<scope.name>_Scope release];<\n> %>

ruleAttributeScope(scope) ::= <%
<if(scope.attributes)>
/* ruleAttributeScope */<\n>
static ANTLRSymbolStack *<scope.name>_stack;<\n>
<endif>
%>

ruleAttributeScopeDecl(scope) ::= <%
/* ruleAttributeScopeDecl */<\n>
<if(scope.attributes)>
<scope.name>_Scope *<scope.name>_scope;<\n>
<endif>
%>

returnStructName(r) ::= "<className()>_<r.name>_return"

returnType() ::= <%
<if(!ruleDescriptor.isSynPred)>
<if(ruleDescriptor.hasMultipleReturnValues)>
<ruleDescriptor:returnStructName()> *
<else>
<if(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnType>
<else>
void
<endif>
<endif>
<else>
void
<endif>
%>

/** Generate the Objective-C type associated with a single or multiple return
 *  values.
 */
ruleLabelType(referencedRule) ::= <%
<if(referencedRule.hasMultipleReturnValues)>
<className()>_<referencedRule.name>_return *<else>
<if(referencedRule.hasSingleReturnValue)><referencedRule.singleValueReturnType><else>
void<endif>
<endif>
%>

delegateName(d) ::= << <if(d.label)><d.label><else>g<d.name><endif> >>

/** Using a type to init value map, try to init a type; if not in table
 *  must be an object, default value is "null".
 */
initValue(typeName) ::= <% <objcTypeInitMap.(typeName)> %>

/** Define a rule label including default value */
ruleLabelDef(label) ::= << <ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n> >>

/** Define a return struct for a rule if the code needs to access its
 *  start/stop tokens, tree stuff, attributes, ...  Leave a hole for
 *  subgroups to stick in members.
 */
returnScopeInterface(scope) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
/* returnScopeInterface <ruleDescriptor:returnStructName()> */
@interface <ruleDescriptor:returnStructName()> : ANTLR<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope { /* returnScopeInterface line 1838 */
<@memVars()> /* ObjC start of memVars() */<\n>
<if(scope.attributes)>
<memVars(scope)><\n>
<endif>
}
/* start property declarations */
<@properties()><\n>
<if(scope.attributes)>
<properties(scope)><\n>
<endif>
/* start of method declarations */<\n>
+ (<ruleDescriptor:returnStructName()> *)new<ruleDescriptor:returnStructName()>;
/* this is start of set and get methods */
<@methodsDecl()>  /* methodsDecl */<\n>
<if(scope.attributes)>
/* start of iterated get and set functions */<\n>
<methodsDecl(scope)><\n>
<endif>
@end /* end of returnScopeInterface interface */<\n>
<endif>
>>

returnScopeImplementation(scope) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
@implementation <ruleDescriptor:returnStructName()> /* returnScopeImplementation */<\n>
<@synthesize()> /* start of synthesize -- OBJC-Line 1837 */<\n>
<if(scope.attributes)>
    <synthesize(scope)><\n>
<endif>
+ (<ruleDescriptor:returnStructName()> *)new<ruleDescriptor:returnStructName()><\n>
{<\n>
    return [[[<ruleDescriptor:returnStructName()> alloc] init] retain];<\n>
}<\n>
<\n>
- (id) init<\n>
{<\n>
    self = [super init];<\n>
    return self;<\n>
}<\n>
<\n>
<@methods()><\n>
<if(scope.attributes)>
/* start of iterate get and set functions */<\n>
<methods(scope)><\n>
/* End of iterate get and set functions */<\n>
<endif>
<actions.(actionScope).ruleReturnMethods>
<@ruleReturnMembers()><\n>
@end /* end of returnScope implementation */<\n><\n>
<endif>
%>

parameterScope(scope) ::= <<
<! <scope.attributes:{it | :(<it.type>)<it.name>}; separator=" "> !>
<first(scope.attributes):{ a | :(<a.type>)<a.name>}> <rest(scope.attributes):{ a | arg<i>:(<a.type>)<a.name> }; separator=" ">
>>

parameterAttributeRef(attr) ::= "<attr.name>"
parameterSetAttributeRef(attr,expr) ::= "<attr.name> = <expr>;"

/** Note that the scopeAttributeRef does not have access to the
 * grammar name directly
 */
scopeAttributeRef(scope,attr,index,negIndex) ::= <%
<if(negIndex)>
([((<scope>_Scope *)[<scope>_stack objectAtIndex:[<scope>_stack size]-<negIndex>-1)]).<attr.name>
<else>
<if(index)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:<index>]).<attr.name>
<else>
((<scope>_Scope *)[<scope>_stack peek]).<attr.name>
<endif>
<endif>
%>

scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <%
/* scopeSetAttributeRef */
<if(negIndex)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:([<scope>_stack size]-<negIndex>-1)]).<attr.name> = <expr>;
<else>
<if(index)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:<index>]).<attr.name> = <expr>;
<else>
((<scope>_Scope *)[<scope>_stack peek]).<attr.name> = <expr>;
<endif>
<endif>
%>

scopeAttributeRefStack() ::= <<
/* scopeAttributeRefStack */
<if(negIndex)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:[<scope>_stack count]-<negIndex>-1]).<attr.name> = <expr>;
<else>
<if(index)>
((<scope>_Scope *)[<scope>_stack objectAtIndex:<index>]).<attr.name> = <expr>;
<else>
((<scope>_Scope *)[<scope>_stack peek]).<attr.name> = <expr>;
<endif>
<endif>
>>

/** $x is either global scope or x is rule with dynamic scope; refers
 *  to stack itself not top of stack.  This is useful for predicates
 *  like {$function.size()>0 && $function::name.equals("foo")}?
 */
isolatedDynamicScopeRef(scope) ::= "<scope>_stack"

/** reference an attribute of rule; might only have single return value */
ruleLabelRef(referencedRule,scope,attr) ::= <<
<if(referencedRule.hasMultipleReturnValues)>
(<scope>!=nil?<scope>.<attr.name>:<initValue(attr.type)>)
<else>
<scope>
<endif>
>>

returnAttributeRef(ruleDescriptor,attr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name>  /* added to returnAttributeRef */<\n>
<else>
<attr.name><\n>
<endif>
%>

returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
 retval.<attr.name> =<expr>; /* added to returnSetAttributeRef */<\n>
<else>
<attr.name> = <expr>;<\n>
<endif>
%>

/** How to translate $tokenLabel */
tokenLabelRef(label) ::= "<label>"

/** ids+=ID {$ids} or e+=expr {$e} */
listLabelRef(label) ::= "list_<label>"


/* not sure the next are the right approach; and they are evaluated early; */
/* they cannot see TREE_PARSER or PARSER attributes for example. :( */

tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=nil?<scope>.text:nil)"
tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=nil?<scope>.type:0)"
tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=nil?<scope>.line:0)"
tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=nil?<scope>.charPositionInLine:0)"
tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=nil?<scope>.channel:0)"
tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=nil?[<scope> getTokenIndex]:0)"
tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=nil?[<scope>.text integerValue]:0)"

ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=nil?((<labelType> *)<scope>.start):nil)"
ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=nil?((<labelType> *)<scope>.stopToken):nil)"
ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=nil?((<ASTLabelType> *)<scope>.tree):nil)"
ruleLabelPropertyRef_text(scope,attr) ::= <%
<if(TREE_PARSER)>
(<scope>!=nil?[[input getTokenStream] toStringFromStart:[[input getTreeAdaptor] getTokenStartIndex:[<scope> getStart]]
         ToEnd:[[input getTreeAdaptor] getTokenStopIndex:[<scope> getStart]]]:0)
<else>
(<scope>!=nil?([input toStringFromStart:[<scope> getStart] ToEnd:[<scope> getStop]]:0)
<endif>
%>
ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=nil?[<scope> st]:nil)"

/** Isolated $RULE ref ok in lexer as it's a Token */
lexerRuleLabel(label) ::= "<label>"

lexerRuleLabelPropertyRef_type(scope,attr) ::= "(<scope>!=nil?<scope>.type:0)"
lexerRuleLabelPropertyRef_line(scope,attr) ::= "(<scope>!=nil?<scope>.line:0)"
lexerRuleLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=nil?<scope>.charPositionInLine:-1)"
lexerRuleLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=nil?<scope>.channel:0)"
lexerRuleLabelPropertyRef_index(scope,attr) ::= "(<scope>!=nil?[<scope> getTokenIndex]:0)"
lexerRuleLabelPropertyRef_text(scope,attr) ::= "(<scope>!=nil?<scope>.text:nil)"
lexerRuleLabelPropertyRef_int(scope,attr) ::="(<scope>!=nil?[<scope>.text integerValue]:0)"

// Somebody may ref $template or $tree or $stop within a rule:
rulePropertyRef_start(scope,attr) ::= "((<labelType> *)retval.start)"
rulePropertyRef_stop(scope,attr) ::= "((<labelType> *)retval.stopToken)"
rulePropertyRef_tree(scope,attr) ::= "((<ASTLabelType> *)retval.tree)"
rulePropertyRef_text(scope,attr) ::= <<
<if(TREE_PARSER)>
[[input getTokenStream] toStringFromStart:[[input getTreeAdaptor] getTokenStartIndex:retval.start.token.startIndex]
                                    ToEnd:[[input getTreeAdaptor] getTokenStopIndex:retval.start.token.stopIndex]]
<else>
[input toStringFromToken:retval.start ToToken:[input LT:-1]]
<endif>
>>
rulePropertyRef_st(scope,attr) ::= "retval.st"

/* hideous: find a way to cut down on the number of templates to support read/write access */
/* TODO: also, which ones are valid to write to? ask Ter */
lexerRuleSetPropertyRef_text(scope,attr,expr) ::= "state.text = <expr>;"
lexerRuleSetPropertyRef_type(scope,attr,expr) ::= "_type"
lexerRuleSetPropertyRef_line(scope,attr,expr) ::= "state.tokenStartLine"
lexerRuleSetPropertyRef_pos(scope,attr,expr) ::= "state.tokenStartCharPositionInLine"
lexerRuleSetPropertyRef_index(scope,attr,expr) ::= "-1" /* undefined token index in lexer */
lexerRuleSetPropertyRef_channel(scope,attr,expr) ::= "state.channel=<expr>;"
lexerRuleSetPropertyRef_start(scope,attr,expr) ::= "state.tokenStartCharIndex"
lexerRuleSetPropertyRef_stop(scope,attr,expr) ::= "(input.index-1)"


lexerRulePropertyRef_text(scope,attr) ::= "self.text"
lexerRulePropertyRef_type(scope,attr) ::= "state.type"
lexerRulePropertyRef_line(scope,attr) ::= "state.tokenStartLine"
lexerRulePropertyRef_pos(scope,attr) ::= "state.tokenStartCharPositionInLine"
lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
lexerRulePropertyRef_channel(scope,attr) ::= "_channel"
lexerRulePropertyRef_start(scope,attr) ::= "state.tokenStartCharIndex"
lexerRulePropertyRef_stop(scope,attr) ::= "(input.index-1)"
lexerRulePropertyRef_int(scope,attr) ::= "[<scope>.text integerValue]"

// setting $st and $tree is allowed in local rule. everything else
// is flagged as error
ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.start =<expr>;"
ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.st =<expr>;" /* "<\n>#error StringTemplates are unsupported<\n>" */


/** How to execute an action */
execAction(action) ::= <<
<if(backtracking)>
if ( <actions.(actionScope).synpredgate> ) {
    <action>
}
<else>
<action>
<endif>
>>

/** How to always execute an action even when backtracking */
execForcedAction(action) ::= "<action>"

// M I S C (properties, etc...)

bitset(name, words64) ::= <<
static ANTLRBitSet *<name>;
static const unsigned long long <name>_data[] = { <words64:{it | <it>LL};separator=", ">};<\n>
>>

bitsetInit(name, words64) ::= <<
<name> = [[ANTLRBitSet newANTLRBitSetWithBits:(const unsigned long long *)<name>_data Count:(NSUInteger)<length(words64)>] retain];<\n>
>>

codeFileExtension() ::= ".m"

true_value() ::= "YES"
false_value() ::= "NO"
