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

group Perl5;

/** 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>
<actions.(actionScope).header>

<@imports>
<if(TREE_PARSER)>
<endif>
<if(backtracking)>
<endif>
<@end>

<docComment>
<recognizer>
>>

lexer(grammar, name, tokens, scopes, rules, numRules, labelType="Token",
      filterMode, superClass="ANTLR::Runtime::Lexer")  ::= <<
package <name>;

use Carp;
use English qw( -no_match_vars ) ;
use Readonly;
use Switch;

use ANTLR::Runtime::BaseRecognizer;
use ANTLR::Runtime::DFA;
use ANTLR::Runtime::NoViableAltException;

use Moose;

extends 'ANTLR::Runtime::Lexer';

Readonly my $HIDDEN => ANTLR::Runtime::BaseRecognizer->HIDDEN;
sub HIDDEN { $HIDDEN }

use constant {
    <tokens:{ <it.name> => <it.type>, }; separator="\n">
};
<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
<actions.lexer.members>

sub BUILD {
    my ($self, $arg_ref) = @_;

    $self->init_dfas();
}

sub get_grammar_file_name {
    return "<fileName>";
}

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

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

<cyclicDFAs:{dfa | has 'dfa<dfa.decisionNumber>';}; separator="\n">

sub init_dfas {
    my ($self) = @_;

    <cyclicDFAs:{dfa |
    $self->dfa<dfa.decisionNumber>(<name>::DFA<dfa.decisionNumber>->new({ recognizer => $self }));
    }; separator="\n">

    return;
}

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

no Moose;
__PACKAGE__->meta->make_immutable();
1;

>>

perlTypeInitMap ::= [
	"$":"undef",
	"@":"()",
	"%":"()",
	default:"undef"
]

/** 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() ::= <<
public Token nextToken() {
    while (true) {
        if ( input.LA(1)==CharStream.EOF ) {
            return Token.EOF_TOKEN;
        }
        token = null;
	channel = Token.DEFAULT_CHANNEL;
        tokenStartCharIndex = input.index();
        tokenStartCharPositionInLine = input.getCharPositionInLine();
        tokenStartLine = input.getLine();
	text = null;
        try {
            int m = input.mark();
            backtracking=1; <! means we won't throw slow exception !>
            failed=false;
            mTokens();
            backtracking=0;
            <! mTokens backtracks with synpred at backtracking==2
               and we set the synpredgate to allow actions at level 1. !>
            if ( failed ) {
                input.rewind(m);
                input.consume(); <! advance one char and try again !>
            }
            else {
                emit();
                return token;
            }
        }
        catch (RecognitionException re) {
            // shouldn't happen in backtracking mode, but...
            reportError(re);
            recover(re);
        }
    }
}

public void memoize(IntStream input,
		int ruleIndex,
		int ruleStartIndex)
{
if ( backtracking>1 ) super.memoize(input, ruleIndex, ruleStartIndex);
}

public boolean alreadyParsedRule(IntStream input, int ruleIndex) {
if ( backtracking>1 ) return super.alreadyParsedRule(input, ruleIndex);
return false;
}
>>

actionGate() ::= "$self->state->backtracking==0"

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

/** How to generate a parser */
genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
              bitsets, inputStreamType, superClass, filterMode,
              ASTLabelType="Object", labelType, members) ::= <<
package <name>;

use English qw( -no_match_vars ) ;
use Readonly;
use Switch;
use Carp;
use ANTLR::Runtime::BitSet;

use Moose;

extends '<@superClassName><superClass><@end>';

Readonly my $token_names => [
    "\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ">
];

use constant {
<tokens:{ <it.name> => <it.type>, }; separator="\n">
};

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

<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
<@members>
<! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !>

sub BUILD {
    my ($self, $arg_ref) = @_;

<if(backtracking)>
    $self->state->rule_memo({});<\n>
<endif>
}
<@end>

sub get_token_names {
    return $token_names;
}

