/*
 [The "BSD license"]
 Copyright (c) 2005-2006 Terence Parr
 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.
*/

/** The API version of the runtime that recognizers generated by this runtime
 *  need.
 */
apiVersion() ::= "1"

// System.Boolean.ToString() returns "True" and "False", but the proper C# literals are "true" and "false"
// The Java version of Boolean returns "true" and "false", so they map to themselves here.
booleanLiteral ::= [
	       "True":"true",
	       "False":"false",
	       "true":"true",
	       "false":"false",
	       default:"false"
]

/** 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) ::=
<<
# $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>

<@imports>
import sys
from antlr3 import *
<if(TREE_PARSER)>
from antlr3.tree import *<\n>
<endif>
from antlr3.compat import set, frozenset
<@end>

<actions.(actionScope).header>

<! <docComment> !>

# for convenience in actions
HIDDEN = BaseRecognizer.HIDDEN

# token types
<tokens:{it | <it.name>=<it.type>}; separator="\n">

<recognizer>

<if(actions.(actionScope).main)>
<actions.(actionScope).main>
<else>
def main(argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
<if(LEXER)>
    from antlr3.main import LexerMain
    main = LexerMain(<recognizer.name>)<\n>
<endif>
<if(PARSER)>
    from antlr3.main import ParserMain
    main = ParserMain("<recognizer.grammar.name>Lexer", <recognizer.name>)<\n>
<endif>
<if(TREE_PARSER)>
    from antlr3.main import WalkerMain
    main = WalkerMain(<recognizer.name>)<\n>
<endif>
    main.stdin = stdin
    main.stdout = stdout
    main.stderr = stderr
    main.execute(argv)<\n>
<endif>

<actions.(actionScope).footer>

if __name__ == '__main__':
    main(sys.argv)

>>

lexer(grammar, name, tokens, scopes, rules, numRules, filterMode,
      labelType="CommonToken", superClass="Lexer") ::= <<
<grammar.directDelegates:
 {g|from <g.recognizerName> import <g.recognizerName>}; separator="\n">

class <grammar.recognizerName>(<@superClassName><superClass><@end>):
    <scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>

    grammarFileName = "<fileName>"
    api_version = <apiVersion()>

    def __init__(self<grammar.delegators:{g|, <g:delegateName()>}>, input=None, state=None):
        if state is None:
            state = RecognizerSharedState()
        super(<grammar.recognizerName>, self).__init__(input, state)

<if(memoize)>
<if(grammar.grammarIsRoot)>
        self._state.ruleMemo = {}
<endif>
<endif>

        <grammar.directDelegates:
         {g|self.<g:delegateName()> = <g.recognizerName>(<trunc(g.delegators):{p|<p:delegateName()>, }>self, input, state)}; separator="\n">
        <grammar.delegators:
         {g|self.<g:delegateName()> = <g:delegateName()>}; separator="\n">
        <last(grammar.delegators):
    	 {g|self.gParent = <g:delegateName()>}; separator="\n">
        self.delegates = [<grammar.delegates: {g|self.<g:delegateName()>}; separator = ", ">]

        <cyclicDFAs:{dfa | <cyclicDFAInit(dfa)>}; separator="\n">

        <actions.lexer.init>


    <actions.lexer.members>


<if(filterMode)>
    <filteringNextToken()>
<endif>
    <rules; separator="\n\n">

    <synpreds:{p | <lexerSynpred(p)>}>

    <cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>


>>

/** 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() ::= <<
def nextToken(self):
    while True:
        if self.input.LA(1) == EOF:
            return self.makeEOFToken()

        self._state.token = None
        self._state.channel = DEFAULT_CHANNEL
        self._state.tokenStartCharIndex = self.input.index()
        self._state.tokenStartCharPositionInLine = self.input.charPositionInLine
        self._state.tokenStartLine = self.input.line
        self._state._text = None
        try:
            m = self.input.mark()
            try:
                # means we won't throw slow exception
                self._state.backtracking = 1
                try:
                    self.mTokens()
                finally:
                    self._state.backtracking = 0

            except BacktrackingFailed:
                # mTokens backtracks with synpred at backtracking==2
                # and we set the synpredgate to allow actions at level 1.
                self.input.rewind(m)
                self.input.consume() # advance one char and try again

            else:
                self.emit()
                return self._state.token

        except RecognitionException, re:
            # shouldn't happen in backtracking mode, but...
            self.reportError(re)
            self.recover(re)


def memoize(self, input, ruleIndex, ruleStartIndex, success):
    if self._state.backtracking > 1:
        # is Lexer always superclass?
        super(<grammar.recognizerName>, self).memoize(input, ruleIndex, ruleStartIndex, success)


def alreadyParsedRule(self, input, ruleIndex):
    if self._state.backtracking > 1:
        return super(<grammar.recognizerName>, self).alreadyParsedRule(input, ruleIndex)
    return False


>>

actionGate() ::= "self._state.backtracking == 0"

filteringActionGate() ::= "self._state.backtracking == 1"

/** How to generate a parser */

genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
              bitsets, inputStreamType, superClass, labelType, members,
	      rewriteElementType, filterMode, init, ASTLabelType="Object") ::= <<
<if(grammar.grammarIsRoot)>
# token names
tokenNames = [
    "\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>",
    <tokenNames; wrap, separator=", ">
]<\n>
<else>
from <grammar.composite.rootGrammar.recognizerName> import tokenNames<\n>
<endif>
<scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScopeClass(scope=it)><endif>}>

<grammar.directDelegates:
 {g|from <g.recognizerName> import <g.recognizerName>}; separator="\n">

<rules:{it|<ruleAttributeScopeClass(scope=it.ruleDescriptor.ruleScope)>}>

class <grammar.recognizerName>(<@superClassName><superClass><@end>):
    grammarFileName = "<fileName>"
    api_version = <apiVersion()>
    tokenNames = tokenNames

    def __init__(self<grammar.delegators:{g|, <g:delegateName()>}>, input, state=None, *args, **kwargs):
        if state is None:
            state = RecognizerSharedState()

        <@args()>
        super(<grammar.recognizerName>, self).__init__(input, state, *args, **kwargs)

<if(memoize)>
<if(grammar.grammarIsRoot)>
        self._state.ruleMemo = {}
<endif>
<endif>

        <cyclicDFAs:{dfa | <cyclicDFAInit(dfa)>}; separator="\n">

        <scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeStack(scope=it)><endif>}>
	<rules:{it | <ruleAttributeScopeStack(scope=it.ruleDescriptor.ruleScope)>}>

        <init>

        <grammar.delegators:
         {g|self.<g:delegateName()> = <g:delegateName()>}; separator="\n">
        <grammar.directDelegates:
         {g|self.<g:delegateName()> = <g.recognizerName>(<trunc(g.delegators):{p|<p:delegateName()>, }>self, input, state)}; separator="\n">
        <grammar.indirectDelegates:
         {g|<g:delegateName()> = <g.delegator:delegateName()>.<g:delegateName()>}; separator="\n">
        <last(grammar.delegators):
    	 {g|self.gParent = self.<g:delegateName()>}; separator="\n">
        self.delegates = [<grammar.delegates: {g|self.<g:delegateName()>}; separator = ", ">]

	<@init><@end>


    <@members><@end>

    <members>

    <rules; separator="\n\n">

    <! generate rule/method definitions for imported rules so they
       appear to be defined in this recognizer. !>
    <grammar.delegatedRules:{ruleDescriptor| <delegateRule(ruleDescriptor)> }; separator="\n">

    <synpreds:{p | <synpred(p)>}>

    <cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>

    <bitsets:{it | FOLLOW_<it.name>_in_<it.inName><it.tokenIndex> = frozenset([<it.tokenTypes:{it | <it>};separator=", ">])<\n>}>

>>

delegateRule(ruleDescriptor) ::= <<
def <ruleDescriptor.name>(self, <ruleDescriptor.parameterScope:parameterScope()>):
<\ >   <if(ruleDescriptor.hasReturnValue)>return <endif>self.<ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name>(<ruleDescriptor.parameterScope.attributes:{a|<a.name>}; separator=", ">)


>>

parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets,
       ASTLabelType="Object", superClass="Parser", labelType="Token",
       members={<actions.parser.members>},
       init={<actions.parser.init>}
       ) ::= <<
<genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
              bitsets, "TokenStream", superClass,
              labelType, members, "Token",
              false, init, ASTLabelType)>
>>

