/*
 [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.
*/
group Cpp;

cppTypeInitMap ::= [
	"int":"0",
	"long":"0",
	"float":"0.0",
	"double":"0.0",
	"bool":"false",
	"byte":"0",
	"short":"0",
	"char":"0",
	default:"0" // anything other than an atomic type
]

// What we generate lexer/parser/treeparser, used a suffix in a few places
generatedType() ::= <<
<if(LEXER)>Lexer<endif><if(PARSER)>Parser<endif><if(TREE_PARSER)>TreeParser<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><\n>
<endif>
<if(PARSER)>
 *     -                for the parser : <name><\n>
<endif>
<if(TREE_PARSER)>
 *     -           for the tree parser : <name><\n>
<endif>
 *
 *  Edit at your own peril.
 */
>>

standardHeaders() ::=
<<
#include \<antlr3/<generatedType()>.h>

<if(profile)>
#warning "No profiling support.."
<endif>
<if(TREE_PARSER)>
#warning "No tree parsing yet..."
<endif>
>>

/** 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, profile,
			  backtracking, synpreds, memoize, numRules,
			  fileName, ANTLRVersion, generatedTimestamp, trace,
			  scopes, superClass) ::=
<<
<leadIn("C++ source")>
<@includes>
#include "<name><headerFileExtension()>"
<@end>
<if(actions.(actionScope).header)>
// Header action start ========================================================
<actions.(actionScope).header>
// Header action end   ========================================================
<endif>

<headerAction>

<standardHeaders()>

<docComment>
<recognizer>
>>
parserHeaderFile() ::= <<
>>
treeParserHeaderFile() ::= <<
>>
lexerHeaderFile() ::= <<
template\<typename StreamType, typename TokenType, typename TokenBuilder>
class <name> : public antlr3::Lexer\<StreamType,TokenType,TokenBuilder> {
	// carry over general types
	typedef typename StreamType::position_type position_type;
	typedef typename StreamType::char_type char_type;

	typedef antlr3::tokenid_type               tokenid_type;
	typedef antlr3::channel_type               channel_type;
	typedef antlr3::decision_type              decision_type;
	// exception shorthands
	typedef antlr3::MismatchException\<position_type,char_type>        MismatchException;
	typedef antlr3::MismatchedRangeException\<position_type,char_type> MismatchedRangeException;
	typedef antlr3::MismatchedSetException\<position_type,char_type>   MismatchedSetException;
	typedef antlr3::EarlyExitException\<position_type>       EarlyExitException;
	typedef antlr3::NoViableAltException\<position_type>     NoViableAltException;
<if(backtracking)>
	// @TODO backtracking ruleMemo = new HashMap[<numRules>+1];<\n> <! index from 1..n !>
<endif>

public:
	<tokens:{static const tokenid_type <tokenPrefix()><it.name> = <it.type>;}; separator="\n">
	<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
	<actions.lexer.members>

	<name>(StreamType* input)
	: antlr3::Lexer\<StreamType,TokenType,TokenBuilder>(input)
	{
	}

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

	// syn preds
	<synpreds:{p | <lexerSynpred(p)>}>

	// cyclic dfa's
	<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this);}; separator="\n">
	// dfa tables..
}; // class <name><\n>
>>

headerFile( 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
        ) ::=
<<
#ifndef	_<name>_H
#define _<name>_H
<leadIn("C++ header")>
<actions.(actionScope).headerfile>

<@includes>
<standardHeaders()>
<@end>

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


#endif	// _<name>_H<\n>
>>

lexer(grammar, name, tokens, scopes, rules, numRules, labelType="Token",
      filterMode) ::= <<

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

>>

filteringNextToken() ::= <<
/** 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.
 */