sub get_grammar_file_name {
    return "<fileName>";
}

<members>

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

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

<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = __PACKAGE__::DFA<dfa.decisionNumber>->new($self);}; separator="\n">
<cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>

no Moose;
__PACKAGE__->meta->make_immutable();
1;
__END__
>>

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

/** 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, labelType={<ASTLabelType>}, ASTLabelType="Object", superClass="ANTLR::Runtime::TreeParser", members={<actions.treeparser.members>}, filterMode) ::= <<
<genericParser(inputStreamType="TreeNodeStream", ...)>
>>

/** 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>
sub <ruleName>_fragment {
# <ruleDescriptor.parameterScope:parameterScope(scope=it)>

<if(trace)>
    $self->traceIn("<ruleName>_fragment", <ruleDescriptor.index>);
    eval {
        <block>
    };
    $self->traceOut("<ruleName>_fragment", <ruleDescriptor.index>);
    if ($EVAL_ERROR) {
        croak $EVAL_ERROR;
    }
<else>
    <block>
<endif>
}
# $ANTLR end <ruleName>
>>

synpred(name) ::= <<
public final boolean <name>() {
    backtracking++;
    <@start()>
    int start = input.mark();
    try {
        <name>_fragment(); // can never throw exception
    } catch (RecognitionException re) {
        System.err.println("impossible: "+re);
    }
    boolean success = !failed;
    input.rewind(start);
    <@stop()>
    backtracking--;
    failed=false;
    return success;
}<\n>
>>

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

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

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

/** This rule has failed, exit indicating failure during backtrack */
ruleBacktrackFailure() ::= <<
<if(backtracking)>if (backtracking>0) {failed=true; return <ruleReturnValue()>;}<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) ::= <<
<ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
<returnScope(scope=ruleDescriptor.returnScope)>

# $ANTLR start <ruleName>
# <fileName>:<description>
sub <ruleName>() {
    my ($self, <ruleDescriptor.parameterScope:parameterScope(scope=it)>) = @_;
    <if(trace)>$self->traceIn("<ruleName>", <ruleDescriptor.index>);<endif>
    <ruleScopeSetUp()>
    <ruleDeclarations()>
    <ruleLabelDefs()>
    <ruleDescriptor.actions.init>
    <@preamble()>
    eval {
        <ruleMemoization(name=ruleName)>
        <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>
    my $exception = $EVAL_ERROR;
    if (ref $exception && $exception->isa('ANTLR::Runtime::RecognitionException')) {
        $self->report_error($exception);
        $self->recover($self->input, $exception);
        $exception = undef;
    }<\n>
<endif>
<endif>
<endif>
    <if(trace)>$self->traceOut("<ruleName>", <ruleDescriptor.index>);<endif>
    <memoize()>
    <ruleScopeCleanUp()>
    <finally>
    if ($exception) {
        croak $exception;
        #$exception->rethrow();
    }
    <@postamble()>
    return <ruleReturnValue()>;
}
# $ANTLR end <ruleName>
>>

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

ruleDeclarations() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
my $retval = <returnType()>->new();
$retval->set_start($self->input->LT(1));<\n>
<else>
<ruleDescriptor.returnScope.attributes:{ a |
my $<a.name> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
}>
<endif>
<if(memoize)>
my $<ruleDescriptor.name>_start_index = $self->input->index();
<endif>
>>

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

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

ruleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels]
    :{my $<it.label.text> = undef;}; separator="\n"
>
<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]
    :{List list_<it.label.text>=null;}; separator="\n"
>
<ruleDescriptor.ruleLabels:ruleLabelDef(label=it); separator="\n">
<ruleDescriptor.ruleListLabels:{ll|RuleReturnScope <ll.label.text> = null;}; separator="\n">
>>

lexerRuleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,
  ruleDescriptor.tokenListLabels,
  ruleDescriptor.ruleLabels]
    :{<labelType> <it.label.text>=null;}; separator="\n"