/** 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="Object",
           superClass={<if(filterMode)><if(buildAST)>TreeRewriter<else>TreeFilter<endif><else>TreeParser<endif>},
           members={<actions.treeparser.members>},
	   init={<actions.treeparser.init>}
           ) ::= <<
<genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
              bitsets, "TreeNodeStream", superClass,
              labelType, members, "Node",
              filterMode, init, ASTLabelType)>
>>

/** 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>"
def <ruleName>_fragment(self, <ruleDescriptor.parameterScope:parameterScope()>):
    <ruleLabelDefs()>
<if(trace)>
    self.traceIn("<ruleName>_fragment", <ruleDescriptor.index>)
    try:
        <block>

    finally:
        self.traceOut("<ruleName>_fragment", <ruleDescriptor.index>)

<else>
    <block>
<endif>
# $ANTLR end "<ruleName>"


>>

synpred(name) ::= <<
def <name>(self):
    self._state.backtracking += 1
    <@start()>
    start = self.input.mark()
    try:
        self.<name>_fragment()
    except BacktrackingFailed:
        success = False
    else:
        success = True
    self.input.rewind(start)
    <@stop()>
    self._state.backtracking -= 1
    return success


>>

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

ruleMemoization(name) ::= <<
<if(memoize)>
if self._state.backtracking > 0 and self.alreadyParsedRule(self.input, <ruleDescriptor.index>):
    # for cached failed rules, alreadyParsedRule will raise an exception
    success = True
    return <ruleReturnValue()>

<endif>
>>

/** This rule has failed, exit indicating failure during backtrack */
ruleBacktrackFailure() ::= <<
<if(backtracking)>
if self._state.backtracking > 0:
    raise BacktrackingFailed

<endif>
>>

/** How to generate code for a rule.  This includes any return type
 *  data aggregates required for multiple return values.
 */
rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<
<returnScope(scope=ruleDescriptor.returnScope)>

# $ANTLR start "<ruleName>"
# <fileName>:<description>
<ruleDescriptor.actions.decorate>
def <ruleName>(self, <ruleDescriptor.parameterScope:parameterScope()>):
<if(trace)>
    self.traceIn("<ruleName>", <ruleDescriptor.index>)<\n>
<endif>
    <ruleScopeSetUp()>
    <ruleDeclarations()>
    <ruleLabelDefs()>
    <ruleDescriptor.actions.init>
    <@preamble()>
    <@body><ruleBody()><@end>
    <@postamble()>
    return <ruleReturnValue()>

# $ANTLR end "<ruleName>"
>>

ruleBody() ::= <<
<if(memoize)>
<if(backtracking)>
success = False<\n>
<endif>
<endif>
try:
    try:
        <ruleMemoization(name=ruleName)>
        <block>
        <ruleCleanUp()>
        <(ruleDescriptor.actions.after):execAction()>

<if(memoize)>
<if(backtracking)>
        success = True<\n>
<endif>
<endif>
<if(exceptions)>
    <exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
<else>
<if(!emptyRule)>
<if(actions.(actionScope).rulecatch)>
    <actions.(actionScope).rulecatch>
<else>
    except RecognitionException, re:
        self.reportError(re)
        self.recover(self.input, re)
        <@setErrorReturnValue()>

<endif>
<else>
    finally:
        pass

<endif>
<endif>
finally:
<if(trace)>
    self.traceOut("<ruleName>", <ruleDescriptor.index>)<\n>
<endif>
    <memoize()>
    <ruleScopeCleanUp()>
    <finally>
    pass
>>

catch(decl,action) ::= <<
except <e.decl>:
    <e.action>

>>

ruleDeclarations() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
retval = self.<ruleDescriptor.name>_return()
retval.start = self.input.LT(1)<\n>
<else>
<ruleDescriptor.returnScope.attributes:{ a |
<a.name> = <if(a.initValue)><a.initValue><else>None<endif>
}>
<endif>
<if(memoize)>
<ruleDescriptor.name>_StartIndex = self.input.index()
<endif>
>>

ruleScopeSetUp() ::= <<
<ruleDescriptor.useScopes:{it | self.<it>_stack.append(<it>_scope())}; separator="\n">
<ruleDescriptor.ruleScope:{it | self.<it.name>_stack.append(<it.name>_scope())}; separator="\n">
>>

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

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

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

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

ruleCleanUp() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
<if(!TREE_PARSER)>
retval.stop = self.input.LT(-1)<\n>
<endif>
<endif>
>>