public Token nextToken() {
	while (true) {
		if ( input.LA(1)==CharStream.EOF ) {
			return Token.EOF_TOKEN;
		}
		this->token = 0;
		tokenStartCharIndex = getCharIndex();
		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 {
				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;
}
>>

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

/** How to generate a parser */
genericParser(
	grammar, name, scopes, tokens, tokenNames, rules, numRules, cyclicDFAs,
	bitsets, inputStreamType, superClass, ASTLabelType="Object",
	labelType, members, filterMode
	) ::= <<
// genericParser
class <name> : public <@superClassName><superClass><@end> {
public:
	static const char* tokenNames[] = {
		"\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ">
	};
	<tokens:{static tokenid_type <tokenPrefix()><it.name>=<it.type>;}; separator="\n">
	<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
	<@members>

	<name>(StreamType* input)
	: <superClass>\<StreamType,TokenType>(input)
	{
<if(backtracking)>
		ruleMemo = new HashMap[<numRules>+1];<\n> <! index from 1..n !>
<endif>
	}
	<@end>

	//@TODO public String[] getTokenNames() { return tokenNames; }
	//@TODO public String getGrammarFileName() { return "<fileName>"; }
	<members>

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

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

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

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

parser(
	grammar, name, scopes, tokens, tokenNames,
	rules, numRules, bitsets, ASTLabelType,
	superClass="Parser", labelType="Token",
	members={<actions.parser.members>}) ::= <<
<genericParser(inputStreamType="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="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>
public void <ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) throws RecognitionException {
	<if(trace)>System.out.println("enter <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);<endif>
<if(trace)>
	try {
		<block>
	}
	finally {
		System.out.println("exit <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);
	}
<else>
	<block>
<endif>
}
// $ANTLR end <ruleName>
>>

synpred(name) ::= <<
public boolean <name>() {
    this->backtracking++;
    <@start()>
    int start = input.mark();
    try {
        <name>_fragment(); // can never throw exception
    } catch (RecognitionException re) {
        System.err.println("impossible: "+re);
    }
    boolean success = ! this->failed;
    input.rewind(start);
    <@stop()>
    this->backtracking--;
    this->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 (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,memoize) ::= <<
<ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
<returnScope(scope=ruleDescriptor.returnScope)>

// $ANTLR start <ruleName>
// <fileName>:<description>
public <returnType()> <ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) throw(antlr3::BaseRecognitionException)
{
<if(trace)>
	antlr3::Tracer trace(this,"<ruleName>");
	System.out.println("enter <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);
<endif>
	<ruleDeclarations()>
	<ruleLabelDefs()>
	<ruleDescriptor.actions.init>
	<@preamble()>
	try {
		<ruleMemoization(name=ruleName)>
		<block>
	}
<if(exceptions)>
	<exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
<else>
<if(!emptyRule)>
<if(actions.(actionScope).rulecatch)>
	<actions.(actionScope).rulecatch>
<else>
	catch (RecognitionException re) {
		reportError(re);
		recover(input,re);
	}<\n>
<endif>
<endif>
<endif>
	finally {
		<if(trace)>System.out.println("exit <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);<endif>
		<ruleCleanUp()>
		<(ruleDescriptor.actions.finally):execAction()>
	}
	<@postamble()>
	return <ruleReturnValue()>;
}
// $ANTLR end <ruleName>
>>

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

ruleDeclarations() ::= <<
<ruleDescriptor.useScopes:{<it>_stack.push(new <it>_scope());}; separator="\n">
<ruleDescriptor.ruleScope:{<it.name>_stack.push(new <it.name>_scope());}; separator="\n">
<if(ruleDescriptor.hasMultipleReturnValues)>
<returnType()> retval = new <returnType()>();
retval.start = 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)>
int <ruleDescriptor.name>_StartIndex = input.index();
<endif>
>>

ruleLabelDefs() ::= <<
<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels]
    :{<labelType> <it.label.text>=null;}; separator="\n"
>
<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]
    :{List list_<it.label.text>=null;}; separator="\n"
>
<[ruleDescriptor.ruleLabels,ruleDescriptor.ruleListLabels]
    :ruleLabelDef(label=it); separator="\n"
>
<[ruleDescriptor.allRuleRefsInAltsWithRewrites,ruleDescriptor.allTokenRefsInAltsWithRewrites]
    :{List list_<it>=new ArrayList();}; separator="\n"
>
>>

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

ruleCleanUp() ::= <<
<ruleDescriptor.useScopes:{<it>_stack.pop();}; separator="\n">
<ruleDescriptor.ruleScope:{<it.name>_stack.pop();}; separator="\n">
<if(ruleDescriptor.hasMultipleReturnValues)>
retval.stop = input.LT(-1);<\n>
<endif>
<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) ::= <<
void m<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) throw(antlr3::BaseRecognitionException)
{
<if(trace)>
	antlr3::Tracer trace(this,"<ruleName>");
<endif>
	antlr3::CountScope nestingTracker(this->ruleNestingLevel);
	StreamType& input(this->getInput());
<if(nakedBlock)>
	<ruleDescriptor.actions.init>
	<ruleMemoization(name=ruleName)>
	<block><\n>
<else>
	tokenid_type type = <tokenPrefix()><ruleName>;
	channel_type channel = antlr3::Token::DEFAULT_CHANNEL;
	position_type start(input.getPosition());
	<ruleDescriptor.actions.init>
	<ruleMemoization(name=ruleName)>
	<block>
	<! create token if none exists *and* we are an outermost token rule !>
	<execAction({if ( this->token == 0 && this->ruleNestingLevel == 1 ) {
	TokenType *tt = TokenBuilder::build(type,start,input,channel);
	std::cout \<\< (*tt) \<\< std::endl;
	this->emit(tt);
	}<\n>
})>
<endif>
}
>>

/** How to generate code for the implicitly-defined lexer grammar rule
 *  that chooses between lexer rules.
 */
tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
void mTokens() throw(antlr3::BaseRecognitionException)
{
	StreamType& input(this->getInput());
	<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) ::= <<
// block <fileName>:<description>
decision_type 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) ::= <<
// ruleBlock <fileName>:<description>
decision_type alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
switch (alt<decisionNumber>) {
    <alts:altSwitchCase()>
}
>>

ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
// ruleBlockSingleAlt <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 0 or more alternatives */
positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// positiveClosureBlock <fileName>:<description>
decision_type cnt<decisionNumber>=0;
<decls>
<@preloop()>
do {
	decision_type alt<decisionNumber>=<maxAlt>;
	<@predecision()>
	<decision>
	<@postdecision()>
	switch (alt<decisionNumber>) {
	<alts:altSwitchCase()>
	default :
		if ( cnt<decisionNumber> >= 1 )
			goto loop<decisionNumber>;
            EarlyExitException eee( input.getPosition(), <decisionNumber> );
				<@earlyExitException()>
            throw eee;
	}
	cnt<decisionNumber>++;
} while (true);
loop<decisionNumber>: ;
<@postloop()>
>>

positiveClosureBlockSingleAlt ::= positiveClosureBlock

/** A (..)* block with 1 or more alternatives */
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// closureBlock <fileName>:<description>
<decls>
<@preloop()>
do {
	decision_type alt<decisionNumber>=<maxAlt>;
	<@predecision()>
	<decision>
	<@postdecision()>
	switch (alt<decisionNumber>) {
	<alts:altSwitchCase()>
	default :
		goto loop<decisionNumber>;
	}
} while (true);
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>
	break;<\n>
>>

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

// E L E M E N T S

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

/** match a token optionally with a label in front */
tokenRef(token,label,elementIndex) ::= <<
// tokenRef
<if(label)>
<label> = input.LT(1);<\n>
<endif>
this->match(input,<token>,FOLLOW_<token>_in_<ruleName><elementIndex>);
<checkRuleBacktrackFailure()>
>>

/** ids+=ID no AST building */
tokenRefAndListLabel(token,label,elementIndex) ::= <<
<tokenRef(...)>
<listLabel(...)>
>>

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

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

/** match a character range */
charRangeRef(a,b) ::= "this->matchRange(<a>,<b>); <checkRuleBacktrackFailure()>"

/** For now, sets are interval tests and must be tested inline */
matchSet(s,label,elementIndex,postmatchCode="") ::= <<
// matchSet
<if(label)>
<label> = input.LT(1);<\n>
<endif>
if ( <s> )
{
	<postmatchCode>
	input.consume();
<if(!LEXER)>
	errorRecovery=false;
<endif>
	<if(backtracking)>failed=false;<endif>
}
else
{
	<ruleBacktrackFailure()>
	MismatchedSetException mse(input.getPosition(),input.LA(1));
	<@mismatchedSetException()>
<if(LEXER)>
	this->recover(mse);
<else>
	this->recoverFromMismatchedSet(input,mse,FOLLOW_set_in_<ruleName><elementIndex>);
<endif>
	throw mse;
}<\n>
>>

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

/** Match a string literal */
lexerStringRef(string,label,elementIndex) ::= <<
// lexerStringRef
<if(label)>
position_type <label>Start(input.getPosition());
this->match( <string> );
<checkRuleBacktrackFailure()>
TokenType* <label> = TokenBuilder::build(Token.INVALID_TOKEN_TYPE,<label>Start,input,Token.DEFAULT_CHANNEL);
<else>
this->match( <string> );
<checkRuleBacktrackFailure()><\n>
<endif>
>>

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

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

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

tokenid_type() ::= "<if(LEXER)>char_type<else>tokenid_type<endif>"

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

/** Match a rule reference by invoking it possibly with arguments
 *  and a return value or values.
 */
ruleRef(rule,label,elementIndex,args) ::= <<
following.push(FOLLOW_<rule>_in_<ruleName><elementIndex>);
<if(label)>
<label>=<rule>(<args>);<\n>
<else>
<rule>(<args>);<\n>
<endif>
following.pop();
<checkRuleBacktrackFailure()>
>>

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

/** A lexer rule reference */
lexerRuleRef(rule,label,args) ::= <<
<if(label)>
position_type <label>Start(input.getPosition());
m<rule>(<args>);
<checkRuleBacktrackFailure()>
TokenType* <label> = TokenBuilder::build(Token.INVALID_TOKEN_TYPE,<label>Start,input,Token.DEFAULT_CHANNEL);
<else>
m<rule>(<args>);
<checkRuleBacktrackFailure()>
<endif>
>>

/** EOF in the lexer */
lexerMatchEOF(label) ::= <<
<if(label)>
position_type <label>Start(input.getPosition());
match(EOF);
<checkRuleBacktrackFailure()>
TokenType* <label> = TokenBuilder::build(Token.EOF,<label>Start,input,Token.DEFAULT_CHANNEL);
<else>
match(EOF);
<checkRuleBacktrackFailure()>
<endif>
>>

/** match ^(root children) in tree parser */
tree(root, children, nullableChildList) ::= <<
<root:element()>
<if(nullableChildList)>
if ( input.LA(1)==antlr3::Token::DOWN ) {
    match(input, antlr3::Token::DOWN, null);
    <checkRuleBacktrackFailure()>
    <children:element()>
    match(input, antlr3::Token::UP, null);
    <checkRuleBacktrackFailure()>
}
<else>
match(input, antlr3::Token::DOWN, null);
<checkRuleBacktrackFailure()>
<children:element()>
match(input, antlr3::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) ::= <<
<if(!semPredState)>
<tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
<endif>
<edges; separator="\nelse ">
else
{
<if(eotPredictsAlt)>
	alt<decisionNumber> = <eotPredictsAlt>;<\n>
<else>
	<ruleBacktrackFailure()>
	NoViableAltException nvae(input.getPosition(), "<description>", <decisionNumber>, <stateNumber>);<\n>
	<@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) ::= <<
<if(!semPredState)>
<tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);
<endif>
<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) ::= <<
<if(!semPredState)>
<tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);
<endif>
<edges; separator="\nelse "><\n>
<if(eotPredictsAlt)>
else
{
	alt<decisionNumber> = <eotPredictsAlt>;
}<\n>
<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 ( input.LA(<k>) ) {
<edges; separator="\n">
default:
<if(eotPredictsAlt)>
	alt<decisionNumber> = <eotPredictsAlt>;
<else>
	NoViableAltException nvae( input.getPosition(), "<description>", <decisionNumber>, <stateNumber> );<\n>
	<@noViableAltException()>
	throw nvae;<\n>
<endif>
}<\n>
>>

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

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