>
<ruleDescriptor.charLabels:{my $<it.label.text>;}; separator="\n">
<[ruleDescriptor.tokenListLabels,
  ruleDescriptor.ruleListLabels,
  ruleDescriptor.ruleListLabels]
    :{List list_<it.label.text>=null;}; 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->set_stop($self->input->LT(-1));<\n>
<endif>
<endif>
>>

memoize() ::= <<
<if(memoize)>
<if(backtracking)>
if ( backtracking>0 ) { memoize(input, <ruleDescriptor.index>, <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>
sub m_<ruleName> {
# <ruleDescriptor.parameterScope:parameterScope(scope=it)>
    my ($self) = @_;
    <if(trace)>traceIn("<ruleName>", <ruleDescriptor.index>);<endif>
    <ruleDeclarations()>
    eval {
<if(nakedBlock)>
        <ruleMemoization(name=ruleName)>
        <lexerRuleLabelDefs()>
        <ruleDescriptor.actions.init>
        <block><\n>
<else>
        my $_type = <ruleName>;
        my $_channel = $self->DEFAULT_TOKEN_CHANNEL;
        <ruleMemoization(name=ruleName)>
        <lexerRuleLabelDefs()>
        <ruleDescriptor.actions.init>
        <block>
        <ruleCleanUp()>
        $self->state->type($_type);
        $self->state->channel($_channel);
        <(ruleDescriptor.actions.after):execAction()>
<endif>
    };
    <if(trace)>traceOut("<ruleName>", <ruleDescriptor.index>);<endif>
    <memoize()>

    if ($EVAL_ERROR) {
        croak $EVAL_ERROR;
    }
}
# $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) ::= <<
sub m_tokens {
    my ($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>
my $alt<decisionNumber> = <maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
<@prebranch()>
switch ($alt<decisionNumber>) {
    <alts:altSwitchCase()>
}
<@postbranch()>
>>

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

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>
my $cnt<decisionNumber> = 0;
<decls>
<@preloop()>
LOOP<decisionNumber>:
while (1) {
    my $alt<decisionNumber> = <maxAlt>;
    <@predecision()>
    <decision>
    <@postdecision()>
    switch ($alt<decisionNumber>) {
	    <alts:altSwitchCase()>
	    else {
	        if ( $cnt<decisionNumber> >= 1 ) { last LOOP<decisionNumber> }
	        <ruleBacktrackFailure()>
            my $eee =
                ANTLR::Runtime::EarlyExitException->new(<decisionNumber>, $self->input);
            <@earlyExitException()>
            croak $eee;
        }
    }
    ++$cnt<decisionNumber>;
}
<@postloop()>
>>

positiveClosureBlockSingleAlt ::= positiveClosureBlock

/** A (..)* block with 1 or more alternatives */
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
# <fileName>:<description>
<decls>
<@preloop()>
LOOP<decisionNumber>:
while (1) {
    my $alt<decisionNumber> = <maxAlt>;
    <@predecision()>
    <decision>
    <@postdecision()>
    switch ($alt<decisionNumber>) {
	    <alts:altSwitchCase()>
	    else { last 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() ::= <<
case <i> {
    <@prealt()>
    <it>
}<\n>
>>

/** An alternative is just a list of elements; at outermost level */
alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
# <fileName>:<description>
{
<@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() ::= <<
<@prematch()>
<it.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>, $FOLLOW_<token>_in_<ruleName><elementIndex>);
<checkRuleBacktrackFailure()>
>>

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

listLabel(label,elem) ::= <<
if (list_<label>==null) list_<label>=new ArrayList();
list_<label>.add(<elem>);<\n>
>>

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

/** match a character range */
charRangeRef(a,b,label) ::= <<
<if(label)>
<label> = $self->input->LA(1);<\n>
<endif>
$self->match_range(<a>,<b>); <checkRuleBacktrackFailure()>
>>

/** For now, sets are interval tests and must be tested inline */
matchSet(s,label,elementIndex,postmatchCode="") ::= <<
<if(label)>
<if(LEXER)>
<label>= $self->input->LA(1);<\n>
<else>
<label>=(<labelType>)input.LT(1);<\n>
<endif>
<endif>
if ( <s> ) {
    $self->input->consume();
    <postmatchCode>
<if(!LEXER)>
    $self->state->error_recovery(0);
<endif>
    <if(backtracking)>failed=false;<endif>
}
else {
    <ruleBacktrackFailure()>
    my $mse =
        ANTLR::Runtime::MismatchedSetException->new(undef, $self->input);
    <@mismatchedSetException()>
<if(LEXER)>
    $self->recover($mse);
    $mse->throw();
<else>
    $mse->throw();
    <! use following code to make it recover inline; remove throw mse;
    $self->recoverFromMismatchedSet($self->input, $mse, $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) ::= <<
<if(label)>
int <label>Start = getCharIndex();
$self->match(<string>); <checkRuleBacktrackFailure()>
<labelType> <label> = new CommonToken(input, Token.INVALID_TOKEN_TYPE, Token.DEFAULT_CHANNEL, <label>Start, getCharIndex()-1);
<else>
$self->match(<string>); <checkRuleBacktrackFailure()><\n>
<endif>
>>

wildcard(label,elementIndex) ::= <<
<if(label)>
<label>=(<labelType>)input.LT(1);<\n>
<endif>
matchAny(input); <checkRuleBacktrackFailure()>
>>

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

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

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

/** Match a rule reference by invoking it possibly with arguments
 *  and a return value or values.
 */
ruleRef(rule,label,elementIndex,args,scope) ::= <<
$self->push_follow($FOLLOW_<rule.name>_in_<ruleName><elementIndex>);
<if(label)>
$<label> = $self-><rule.name>(<args; separator=", ">);<\n>
<else>
$self-><rule.name>(<args; separator=", ">);<\n>
<endif>
$self->state->_fsp($self->state->_fsp - 1);
<checkRuleBacktrackFailure()>
>>

/** 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)>
int <label>Start<elementIndex> = getCharIndex();
$self->m_<rule>(<args; separator=", ">); <checkRuleBacktrackFailure()>
<label> = new CommonToken(input, Token.INVALID_TOKEN_TYPE, Token.DEFAULT_CHANNEL, <label>Start<elementIndex>, getCharIndex()-1);
<else>
$self->m_<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
<endif>
>>

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

/** EOF in the lexer */
lexerMatchEOF(label,elementIndex) ::= <<
<if(label)>
int <label>Start<elementIndex> = getCharIndex();
match(EOF); <checkRuleBacktrackFailure()>
<labelType> <label> = new CommonToken(input, EOF, Token.DEFAULT_CHANNEL, <label>Start<elementIndex>, getCharIndex()-1);
<else>
match(EOF); <checkRuleBacktrackFailure()>
<endif>
>>

/** match ^(root children) in tree parser */
tree(root, actionsAfterRoot, children, nullableChildList,
     enclosingTreeLevel, treeLevel) ::= <<
<root:element()>
<actionsAfterRoot:element()>
<if(nullableChildList)>
if ( input.LA(1)==Token.DOWN ) {
    match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
    <children:element()>
    match(input, Token.UP, null); <checkRuleBacktrackFailure()>
}
<else>
match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
<children:element()>
match(input, Token.UP, null); <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 new FailedPredicateException(input, "<ruleName>", "<description>");
}
>>

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

dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
my $LA<decisionNumber>_<stateNumber> = $self->input->LA(<k>);<\n>
<edges; separator="\nels">
else {
<if(eotPredictsAlt)>
    $alt<decisionNumber> = <eotPredictsAlt>;
<else>
    <ruleBacktrackFailure()>
    my $nvae =
        ANTLR::Runtime::NoViableAltException->new({
            grammar_decision_description => "<description>",
            decision_number => <decisionNumber>,
            state_number => <stateNumber>,
            input => $self->input,
        });<\n>
    <@noViableAltException()>
    croak $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) ::= <<
my $LA<decisionNumber>_<stateNumber> = $self->input->LA(<k>);<\n>
<edges; separator="\nels">
>>

/** 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) ::= <<
my $LA<decisionNumber>_<stateNumber> = $self->input->LA(<k>);<\n>
<edges; separator="\nels"><\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) ::= <<
switch ( $self->input->LA(<k>) ) {
    <edges; separator="\n">
    else {
    <if(eotPredictsAlt)>
        $alt<decisionNumber> = <eotPredictsAlt>;
    <else>
        <ruleBacktrackFailure()>
        my $nvae =
            ANTLR::Runtime::NoViableAltException->new({
                grammar_decision_description => "<description>",
                decision_number => <decisionNumber>,
                state_number => <stateNumber>,
                input => $self->input,
            });<\n>
        <@noViableAltException()>
        croak $nvae;<\n>
    <endif>
    }
}<\n>
>>

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

dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
switch ( $self->input->LA(<k>) ) {
<edges; separator="\n"><\n>
<if(eotPredictsAlt)>
else { $alt<decisionNumber> = <eotPredictsAlt> }<\n>
<endif>
}<\n>
>>

dfaEdgeSwitch(labels, targetState) ::= <<
case [<labels:{ <it> }; separator=", ">] { <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) ::= <<
Readonly my $DFA<dfa.decisionNumber>_eot => ANTLR::Runtime::DFA->unpack_rle([ <dfa.javaCompressedEOT; separator=", "> ]);
Readonly my $DFA<dfa.decisionNumber>_eof => ANTLR::Runtime::DFA->unpack_rle([ <dfa.javaCompressedEOF; separator=", "> ]);
Readonly my $DFA<dfa.decisionNumber>_min => ANTLR::Runtime::DFA->unpack_rle([ <dfa.javaCompressedMin; separator=", "> ]);
Readonly my $DFA<dfa.decisionNumber>_max => ANTLR::Runtime::DFA->unpack_rle([ <dfa.javaCompressedMax; separator=", "> ]);
Readonly my $DFA<dfa.decisionNumber>_accept => ANTLR::Runtime::DFA->unpack_rle([ <dfa.javaCompressedAccept; separator=", "> ]);
Readonly my $DFA<dfa.decisionNumber>_special => ANTLR::Runtime::DFA->unpack_rle([ <dfa.javaCompressedSpecial; separator=", "> ]);
Readonly my $DFA<dfa.decisionNumber>_transition => [ <dfa.javaCompressedTransition:{s|ANTLR::Runtime::DFA->unpack_rle([ <s; separator=", "> ])}; separator=", "> ];

{
package <name>::DFA<dfa.decisionNumber>;
use ANTLR::Runtime::Class;

use strict;
use warnings;

extends 'ANTLR::Runtime::DFA';

sub BUILD {
    my $self = shift;
    my $param_ref = __PACKAGE__->unpack_params(@_, {
        spec => [
            {
                name => 'recognizer',
                isa  => 'ANTLR::Runtime::BaseRecognizer'
            },
        ]
    });

    $self->recognizer($param_ref->{recognizer});
    $self->decision_number(<dfa.decisionNumber>);
    $self->eot($DFA<dfa.decisionNumber>_eot);
    $self->eof($DFA<dfa.decisionNumber>_eof);
    $self->min($DFA<dfa.decisionNumber>_min);
    $self->max($DFA<dfa.decisionNumber>_max);
    $self->accept($DFA<dfa.decisionNumber>_accept);
    $self->special($DFA<dfa.decisionNumber>_special);
    $self->transition($DFA<dfa.decisionNumber>_transition);
}

sub get_description {
    return "<dfa.description>";
}

<@errorMethod()>

<if(dfa.specialStateSTs)>
sub special_state_transition {
    my ($self, $param_ref) = unpack_params(@_, {
        spec => [
            {
                name => 's',
                type => SCALAR,
            },
            {
                name => 'input',
                isa  => 'ANTLR::Runtime::IntStream',
            }
        ]
    });
    my $s = $param_ref->{s};
    my $input = $param_ref->{input};

    switch ($s) {
        <dfa.specialStateSTs:{state |
        case <i0> \{ <! compressed special state numbers 0..n-1 !>
            <state>}; separator="\n">
        }
    }

<if(backtracking)>
    if ($self->state->backtracking > 0) {
        $self->state->failed = 1;
        return -1;
    }<\n>
<endif>

    my $nvae =
        ANTLR::Runtime::NoViableAltException->new({
            grammar_decision_description => $self->get_description(),
            decision_number => <dfa.decisionNumber>,
            state_number => $s,
            input => $input,
        });<\n>
    $self->error($nvae);
    $nvae->throw();
    }<\n>
<endif>
}<\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) ::= <<
my $input = $self->input;
my $LA<decisionNumber>_<stateNumber> = $input->LA(1);<\n>
<if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>
my $index<decisionNumber>_<stateNumber> = $input->index();
$input->rewind();<\n>
<endif>
s = -1;
<edges; separator="\nels">
<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) ::= <<
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>
>>


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

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

orPredicates(operands) ::= "(<operands; separator=\"||\">)"

notPredicate(pred) ::= "!(<evalPredicate(...)>)"

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

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

lookaheadTest(atom,k,atomAsInt) ::= "$LA<decisionNumber>_<stateNumber> eq <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>) eq <atom>"

lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <<
($LA<decisionNumber>_<stateNumber> ge <lower> && $LA<decisionNumber>_<stateNumber> le <upper>)
>>

isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "($self->input->LA(<k>) ge <lower> && $self->input->LA(<k>) le <upper>)"

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

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

globalAttributeScope(scope) ::= <<
<if(scope.attributes)>
protected static class <scope.name>_scope {
    <scope.attributes:{<it.decl>;}; separator="\n">
}
protected Stack <scope.name>_stack = new Stack();<\n>
<endif>
>>

ruleAttributeScope(scope) ::= <<
<if(scope.attributes)>
protected static class <scope.name>_scope {
    <scope.attributes:{<it.decl>;}; separator="\n">
}
protected Stack <scope.name>_stack = new Stack();<\n>
<endif>
>>

returnType() ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
<ruleDescriptor.name>_return
<else>
<if(ruleDescriptor.hasSingleReturnValue)>
<ruleDescriptor.singleValueReturnType>
<else>
void
<endif>
<endif>
>>

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

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

/** Define a rule label including default value */
ruleLabelDef(label) ::= <<
my $<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.
 */
returnScope(scope) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
{
    package <returnType()>;
    use ANTLR::Runtime::Class;

    extends 'ANTLR::Runtime::<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope';

    <scope.attributes:{public <it.decl>;}; separator="\n">
    <@ruleReturnMembers()>
}
<endif>
>>

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

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

scopeAttributeRef(scope,attr,index,negIndex) ::= <<
<if(negIndex)>
((<scope>_scope)<scope>_stack.elementAt(<scope>_stack.size()-<negIndex>-1)).<attr.name>
<else>
<if(index)>
((<scope>_scope)<scope>_stack.elementAt(<index>)).<attr.name>
<else>
((<scope>_scope)<scope>_stack.peek()).<attr.name>
<endif>
<endif>
>>

scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <<
<if(negIndex)>
((<scope>_scope)<scope>_stack.elementAt(<scope>_stack.size()-<negIndex>-1)).<attr.name> =<expr>;
<else>
<if(index)>
((<scope>_scope)<scope>_stack.elementAt(<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>.<attr.name>
<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

tokenLabelPropertyRef_text(scope,attr) ::= "$<scope>->get_text()"
tokenLabelPropertyRef_type(scope,attr) ::= "<scope>.getType()"
tokenLabelPropertyRef_line(scope,attr) ::= "<scope>.getLine()"
tokenLabelPropertyRef_pos(scope,attr) ::= "<scope>.getCharPositionInLine()"
tokenLabelPropertyRef_channel(scope,attr) ::= "<scope>.getChannel()"
tokenLabelPropertyRef_index(scope,attr) ::= "<scope>.getTokenIndex()"
tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"

ruleLabelPropertyRef_start(scope,attr) ::= "((<labelType>)<scope>.start)"
ruleLabelPropertyRef_stop(scope,attr) ::= "((<labelType>)<scope>.stop)"
ruleLabelPropertyRef_tree(scope,attr) ::= "((<ASTLabelType>)<scope>.tree)"
ruleLabelPropertyRef_text(scope,attr) ::= <<
<if(TREE_PARSER)>
input.getTokenStream().toString(
  input.getTreeAdaptor().getTokenStartIndex(<scope>.start),
  input.getTreeAdaptor().getTokenStopIndex(<scope>.start))
<else>
substr($self->input, $<scope>->start, $<scope>->stop)
<endif>
>>

ruleLabelPropertyRef_st(scope,attr) ::= "<scope>.st"

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

lexerRuleLabelPropertyRef_type(scope,attr) ::= "<scope>.getType()"
lexerRuleLabelPropertyRef_line(scope,attr) ::= "<scope>.getLine()"
lexerRuleLabelPropertyRef_pos(scope,attr) ::= "<scope>.getCharPositionInLine()"
lexerRuleLabelPropertyRef_channel(scope,attr) ::= "<scope>.getChannel()"
lexerRuleLabelPropertyRef_index(scope,attr) ::= "<scope>.getTokenIndex()"
lexerRuleLabelPropertyRef_text(scope,attr) ::= "<scope>.getText()"

// Somebody may ref $template or $tree or $stop within a rule:
rulePropertyRef_start(scope,attr) ::= "((<labelType>)retval.start)"
rulePropertyRef_stop(scope,attr) ::= "((<labelType>)retval.stop)"
rulePropertyRef_tree(scope,attr) ::= "((<ASTLabelType>)retval.tree)"
rulePropertyRef_text(scope,attr) ::= <<
<if(TREE_PARSER)>
input.getTokenStream().toString(
  input.getTreeAdaptor().getTokenStartIndex(retval.start),
  input.getTreeAdaptor().getTokenStopIndex(retval.start))
<else>
input.toString(retval.start,input.LT(-1))
<endif>
>>
rulePropertyRef_st(scope,attr) ::= "retval.st"

lexerRulePropertyRef_text(scope,attr) ::= "getText()"
lexerRulePropertyRef_type(scope,attr) ::= "$_type"
lexerRulePropertyRef_line(scope,attr) ::= "tokenStartLine"
lexerRulePropertyRef_pos(scope,attr) ::= "tokenStartCharPositionInLine"
lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
lexerRulePropertyRef_channel(scope,attr) ::= "$_channel"
lexerRulePropertyRef_start(scope,attr) ::= "tokenStartCharIndex"
lexerRulePropertyRef_stop(scope,attr) ::= "(getCharIndex()-1)"
lexerRulePropertyRef_self(scope,attr) ::= "$self"

// 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 */
execAction(action) ::= <<
<if(backtracking)>
<if(actions.(actionScope).synpredgate)>
if ( <actions.(actionScope).synpredgate> ) {
  <action>
}
<else>
if ( backtracking==0 ) {
  <action>
}
<endif>
<else>
<action>
<endif>
>>

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

bitset(name, words64) ::= <<
Readonly my $<name> => ANTLR::Runtime::BitSet->new({ words64 => [ <words64:{'<it>'};separator=", "> ] });<\n>
>>

codeFileExtension() ::= ".pm"

true() ::= "1"
false() ::= "0"