memoize() ::= <<
<if(memoize)>
<if(backtracking)>
if self._state.backtracking > 0:
    self.memoize(self.input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex, success)

<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>"
def m<ruleName>(self, <ruleDescriptor.parameterScope:parameterScope()>):
<if(trace)>
    self.traceIn("<ruleName>", <ruleDescriptor.index>)<\n>
<endif>
    <ruleScopeSetUp()>
    <ruleDeclarations()>
<if(memoize)>
<if(backtracking)>
    success = False<\n>
<endif>
<endif>
    try:
<if(nakedBlock)>
        <ruleMemoization(name=ruleName)>
        <lexerRuleLabelDefs()>
        <ruleDescriptor.actions.init>
        <block><\n>
<else>
        _type = <ruleName>
        _channel = DEFAULT_CHANNEL

        <ruleMemoization(name=ruleName)>
        <lexerRuleLabelDefs()>
        <ruleDescriptor.actions.init>
        <block>
        <ruleCleanUp()>
        self._state.type = _type
        self._state.channel = _channel
        <(ruleDescriptor.actions.after):execAction()>
<endif>
<if(memoize)>
<if(backtracking)>
        success = True<\n>
<endif>
<endif>

    finally:
<if(trace)>
        self.traceOut("<ruleName>", <ruleDescriptor.index>)<\n>
<endif>
	<ruleScopeCleanUp()>
        <memoize()>
        pass

# $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) ::= <<
def mTokens(self):
    <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>
alt<decisionNumber> = <maxAlt>
<decls>
<@body><blockBody()><@end>
>>

blockBody() ::= <<
<@predecision()>
<@decision><decision><@end>
<@postdecision()>
<@prebranch()>
<alts:{a | <altSwitchCase(i, a)>}; separator="\nel">
<@postbranch()>
>>

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

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

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

/** A (..)+ block with 1 or more alternatives */
positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
# <fileName>:<description>
cnt<decisionNumber> = 0
<decls>
<@preloop()>
<@loopBody>
<positiveClosureBlockLoop()>
<@end>
<@postloop()>
>>

positiveClosureBlockLoop() ::= <<
while True: #loop<decisionNumber>
    alt<decisionNumber> = <maxAlt>
    <@predecision()>
    <@decisionBody><decision><@end>
    <@postdecision()>
    <alts:{a | <altSwitchCase(i, a)>}; separator="\nel">
    else:
        if cnt<decisionNumber> >= 1:
            break #loop<decisionNumber>

        <ruleBacktrackFailure()>
        eee = EarlyExitException(<decisionNumber>, self.input)
        <@earlyExitException()>
        raise eee

    cnt<decisionNumber> += 1
>>

positiveClosureBlockSingleAlt ::= positiveClosureBlock

/** A (..)* block with 1 or more alternatives */
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
# <fileName>:<description>
<decls>
<@preloop()>
<@loopBody>
<closureBlockLoop()>
<@end>
<@postloop()>
>>

closureBlockLoop() ::= <<
while True: #loop<decisionNumber>
    alt<decisionNumber> = <maxAlt>
    <@predecision()>
    <@decisionBody><decision><@end>
    <@postdecision()>
    <alts:{a | <altSwitchCase(i, a)>}; separator="\nel">
    else:
        break #loop<decisionNumber>
>>

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) ::= <<
if alt<decisionNumber> == <altNum>:
    <@prealt()>
    <alt>
>>

/** An alternative is just a list of elements; at outermost level */
alt(elements,altNum,description,autoAST,outerAlt, treeLevel,rew) ::= <<
# <fileName>:<description>
pass <! so empty alternatives are a valid block !>
<@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()>
<e.el><\n>
>>

/** match a token optionally with a label in front */
tokenRef(token,label,elementIndex,terminalOptions) ::= <<
<if(label)><label> = <endif>self.match(self.input, <token>, self.FOLLOW_<token>_in_<ruleName><elementIndex>)
>>

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

listLabel(label, elem) ::= <<
if list_<label> is None:
    list_<label> = []
list_<label>.append(<elem>)<\n>
>>

/** match a character */
charRef(char,label) ::= <<
<if(label)>
<label> = self.input.LA(1)<\n>
<endif>
self.match(<char>)
>>

/** match a character range */
charRangeRef(a,b,label) ::= <<
<if(label)>
<label> = self.input.LA(1)<\n>
<endif>
self.matchRange(<a>, <b>)
>>