dfaEdgeSwitch(labels, targetState) ::= <<
<labels:{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) ::= <<
// dfaDecision
alt<decisionNumber> = predictDFA<decisionNumber>(input);
>>

/** The overall cyclic DFA chunk; contains all the DFA states */
cyclicDFA(dfa) ::= <<
/* cyclicDFA=<dfa>
*/
// cyclic    = <dfa.cyclic>
// numstates = <dfa.numberOfStates>

// startState = <dfa.startState>
// startState.numberOfTransitions = <dfa.startState.NumberOfTransitions>
// startState.lookaheadDepth = <dfa.startState.LookaheadDepth>

const static short <name>dfa<dfa.decisionNumber>_eot[<dfa.numberOfStates>] = {
	<dfa.eot; wrap="\n     ", separator=",", null="-1">
};
const static short <name>dfa<dfa.decisionNumber>_eof[<dfa.numberOfStates>] = {
	<dfa.eof; wrap="\n     ", separator=",", null="-1">
};
const static unichar <name>dfa<dfa.decisionNumber>_min[<dfa.numberOfStates>] = {
	<dfa.min; wrap="\n     ", separator=",", null="0">
};
const static unichar <name>dfa<dfa.decisionNumber>_max[<dfa.numberOfStates>] = {
	<dfa.max; wrap="\n     ", separator=",", null="0">
};
const static short <name>dfa<dfa.decisionNumber>_accept[<dfa.numberOfStates>] = {
	<dfa.accept; wrap="\n     ", separator=",", null="-1">
};
const static short <name>dfa<dfa.decisionNumber>_special[<dfa.numberOfStates>] = {
	<dfa.special; wrap="\n     ", separator=",", null="-1">
};
<dfa.edgeTransitionClassMap.keys:{ table |
const static short <name>dfa<dfa.decisionNumber>_transition<i0>[] = {
	<table; separator=", ", wrap="\n	", null="-1">
};
}; null="">
const static short <name>dfa<dfa.decisionNumber>_transition[] = {
	<dfa.transitionEdgeTables:{whichTable|<name>dfa<dfa.decisionNumber>_transition<whichTable>,}; separator="\n", null="0 /* fixme? */">
};
	<! add attribute for the DFA !>
	DFA\<char_type> dfa<dfa.decisionNumber>;