/** For now, sets are interval tests and must be tested inline */
matchSet(s,label,elementIndex,terminalOptions,postmatchCode="") ::= <<
<if(label)>
<label> = self.input.LT(1)<\n>
<endif>
if <s>:
    self.input.consume()
    <postmatchCode>
<if(!LEXER)>
    self._state.errorRecovery = False<\n>
<endif>

else:
    <ruleBacktrackFailure()>
    mse = MismatchedSetException(None, self.input)
    <@mismatchedSetException()>
<if(LEXER)>
    self.recover(mse)
    raise mse
<else>
    raise mse
    <! use following code to make it recover inline; remove throw mse;
    self.recoverFromMismatchedSet(
        self.input, mse, self.FOLLOW_set_in_<ruleName><elementIndex>
        )
    !>
<endif>
<\n>
>>

matchRuleBlockSet ::= matchSet

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

/** Match a string literal */
lexerStringRef(string,label,elementIndex="0") ::= <<
<if(label)>
<label>Start = self.getCharIndex()
self.match(<string>)
<label>StartLine<elementIndex> = self.getLine()
<label>StartCharPos<elementIndex> = self.getCharPositionInLine()
<label> = <labelType>(input=self.input, type=INVALID_TOKEN_TYPE, channel=DEFAULT_CHANNEL, start=<label>Start, stop=self.getCharIndex()-1)
<label>.setLine(<label>StartLine<elementIndex>)
<label>.setCharPositionInLine(<label>StartCharPos<elementIndex>)
<else>
self.match(<string>)
<endif>
>>

wildcard(token,label,elementIndex,terminalOptions) ::= <<
<if(label)>
<label> = self.input.LT(1)<\n>
<endif>
self.matchAny(self.input)
>>

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

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

wildcardCharListLabel(label, elementIndex) ::= <<
<wildcardChar(label, elementIndex)>
<listLabel(label, 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) ::= <<
self._state.following.append(self.FOLLOW_<rule.name>_in_<ruleName><elementIndex>)
<if(label)><label> = <endif>self.<if(scope)><scope:delegateName()>.<endif><rule.name>(<args; separator=", ">)<\n>
self._state.following.pop()
>>

/** ids+=rule */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRef(rule,label,elementIndex,args,scope)>
<listLabel(label, 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)>
<label>Start<elementIndex> = self.getCharIndex()
self.<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">)
<label>StartLine<elementIndex> = self.getLine()
<label>StartCharPos<elementIndex> = self.getCharPositionInLine()
<label> = <labelType>(
    input=self.input,
    type=INVALID_TOKEN_TYPE,
    channel=DEFAULT_CHANNEL,
    start=<label>Start<elementIndex>,
    stop=self.getCharIndex()-1)
<label>.setLine(<label>StartLine<elementIndex>)
<label>.setCharPositionInLine(<label>StartCharPos<elementIndex>)
<else>
self.<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">)
<endif>
>>

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

/** EOF in the lexer */
lexerMatchEOF(label,elementIndex) ::= <<
<if(label)>
<label>Start<elementIndex> = self.getCharIndex()
<label>StartLine<elementIndex> = self.getLine()
<label>StartCharPos<elementIndex> = self.getCharPositionInLine()
self.match(EOF)
<label> = <labelType>(input=self.input, type=EOF, channel=DEFAULT_CHANNEL, start=<label>Start<elementIndex>, stop=self.getCharIndex()-1)
<label>.setLine(<label>StartLine<elementIndex>)
<label>.setCharPositionInLine(<label>StartCharPos<elementIndex>)
<else>
self.match(EOF)
<endif>
>>

// used for left-recursive rules
recRuleDefArg()                       ::= "<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 self.input.LA(1) == DOWN:
    self.match(self.input, DOWN, None)
    <children:element()>
    self.match(self.input, UP, None)

<else>
self.match(self.input, DOWN, None)
<children:element()>
self.match(self.input, UP, None)
<endif>
>>

/** Every predicate is used as a validating predicate (even when it is
 *  also hoisted into a prediction expression).
 */
validateSemanticPredicate(pred,description) ::= <<
if not (<evalPredicate(pred, description)>):
    <ruleBacktrackFailure()>
    raise FailedPredicateException(self.input, "<ruleName>", "<description>")

>>

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

dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
LA<decisionNumber>_<stateNumber> = self.input.LA(<k>)<\n>
<edges; separator="\nel">
else:
<if(eotPredictsAlt)>
    alt<decisionNumber> = <eotPredictsAlt>
<else>
    <ruleBacktrackFailure()>
    nvae = NoViableAltException("<description>", <decisionNumber>, <stateNumber>, self.input)<\n>
    <@noViableAltException()>
    raise 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) ::= <<
LA<decisionNumber>_<stateNumber> = self.input.LA(<k>)<\n>
<edges; separator="\nel">
>>

/** 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) ::= <<
LA<decisionNumber>_<stateNumber> = self.input.LA(<k>)<\n>
<edges; separator="\nel"><\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)>and (<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) ::= <<
<!
  FIXME: this is one of the few occasion, where I miss a switch statement
  in Python. ATM this is implemented as a list of if .. elif ..
  This may be replaced by faster a dictionary lookup, when I find a solution
  for the cases when an edge is not a plain dfaAcceptState.
!>
LA<decisionNumber> = self.input.LA(<k>)
<edges; separator="\nel">
else:
<if(eotPredictsAlt)>
    alt<decisionNumber> = <eotPredictsAlt>
<else>
    <ruleBacktrackFailure()>
    nvae = NoViableAltException("<description>", <decisionNumber>, <stateNumber>, self.input)<\n>
    <@noViableAltException()>
    raise nvae<\n>
<endif>

>>

dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
LA<decisionNumber> = self.input.LA(<k>)
<edges; separator="\nel">
>>

dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
LA<decisionNumber> = self.input.LA(<k>)
<edges; separator="\nel">
<if(eotPredictsAlt)>
else:
    alt<decisionNumber> = <eotPredictsAlt>
<endif>
>>

dfaEdgeSwitch(labels, targetState) ::= <<
if <labels:{it | LA<decisionNumber> == <it>}; separator=" or ">:
    <targetState>
>>

// 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> = self.dfa<decisionNumber>.predict(self.input)
>>

/* 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) ::= <<
# lookup tables for DFA #<dfa.decisionNumber>

DFA<dfa.decisionNumber>_eot = DFA.unpack(
    u"<dfa.javaCompressedEOT; wrap="\"\n    u\"">"
    )

DFA<dfa.decisionNumber>_eof = DFA.unpack(
    u"<dfa.javaCompressedEOF; wrap="\"\n    u\"">"
    )

DFA<dfa.decisionNumber>_min = DFA.unpack(
    u"<dfa.javaCompressedMin; wrap="\"\n    u\"">"
    )

DFA<dfa.decisionNumber>_max = DFA.unpack(
    u"<dfa.javaCompressedMax; wrap="\"\n    u\"">"
    )

DFA<dfa.decisionNumber>_accept = DFA.unpack(
    u"<dfa.javaCompressedAccept; wrap="\"\n    u\"">"
    )

DFA<dfa.decisionNumber>_special = DFA.unpack(
    u"<dfa.javaCompressedSpecial; wrap="\"\n    u\"">"
    )


DFA<dfa.decisionNumber>_transition = [
    <dfa.javaCompressedTransition:{s|DFA.unpack(u"<s; wrap="\"\nu\"">")}; separator=",\n">
]

# class definition for DFA #<dfa.decisionNumber>

class DFA<dfa.decisionNumber>(DFA):
    pass

    <@errorMethod()>

<if(dfa.specialStateSTs)>
    def specialStateTransition(self_, s, input):
        # convince pylint that my self_ magic is ok ;)
        # pylint: disable-msg=E0213

        # pretend we are a member of the recognizer
        # thus semantic predicates can be evaluated
        self = self_.recognizer

        _s = s

        <dfa.specialStateSTs:{state |
if s == <i0>: <! compressed special state numbers 0..n-1 !>
    <state>}; separator="\nel">

<if(backtracking)>
        if self._state.backtracking > 0:
            raise BacktrackingFailed

<endif>
        nvae = NoViableAltException(self_.getDescription(), <dfa.decisionNumber>, _s, input)
        self_.error(nvae)
        raise nvae<\n>
<endif>

>>

cyclicDFAInit(dfa) ::= <<
self.dfa<dfa.decisionNumber> = self.DFA<dfa.decisionNumber>(
    self, <dfa.decisionNumber>,
    eot = self.DFA<dfa.decisionNumber>_eot,
    eof = self.DFA<dfa.decisionNumber>_eof,
    min = self.DFA<dfa.decisionNumber>_min,
    max = self.DFA<dfa.decisionNumber>_max,
    accept = self.DFA<dfa.decisionNumber>_accept,
    special = self.DFA<dfa.decisionNumber>_special,
    transition = self.DFA<dfa.decisionNumber>_transition
    )<\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) ::= <<
LA<decisionNumber>_<stateNumber> = input.LA(1)<\n>
<if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>
index<decisionNumber>_<stateNumber> = input.index()
input.rewind()<\n>
<endif>
s = -1
<edges; separator="\nel">
<if(semPredState)> <! return input cursor to state before we rewound !>
input.seek(index<decisionNumber>_<stateNumber>)<\n>
<endif>
if s >= 0:
    return s
>>

/** Just like a fixed DFA edge, test the lookahead and indicate what
 *  state to jump to next if successful.
 */
cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
if (<labelExpr>)<if(predicates)> and (<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) ::= <<
se:
    s = <targetStateNumber><\n>
>>


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

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

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

notPredicate(pred) ::= "not (<evalPredicate(pred, {})>)"

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

evalSynPredicate(pred,description) ::= "self.<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) ::= "self.input.LA(<k>) == <atom>"

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

isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(<lower> \<= self.input.LA(<k>) \<= <upper>)"

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

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

globalAttributeScopeClass(scope) ::= <<
<if(scope.attributes)>
class <scope.name>_scope(object):
    def __init__(self):
        <scope.attributes:{it | self.<it.decl> = None}; separator="\n">

<endif>
>>

globalAttributeScopeStack(scope) ::= <<
<if(scope.attributes)>
self.<scope.name>_stack = []<\n>
<endif>
>>

ruleAttributeScopeClass(scope) ::= <<
<if(scope.attributes)>
class <scope.name>_scope(object):
    def __init__(self):
        <scope.attributes:{it | self.<it.decl> = None}; separator="\n">

<endif>
>>

ruleAttributeScopeStack(scope) ::= <<
<if(scope.attributes)>
self.<scope.name>_stack = []<\n>
<endif>
>>

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

/** Define a rule label including default value */
ruleLabelDef(label) ::= <<
<label.label.text> = None<\n>
>>

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

/** 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.
 */
returnScope(scope) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
class <ruleDescriptor:returnStructName()>(<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope):
    def __init__(self):
        super(<grammar.recognizerName>.<ruleDescriptor:returnStructName()>, self).__init__()

        <scope.attributes:{it | self.<it.decl> = None}; separator="\n">
        <@ruleReturnInit()>


    <@ruleReturnMembers()>

<endif>
>>

parameterScope(scope) ::= <<
<scope.attributes:{it | <it.decl>}; separator=", ">
>>

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

scopeAttributeRef(scope,attr,index,negIndex) ::= <%
<if(negIndex)>
self.<scope>_stack[-<negIndex>].<attr.name>
<else>
<if(index)>
self.<scope>_stack[<index>].<attr.name>
<else>
self.<scope>_stack[-1].<attr.name>
<endif>
<endif>
%>

/* not applying patch because of bug in action parser!

<if(negIndex)>
((len(self.<scope>_stack) - <negIndex> - 1) >= 0 and [self.<scope>_stack[-<negIndex>].<attr.name>] or [None])[0]
<else>
<if(index)>
((<index> \< len(self.<scope>_stack)) and [self.<scope>_stack[<index>].<attr.name>] or [None])[0]
<else>
((len(self.<scope>_stack) > 0) and [self.<scope>_stack[-1].<attr.name>] or [None])[0]
<endif>
<endif>

*/

scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <%
<if(negIndex)>
<!FIXME: this seems not to be used by ActionTranslator...!>
self.<scope>_stack[-<negIndex>].<attr.name> = <expr>
<else>
<if(index)>
<!FIXME: this seems not to be used by ActionTranslator...!>
self.<scope>_stack[<index>].<attr.name> = <expr>
<else>
self.<scope>_stack[-1].<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) ::= "self.<scope>_stack"

/** reference an attribute of rule; might only have single return value */
ruleLabelRef(referencedRule,scope,attr) ::= <%
<if(referencedRule.hasMultipleReturnValues)>
((<scope> is not None) and [<scope>.<attr.name>] or [None])[0]
<else>
<scope>
<endif>
%>