<! this should go in the initializer of the thing
- (id) init
{
	if ((self = [super init]) != nil) {
		eot = <name>dfa<dfa.decisionNumber>_eot;
		eof = <name>dfa<dfa.decisionNumber>_eof;
		min = <name>dfa<dfa.decisionNumber>_min;
		max = <name>dfa<dfa.decisionNumber>_max;
		accept = <name>dfa<dfa.decisionNumber>_accept;
		special = <name>dfa<dfa.decisionNumber>_special;
		if (!(transition = calloc(<dfa.numberOfStates>, sizeof(void*)))) {
			[self release];
			return nil;
		}
		<dfa.transitionEdgeTables:{whichTable|transition[<i0>] = <name>dfa<dfa.decisionNumber>_transition<whichTable>;}; separator="\n", null="">
	}
	return self;
}
!>

<if(dfa.specialStateSTs)>
int specialStateTransition( int state )
{
	int s = state;
	switch ( s ) {
 		<dfa.specialStateSTs:{state |
		case <i0> : <! compressed special state numbers 0..n-1 !>
		<state>}; separator="\n">
	}
<if(backtracking)>
	if ( recognizer.isBacktracking() ) {
		recognizer.setFailed();
		return -1;
	}<\n>
<endif>
	noViableAlt(s, input);
}<\n>
<endif>


<\n>

// <dfa.description>
decision_type predictDFA<dfa.decisionNumber>( StreamType& input )
{
	/* mark current location (rewind automatically when the rewinder goes
	 * out of scope */
	antlr3::Rewinder\<position_type> markPoint(input.getPosition());
	goto s0;	// goto start...
	// ...
	throw NoViableAltException( input.getPosition(), "<dfa.description>", <dfa.decisionNumber>, 0 /* fixme */ );<\n>
}<\n>
>>

/** A state in a cyclic DFA */
cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<
// cyclicDFAState
s<stateNumber>: {
	<if(semPredState)>
	input.rewind();<\n>
	<else>
	<tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(1);
	<endif>
	<edges>
	<if(needErrorClause)>
	throw NoViableAltException( input.getPosition(), "<description>", <decisionNumber>, <stateNumber> );<\n>
	<endif><\n>
}<\n>
>>

/** 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>)
{
	input.consume();
	goto s<targetStateNumber>;
}<\n>
>>

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

// 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) ::= "!(<pred>)"

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

evalSynPredicate(pred,description) ::= "<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

globalAttributeScope(scope) ::= <<
<if(scope.attributes)>
protected static class <scope.name> {
    <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.singleValueReturnType)>
<ruleDescriptor.singleValueReturnType>
<else>
void
<endif>
<endif>
>>

ruleLabelType(referencedRule) ::= <<
<if(referencedRule.hasMultipleReturnValues)>
<referencedRule.name>_return
<else>
<if(referencedRule.singleValueReturnType)>
<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 "null".
 */