returnAttributeRef(ruleDescriptor,attr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name>
<else>
<attr.name>
<endif>
%>

returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <%
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.<attr.name> = <expr>
<else>
<attr.name> = <expr>
<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>.text"
tokenLabelPropertyRef_type(scope,attr) ::= "<scope>.type"
tokenLabelPropertyRef_line(scope,attr) ::= "<scope>.line"
tokenLabelPropertyRef_pos(scope,attr) ::= "<scope>.charPositionInLine"
tokenLabelPropertyRef_channel(scope,attr) ::= "<scope>.channel"
tokenLabelPropertyRef_index(scope,attr) ::= "<scope>.index"
tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"

ruleLabelPropertyRef_start(scope,attr) ::= "<scope>.start"
ruleLabelPropertyRef_stop(scope,attr) ::= "<scope>.stop"
ruleLabelPropertyRef_tree(scope,attr) ::= "<scope>.tree"
ruleLabelPropertyRef_text(scope,attr) ::= <%
<if(TREE_PARSER)>
((<scope> is not None) and [self.input.getTokenStream().toString(
    self.input.getTreeAdaptor().getTokenStartIndex(<scope>.start),
    self.input.getTreeAdaptor().getTokenStopIndex(<scope>.start)
    )] or [None])[0]
<else>
((<scope> is not None) and [self.input.toString(<scope>.start,<scope>.stop)] or [None])[0]
<endif>
%>
ruleLabelPropertyRef_st(scope,attr) ::= "((<scope> is not None) and [<scope>.st] or [None])[0]"

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

lexerRuleLabelPropertyRef_type(scope,attr) ::= "((<scope> is not None) and [<scope>.type] or [0])[0]"
lexerRuleLabelPropertyRef_line(scope,attr) ::= "((<scope> is not None) and [<scope>.line] or [0])[0]"
lexerRuleLabelPropertyRef_pos(scope,attr) ::= "((<scope> is not None) and [<scope>.charPositionInLine] or [0])[0]"
lexerRuleLabelPropertyRef_channel(scope,attr) ::= "((<scope> is not None) and [<scope>.channel] or [0])[0]"
lexerRuleLabelPropertyRef_index(scope,attr) ::= "((<scope> is not None) and [<scope>.index] or [0])[0]"
lexerRuleLabelPropertyRef_text(scope,attr) ::= "((<scope> is not None) and [<scope>.text] or [None])[0]"
lexerRuleLabelPropertyRef_int(scope,attr) ::= "((<scope> is not None) and [int(<scope>.text)] or [0])[0]"

// Somebody may ref $template or $tree or $stop within a rule:
rulePropertyRef_start(scope,attr) ::= "retval.start"
rulePropertyRef_stop(scope,attr) ::= "retval.stop" //mmm... or input.LT(-1)??
rulePropertyRef_tree(scope,attr) ::= "retval.tree"
rulePropertyRef_text(scope,attr) ::= "self.input.toString(retval.start, self.input.LT(-1))"
rulePropertyRef_st(scope,attr) ::= "retval.st"

lexerRulePropertyRef_text(scope,attr) ::= "self.text"
lexerRulePropertyRef_type(scope,attr) ::= "_type"
lexerRulePropertyRef_line(scope,attr) ::= "self._state.tokenStartLine"
lexerRulePropertyRef_pos(scope,attr) ::= "self._state.tokenStartCharPositionInLine"
lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
lexerRulePropertyRef_channel(scope,attr) ::= "_channel"
lexerRulePropertyRef_start(scope,attr) ::= "self._state.tokenStartCharIndex"
lexerRulePropertyRef_stop(scope,attr) ::= "(self.getCharIndex()-1)"
lexerRulePropertyRef_int(scope,attr) ::= "int(<scope>.text)"

// setting $st and $tree is allowed in local rule. everything else
// is flagged as error
ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.tree =<expr>"
ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.st =<expr>"


/** How to execute an action (only when not backtracking) */
execAction(action) ::= <<
<if(backtracking)>
<if(actions.(actionScope).synpredgate)>
if <actions.(actionScope).synpredgate>:
    pass
    <action>

<else>
if <actions.(actionScope).synpredgate>:
    pass
    <action>

<endif>
<else>
#action start
<action>
#action end
<endif>
>>

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


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

codeFileExtension() ::= ".py"

true_value() ::= "True"
false_value() ::= "False"