initValue(typeName) ::= <<
<javaTypeInitMap.(typeName)>
>>

ruleLabelDef(label) ::= <<
<ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n>
>>

returnScope(scope) ::= <<
<if(ruleDescriptor.hasMultipleReturnValues)>
public static class <returnType()> {
    <labelType> start, stop;
<if(buildAST)>
    <ASTLabelType> tree;
<else>
<if(buildTemplate)>
    StringTemplate st;
<endif>
<endif>
    <scope.attributes:{<it.decl>;}; separator="\n">
};
<endif>
>>

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

/** Used in codegen.g to translate $x.y references.
 *  I could have left actions as StringTemplates to be inserted in
 *  the output (so they could use attributes inherited from surrounding
 *  templates), but really wanted to pass in AttributeScope and Attribute
 *  objects so this translation could query them.  So, translation of
 *  $x.y to executable code occurs before recognizerST.toString() occurs.
 *  I.e., actions are just text strings during final code generation.
 */
globalAttributeRef(scope,attr) ::= <<
((<scope>)<scope>_stack.peek()).<attr.name>
>>

parameterAttributeRef(attr) ::= "<attr.name>"

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>
>>

/** $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.singleValueReturnType)>
<scope>
<else>
<scope>.<attr.name>
<endif>
>>

returnAttributeRef(ruleDescriptor,attr) ::= <<
<if(ruleDescriptor.singleValueReturnType)>
<attr.name>
<else>
retval.<attr.name>
<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>.getText()"
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) ::= "<scope>.start"
ruleLabelPropertyRef_stop(scope,attr) ::= "<scope>.stop"
ruleLabelPropertyRef_tree(scope,attr) ::= "<scope>.tree"
ruleLabelPropertyRef_text(scope,attr) ::= "input.toString(<scope>.start,<scope>.stop)"
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) ::= "input.toString(retval.start,input.LT(-1))"
rulePropertyRef_st(scope,attr) ::= "retval.st"

// A C T I O N S

emit(type) ::= "emit(<type>);"

setType(type) ::= "setType(<type>);"

/** 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) ::= <<
public static final BitSet <name> = new BitSet(new long[]{<words64:{<it>L};separator=",">});<\n>
>>

tokenPrefix() ::= "TOK_"
codeFileExtension() ::= ".cpp"
// used in CPPTarget.java to generate the headerfile extension
headerFileExtension() ::= ".h"

true() ::= "true"
false() ::= "false"
