Home | History | Annotate | Download | only in CPP
      1 /*
      2  [The "BSD license"]
      3  Copyright (c) 2005-2006 Terence Parr
      4  All rights reserved.
      5 
      6  Redistribution and use in source and binary forms, with or without
      7  modification, are permitted provided that the following conditions
      8  are met:
      9  1. Redistributions of source code must retain the above copyright
     10     notice, this list of conditions and the following disclaimer.
     11  2. Redistributions in binary form must reproduce the above copyright
     12     notice, this list of conditions and the following disclaimer in the
     13     documentation and/or other materials provided with the distribution.
     14  3. The name of the author may not be used to endorse or promote products
     15     derived from this software without specific prior written permission.
     16 
     17  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 group Cpp;
     29 
     30 cppTypeInitMap ::= [
     31 	"int":"0",
     32 	"long":"0",
     33 	"float":"0.0",
     34 	"double":"0.0",
     35 	"bool":"false",
     36 	"byte":"0",
     37 	"short":"0",
     38 	"char":"0",
     39 	default:"0" // anything other than an atomic type
     40 ]
     41 
     42 // What we generate lexer/parser/treeparser, used a suffix in a few places
     43 generatedType() ::= <<
     44 <if(LEXER)>Lexer<endif><if(PARSER)>Parser<endif><if(TREE_PARSER)>TreeParser<endif>
     45 >>
     46 
     47 leadIn(type) ::=
     48 <<
     49 /** \file
     50  *
     51  *  This <type> file was generated by ANTLR version <ANTLRVersion>
     52  *
     53  *     -  From the grammar source file : <fileName>
     54  *     -                            On : <generatedTimestamp>
     55 <if(LEXER)>
     56  *     -                 for the lexer : <name><\n>
     57 <endif>
     58 <if(PARSER)>
     59  *     -                for the parser : <name><\n>
     60 <endif>
     61 <if(TREE_PARSER)>
     62  *     -           for the tree parser : <name><\n>
     63 <endif>
     64  *
     65  *  Edit at your own peril.
     66  */
     67 >>
     68 
     69 standardHeaders() ::=
     70 <<
     71 #include \<antlr3/<generatedType()>.h>
     72 
     73 <if(profile)>
     74 #warning "No profiling support.."
     75 <endif>
     76 <if(TREE_PARSER)>
     77 #warning "No tree parsing yet..."
     78 <endif>
     79 >>
     80 
     81 /** The overall file structure of a recognizer; stores methods for rules
     82  *  and cyclic DFAs plus support code.
     83  */
     84 outputFile(LEXER,PARSER,TREE_PARSER, actionScope, actions,
     85 			  docComment, recognizer,
     86 			  name, tokens, tokenNames, rules, cyclicDFAs,
     87 			  bitsets, buildTemplate, profile,
     88 			  backtracking, synpreds, memoize, numRules,
     89 			  fileName, ANTLRVersion, generatedTimestamp, trace,
     90 			  scopes, superClass) ::=
     91 <<
     92 <leadIn("C++ source")>
     93 <@includes>
     94 #include "<name><headerFileExtension()>"
     95 <@end>
     96 <if(actions.(actionScope).header)>
     97 // Header action start ========================================================
     98 <actions.(actionScope).header>
     99 // Header action end   ========================================================
    100 <endif>
    101 
    102 <headerAction>
    103 
    104 <standardHeaders()>
    105 
    106 <docComment>
    107 <recognizer>
    108 >>
    109 parserHeaderFile() ::= <<
    110 >>
    111 treeParserHeaderFile() ::= <<
    112 >>
    113 lexerHeaderFile() ::= <<
    114 template\<typename StreamType, typename TokenType, typename TokenBuilder>
    115 class <name> : public antlr3::Lexer\<StreamType,TokenType,TokenBuilder> {
    116 	// carry over general types
    117 	typedef typename StreamType::position_type position_type;
    118 	typedef typename StreamType::char_type char_type;
    119 
    120 	typedef antlr3::tokenid_type               tokenid_type;
    121 	typedef antlr3::channel_type               channel_type;
    122 	typedef antlr3::decision_type              decision_type;
    123 	// exception shorthands
    124 	typedef antlr3::MismatchException\<position_type,char_type>        MismatchException;
    125 	typedef antlr3::MismatchedRangeException\<position_type,char_type> MismatchedRangeException;
    126 	typedef antlr3::MismatchedSetException\<position_type,char_type>   MismatchedSetException;
    127 	typedef antlr3::EarlyExitException\<position_type>       EarlyExitException;
    128 	typedef antlr3::NoViableAltException\<position_type>     NoViableAltException;
    129 <if(backtracking)>
    130 	// @TODO backtracking ruleMemo = new HashMap[<numRules>+1];<\n> <! index from 1..n !>
    131 <endif>
    132 
    133 public:
    134 	<tokens:{static const tokenid_type <tokenPrefix()><it.name> = <it.type>;}; separator="\n">
    135 	<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
    136 	<actions.lexer.members>
    137 
    138 	<name>(StreamType* input)
    139 	: antlr3::Lexer\<StreamType,TokenType,TokenBuilder>(input)
    140 	{
    141 	}
    142 
    143 <!if(filterMode)!>
    144     <!filteringNextToken()!>
    145 <!endif!>
    146 	<rules; separator="\n\n">
    147 
    148 	// syn preds
    149 	<synpreds:{p | <lexerSynpred(p)>}>
    150 
    151 	// cyclic dfa's
    152 	<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this);}; separator="\n">
    153 	// dfa tables..
    154 }; // class <name><\n>
    155 >>
    156 
    157 headerFile( LEXER,
    158             PARSER,
    159             TREE_PARSER,
    160             actionScope,
    161             actions,
    162             docComment,
    163             recognizer,
    164             name,
    165             tokens,
    166             tokenNames,
    167             rules,
    168             cyclicDFAs,
    169             bitsets,
    170             buildTemplate,
    171             profile,
    172             backtracking,
    173             synpreds,
    174             memoize,
    175             numRules,
    176             fileName,
    177             ANTLRVersion,
    178             generatedTimestamp,
    179             trace,
    180             scopes,
    181             superClass
    182         ) ::=
    183 <<
    184 #ifndef	_<name>_H
    185 #define _<name>_H
    186 <leadIn("C++ header")>
    187 <actions.(actionScope).headerfile>
    188 
    189 <@includes>
    190 <standardHeaders()>
    191 <@end>
    192 
    193 <if(LEXER)>
    194 <lexerHeaderFile()>
    195 <endif>
    196 <if(PARSER)>
    197 <parserHeaderFile()>
    198 <endif>
    199 <if(TREE_PARSER)>
    200 <treeParserHeaderFile()>
    201 <endif>
    202 
    203 
    204 #endif	// _<name>_H<\n>
    205 >>
    206 
    207 lexer(grammar, name, tokens, scopes, rules, numRules, labelType="Token",
    208       filterMode) ::= <<
    209 
    210 <cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>
    211 
    212 >>
    213 
    214 filteringNextToken() ::= <<
    215 /** A override of Lexer.nextToken() that backtracks over mTokens() looking
    216  *  for matches.  No error can be generated upon error; just rewind, consume
    217  *  a token and then try again.  backtracking needs to be set as well.
    218  *  Make rule memoization happen only at levels above 1 as we start mTokens
    219  *  at backtracking==1.
    220  */
    221 public Token nextToken() {
    222 	while (true) {
    223 		if ( input.LA(1)==CharStream.EOF ) {
    224 			return Token.EOF_TOKEN;
    225 		}
    226 		this->token = 0;
    227 		tokenStartCharIndex = getCharIndex();
    228 		try {
    229 			int m = input.mark();
    230 			backtracking=1; <! means we won't throw slow exception !>
    231 			failed=false;
    232 			mTokens();
    233 			backtracking=0;
    234 			<! mTokens backtracks with synpred at backtracking==2
    235 				and we set the synpredgate to allow actions at level 1. !>
    236 			if ( failed ) {
    237 				input.rewind(m);
    238 				input.consume(); <! advance one char and try again !>
    239 			}
    240 			else {
    241 				return token;
    242 			}
    243 		}
    244 		catch (RecognitionException re) {
    245 			// shouldn't happen in backtracking mode, but...
    246 			reportError(re);
    247 			recover(re);
    248 		}
    249 	}
    250 }
    251 
    252 public void memoize(IntStream input, int ruleIndex, int ruleStartIndex)
    253 {
    254 	if ( backtracking > 1 )
    255 		super.memoize(input, ruleIndex, ruleStartIndex);
    256 }
    257 
    258 public boolean alreadyParsedRule(IntStream input, int ruleIndex)
    259 {
    260 	if ( backtracking > 1 )
    261 		return super.alreadyParsedRule(input, ruleIndex);
    262 	return false;
    263 }
    264 >>
    265 
    266 filteringActionGate() ::= "backtracking == 1"
    267 
    268 /** How to generate a parser */
    269 genericParser(
    270 	grammar, name, scopes, tokens, tokenNames, rules, numRules, cyclicDFAs,
    271 	bitsets, inputStreamType, superClass, ASTLabelType="Object",
    272 	labelType, members, filterMode
    273 	) ::= <<
    274 // genericParser
    275 class <name> : public <@superClassName><superClass><@end> {
    276 public:
    277 	static const char* tokenNames[] = {
    278 		"\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ">
    279 	};
    280 	<tokens:{static tokenid_type <tokenPrefix()><it.name>=<it.type>;}; separator="\n">
    281 	<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
    282 	<@members>
    283 
    284 	<name>(StreamType* input)
    285 	: <superClass>\<StreamType,TokenType>(input)
    286 	{
    287 <if(backtracking)>
    288 		ruleMemo = new HashMap[<numRules>+1];<\n> <! index from 1..n !>
    289 <endif>
    290 	}
    291 	<@end>
    292 
    293 	//@TODO public String[] getTokenNames() { return tokenNames; }
    294 	//@TODO public String getGrammarFileName() { return "<fileName>"; }
    295 	<members>
    296 
    297 	<rules; separator="\n\n">
    298 
    299 	<synpreds:{p | <synpred(p)>}>
    300 
    301 	<cyclicDFAs:{dfa | protected DFA<dfa.decisionNumber> dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this);}; separator="\n">
    302 	<cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>
    303 
    304 	<bitsets:bitset(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>},
    305 							words64=it.bits)>
    306 };
    307 >>
    308 
    309 parser(
    310 	grammar, name, scopes, tokens, tokenNames,
    311 	rules, numRules, bitsets, ASTLabelType,
    312 	superClass="Parser", labelType="Token",
    313 	members={<actions.parser.members>}) ::= <<
    314 <genericParser(inputStreamType="TokenStream", ...)>
    315 >>
    316 
    317 /** How to generate a tree parser; same as parser except the input
    318  *  stream is a different type.
    319  */
    320 treeParser(grammar, name, scopes, tokens, tokenNames, globalAction,
    321 	rules, numRules,
    322 	bitsets,
    323 	labelType={<ASTLabelType>}, ASTLabelType="Object",
    324 	superClass="TreeParser", members={<actions.treeparser.members>}, filterMode
    325 	) ::= <<
    326 <genericParser(inputStreamType="TreeNodeStream", ...)>
    327 >>
    328 
    329 /** A simpler version of a rule template that is specific to the imaginary
    330  *  rules created for syntactic predicates.  As they never have return values
    331  *  nor parameters etc..., just give simplest possible method.  Don't do
    332  *  any of the normal memoization stuff in here either; it's a waste.
    333  *  As predicates cannot be inlined into the invoking rule, they need to
    334  *  be in a rule by themselves.
    335  */
    336 synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::=
    337 <<
    338 // $ANTLR start <ruleName>
    339 public void <ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) throws RecognitionException {
    340 	<if(trace)>System.out.println("enter <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);<endif>
    341 <if(trace)>
    342 	try {
    343 		<block>
    344 	}
    345 	finally {
    346 		System.out.println("exit <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);
    347 	}
    348 <else>
    349 	<block>
    350 <endif>
    351 }
    352 // $ANTLR end <ruleName>
    353 >>
    354 
    355 synpred(name) ::= <<
    356 public boolean <name>() {
    357     this->backtracking++;
    358     <@start()>
    359     int start = input.mark();
    360     try {
    361         <name>_fragment(); // can never throw exception
    362     } catch (RecognitionException re) {
    363         System.err.println("impossible: "+re);
    364     }
    365     boolean success = ! this->failed;
    366     input.rewind(start);
    367     <@stop()>
    368     this->backtracking--;
    369     this->failed = false;
    370     return success;
    371 }<\n>
    372 >>
    373 
    374 lexerSynpred(name) ::= <<
    375 <synpred(name)>
    376 >>
    377 
    378 ruleMemoization(name) ::= <<
    379 <if(memoize)>
    380 if ( backtracking > 0 && alreadyParsedRule(input, <ruleDescriptor.index>) )
    381 	return <ruleReturnValue()>;
    382 <endif>
    383 >>
    384 
    385 /** How to test for failure and return from rule */
    386 checkRuleBacktrackFailure() ::= <<
    387 <if(backtracking)>
    388 if (failed)
    389 	return <ruleReturnValue()>;
    390 <endif>
    391 >>
    392 
    393 /** This rule has failed, exit indicating failure during backtrack */
    394 ruleBacktrackFailure() ::= <<
    395 <if(backtracking)>
    396 if (backtracking > 0)
    397 {
    398 	failed = true;
    399 	return <ruleReturnValue()>;
    400 }
    401 <endif>
    402 >>
    403 
    404 /** How to generate code for a rule.  This includes any return type
    405  *  data aggregates required for multiple return values.
    406  */
    407 rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,memoize) ::= <<
    408 <ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
    409 <returnScope(scope=ruleDescriptor.returnScope)>
    410 
    411 // $ANTLR start <ruleName>
    412 // <fileName>:<description>
    413 public <returnType()> <ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) throw(antlr3::BaseRecognitionException)
    414 {
    415 <if(trace)>
    416 	antlr3::Tracer trace(this,"<ruleName>");
    417 	System.out.println("enter <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);
    418 <endif>
    419 	<ruleDeclarations()>
    420 	<ruleLabelDefs()>
    421 	<ruleDescriptor.actions.init>
    422 	<@preamble()>
    423 	try {
    424 		<ruleMemoization(name=ruleName)>
    425 		<block>
    426 	}
    427 <if(exceptions)>
    428 	<exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
    429 <else>
    430 <if(!emptyRule)>
    431 <if(actions.(actionScope).rulecatch)>
    432 	<actions.(actionScope).rulecatch>
    433 <else>
    434 	catch (RecognitionException re) {
    435 		reportError(re);
    436 		recover(input,re);
    437 	}<\n>
    438 <endif>
    439 <endif>
    440 <endif>
    441 	finally {
    442 		<if(trace)>System.out.println("exit <ruleName> "+input.LT(1)+" failed="+failed+" backtracking="+backtracking);<endif>
    443 		<ruleCleanUp()>
    444 		<(ruleDescriptor.actions.finally):execAction()>
    445 	}
    446 	<@postamble()>
    447 	return <ruleReturnValue()>;
    448 }
    449 // $ANTLR end <ruleName>
    450 >>
    451 
    452 catch(decl,action) ::= <<
    453 catch (<e.decl>) {
    454     <e.action>
    455 }
    456 >>
    457 
    458 ruleDeclarations() ::= <<
    459 <ruleDescriptor.useScopes:{<it>_stack.push(new <it>_scope());}; separator="\n">
    460 <ruleDescriptor.ruleScope:{<it.name>_stack.push(new <it.name>_scope());}; separator="\n">
    461 <if(ruleDescriptor.hasMultipleReturnValues)>
    462 <returnType()> retval = new <returnType()>();
    463 retval.start = input.LT(1);<\n>
    464 <else>
    465 <ruleDescriptor.returnScope.attributes:{ a |
    466 <a.type> <a.name> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
    467 }>
    468 <endif>
    469 <if(memoize)>
    470 int <ruleDescriptor.name>_StartIndex = input.index();
    471 <endif>
    472 >>
    473 
    474 ruleLabelDefs() ::= <<
    475 <[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels]
    476     :{<labelType> <it.label.text>=null;}; separator="\n"
    477 >
    478 <[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]
    479     :{List list_<it.label.text>=null;}; separator="\n"
    480 >
    481 <[ruleDescriptor.ruleLabels,ruleDescriptor.ruleListLabels]
    482     :ruleLabelDef(label=it); separator="\n"
    483 >
    484 <[ruleDescriptor.allRuleRefsInAltsWithRewrites,ruleDescriptor.allTokenRefsInAltsWithRewrites]
    485     :{List list_<it>=new ArrayList();}; separator="\n"
    486 >
    487 >>
    488 
    489 ruleReturnValue() ::= <<
    490 <if(!ruleDescriptor.isSynPred)>
    491 <if(ruleDescriptor.hasReturnValue)>
    492 <if(ruleDescriptor.hasSingleReturnValue)>
    493 <ruleDescriptor.singleValueReturnName>
    494 <else>
    495 retval
    496 <endif>
    497 <endif>
    498 <endif>
    499 >>
    500 
    501 ruleCleanUp() ::= <<
    502 <ruleDescriptor.useScopes:{<it>_stack.pop();}; separator="\n">
    503 <ruleDescriptor.ruleScope:{<it.name>_stack.pop();}; separator="\n">
    504 <if(ruleDescriptor.hasMultipleReturnValues)>
    505 retval.stop = input.LT(-1);<\n>
    506 <endif>
    507 <if(memoize)>
    508 <if(backtracking)>
    509 if ( backtracking > 0 ) { memoize(input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex); }
    510 <endif>
    511 <endif>
    512 >>
    513 
    514 /** How to generate a rule in the lexer; naked blocks are used for
    515  *  fragment rules.
    516  */
    517 lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= <<
    518 void m<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>) throw(antlr3::BaseRecognitionException)
    519 {
    520 <if(trace)>
    521 	antlr3::Tracer trace(this,"<ruleName>");
    522 <endif>
    523 	antlr3::CountScope nestingTracker(this->ruleNestingLevel);
    524 	StreamType& input(this->getInput());
    525 <if(nakedBlock)>
    526 	<ruleDescriptor.actions.init>
    527 	<ruleMemoization(name=ruleName)>
    528 	<block><\n>
    529 <else>
    530 	tokenid_type type = <tokenPrefix()><ruleName>;
    531 	channel_type channel = antlr3::Token::DEFAULT_CHANNEL;
    532 	position_type start(input.getPosition());
    533 	<ruleDescriptor.actions.init>
    534 	<ruleMemoization(name=ruleName)>
    535 	<block>
    536 	<! create token if none exists *and* we are an outermost token rule !>
    537 	<execAction({if ( this->token == 0 && this->ruleNestingLevel == 1 ) {
    538 	TokenType *tt = TokenBuilder::build(type,start,input,channel);
    539 	std::cout \<\< (*tt) \<\< std::endl;
    540 	this->emit(tt);
    541 	}<\n>
    542 })>
    543 <endif>
    544 }
    545 >>
    546 
    547 /** How to generate code for the implicitly-defined lexer grammar rule
    548  *  that chooses between lexer rules.
    549  */
    550 tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
    551 void mTokens() throw(antlr3::BaseRecognitionException)
    552 {
    553 	StreamType& input(this->getInput());
    554 	<block><\n>
    555 }
    556 >>
    557 
    558 // S U B R U L E S
    559 
    560 /** A (...) subrule with multiple alternatives */
    561 block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,
    562 	maxK,maxAlt,description) ::= <<
    563 // block <fileName>:<description>
    564 decision_type alt<decisionNumber>=<maxAlt>;
    565 <decls>
    566 <@predecision()>
    567 <decision>
    568 <@postdecision()>
    569 <@prebranch()>
    570 switch (alt<decisionNumber>) {
    571     <alts:altSwitchCase()>
    572 }
    573 <@postbranch()>
    574 >>
    575 
    576 /** A rule block with multiple alternatives */
    577 ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    578 // ruleBlock <fileName>:<description>
    579 decision_type alt<decisionNumber>=<maxAlt>;
    580 <decls>
    581 <@predecision()>
    582 <decision>
    583 <@postdecision()>
    584 switch (alt<decisionNumber>) {
    585     <alts:altSwitchCase()>
    586 }
    587 >>
    588 
    589 ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
    590 // ruleBlockSingleAlt <fileName>:<description>
    591 <decls>
    592 <@prealt()>
    593 <alts>
    594 <@postalt()>
    595 >>
    596 
    597 /** A special case of a (...) subrule with a single alternative */
    598 blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
    599 // <fileName>:<description>
    600 <decls>
    601 <@prealt()>
    602 <alts>
    603 <@postalt()>
    604 >>
    605 
    606 /** A (..)+ block with 0 or more alternatives */
    607 positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    608 // positiveClosureBlock <fileName>:<description>
    609 decision_type cnt<decisionNumber>=0;
    610 <decls>
    611 <@preloop()>
    612 do {
    613 	decision_type alt<decisionNumber>=<maxAlt>;
    614 	<@predecision()>
    615 	<decision>
    616 	<@postdecision()>
    617 	switch (alt<decisionNumber>) {
    618 	<alts:altSwitchCase()>
    619 	default :
    620 		if ( cnt<decisionNumber> >= 1 )
    621 			goto loop<decisionNumber>;
    622             EarlyExitException eee( input.getPosition(), <decisionNumber> );
    623 				<@earlyExitException()>
    624             throw eee;
    625 	}
    626 	cnt<decisionNumber>++;
    627 } while (true);
    628 loop<decisionNumber>: ;
    629 <@postloop()>
    630 >>
    631 
    632 positiveClosureBlockSingleAlt ::= positiveClosureBlock
    633 
    634 /** A (..)* block with 1 or more alternatives */
    635 closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    636 // closureBlock <fileName>:<description>
    637 <decls>
    638 <@preloop()>
    639 do {
    640 	decision_type alt<decisionNumber>=<maxAlt>;
    641 	<@predecision()>
    642 	<decision>
    643 	<@postdecision()>
    644 	switch (alt<decisionNumber>) {
    645 	<alts:altSwitchCase()>
    646 	default :
    647 		goto loop<decisionNumber>;
    648 	}
    649 } while (true);
    650 loop<decisionNumber>: ;
    651 <@postloop()>
    652 >>
    653 
    654 closureBlockSingleAlt ::= closureBlock
    655 
    656 /** Optional blocks (x)? are translated to (x|) by before code generation
    657  *  so we can just use the normal block template
    658  */
    659 optionalBlock ::= block
    660 
    661 optionalBlockSingleAlt ::= block
    662 
    663 /** A case in a switch that jumps to an alternative given the alternative
    664  *  number.  A DFA predicts the alternative and then a simple switch
    665  *  does the jump to the code that actually matches that alternative.
    666  */
    667 altSwitchCase() ::= <<
    668 case <i> :
    669 	<@prealt()>
    670 	<it>
    671 	break;<\n>
    672 >>
    673 
    674 /** An alternative is just a list of elements; at outermost level */
    675 alt(elements,altNum,description,autoAST,outerAlt) ::= <<
    676 // alt <fileName>:<description>
    677 {
    678 	<@declarations()>
    679 	<elements:element()>
    680 	<@cleanup()>
    681 }
    682 >>
    683 
    684 // E L E M E N T S
    685 
    686 /** Dump the elements one per line */
    687 element() ::= <<
    688 // element <fileName>:<description>
    689 <@prematch()>
    690 <it.el><\n>
    691 >>
    692 
    693 /** match a token optionally with a label in front */
    694 tokenRef(token,label,elementIndex) ::= <<
    695 // tokenRef
    696 <if(label)>
    697 <label> = input.LT(1);<\n>
    698 <endif>
    699 this->match(input,<token>,FOLLOW_<token>_in_<ruleName><elementIndex>);
    700 <checkRuleBacktrackFailure()>
    701 >>
    702 
    703 /** ids+=ID no AST building */
    704 tokenRefAndListLabel(token,label,elementIndex) ::= <<
    705 <tokenRef(...)>
    706 <listLabel(...)>
    707 >>
    708 
    709 listLabel(label) ::= <<
    710 if (list_<label>==null) list_<label>=new ArrayList();
    711 list_<label>.add(<label>);<\n>
    712 >>
    713 
    714 /** match a character */
    715 charRef(char,label) ::= <<
    716 // charRef
    717 <if(label)>
    718 <tokenid_type()> <label> = input.LA(1);<\n>
    719 <endif>
    720 this->match(<char>);
    721 <checkRuleBacktrackFailure()>
    722 >>
    723 
    724 /** match a character range */
    725 charRangeRef(a,b) ::= "this->matchRange(<a>,<b>); <checkRuleBacktrackFailure()>"
    726 
    727 /** For now, sets are interval tests and must be tested inline */
    728 matchSet(s,label,elementIndex,postmatchCode="") ::= <<
    729 // matchSet
    730 <if(label)>
    731 <label> = input.LT(1);<\n>
    732 <endif>
    733 if ( <s> )
    734 {
    735 	<postmatchCode>
    736 	input.consume();
    737 <if(!LEXER)>
    738 	errorRecovery=false;
    739 <endif>
    740 	<if(backtracking)>failed=false;<endif>
    741 }
    742 else
    743 {
    744 	<ruleBacktrackFailure()>
    745 	MismatchedSetException mse(input.getPosition(),input.LA(1));
    746 	<@mismatchedSetException()>
    747 <if(LEXER)>
    748 	this->recover(mse);
    749 <else>
    750 	this->recoverFromMismatchedSet(input,mse,FOLLOW_set_in_<ruleName><elementIndex>);
    751 <endif>
    752 	throw mse;
    753 }<\n>
    754 >>
    755 
    756 matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
    757 <matchSet(...)>
    758 <listLabel(...)>
    759 >>
    760 
    761 /** Match a string literal */
    762 lexerStringRef(string,label,elementIndex) ::= <<
    763 // lexerStringRef
    764 <if(label)>
    765 position_type <label>Start(input.getPosition());
    766 this->match( <string> );
    767 <checkRuleBacktrackFailure()>
    768 TokenType* <label> = TokenBuilder::build(Token.INVALID_TOKEN_TYPE,<label>Start,input,Token.DEFAULT_CHANNEL);
    769 <else>
    770 this->match( <string> );
    771 <checkRuleBacktrackFailure()><\n>
    772 <endif>
    773 >>
    774 
    775 wildcard(label,elementIndex) ::= <<
    776 <if(label)>
    777 <label> = input.LT(1);<\n>
    778 <endif>
    779 this->matchAny( input );
    780 <checkRuleBacktrackFailure()>
    781 >>
    782 
    783 wildcardAndListLabel(label,elementIndex) ::= <<
    784 <wildcard(...)>
    785 <listLabel(...)>
    786 >>
    787 
    788 /** Match . wildcard */
    789 wildcardChar(label, elementIndex) ::= <<
    790 <if(label)>
    791 <tokenid_type()> <label> = input.LA(1);<\n>
    792 <endif>
    793 this->matchAny();
    794 <checkRuleBacktrackFailure()>
    795 >>
    796 
    797 tokenid_type() ::= "<if(LEXER)>char_type<else>tokenid_type<endif>"
    798 
    799 wildcardCharListLabel(label, elementIndex) ::= <<
    800 <wildcardChar(...)>
    801 <listLabel(...)>
    802 >>
    803 
    804 /** Match a rule reference by invoking it possibly with arguments
    805  *  and a return value or values.
    806  */
    807 ruleRef(rule,label,elementIndex,args) ::= <<
    808 following.push(FOLLOW_<rule>_in_<ruleName><elementIndex>);
    809 <if(label)>
    810 <label>=<rule>(<args>);<\n>
    811 <else>
    812 <rule>(<args>);<\n>
    813 <endif>
    814 following.pop();
    815 <checkRuleBacktrackFailure()>
    816 >>
    817 
    818 /** ids+=ID */
    819 ruleRefAndListLabel(rule,label,elementIndex,args) ::= <<
    820 <ruleRef(...)>
    821 <listLabel(...)>
    822 >>
    823 
    824 /** A lexer rule reference */
    825 lexerRuleRef(rule,label,args) ::= <<
    826 <if(label)>
    827 position_type <label>Start(input.getPosition());
    828 m<rule>(<args>);
    829 <checkRuleBacktrackFailure()>
    830 TokenType* <label> = TokenBuilder::build(Token.INVALID_TOKEN_TYPE,<label>Start,input,Token.DEFAULT_CHANNEL);
    831 <else>
    832 m<rule>(<args>);
    833 <checkRuleBacktrackFailure()>
    834 <endif>
    835 >>
    836 
    837 /** EOF in the lexer */
    838 lexerMatchEOF(label) ::= <<
    839 <if(label)>
    840 position_type <label>Start(input.getPosition());
    841 match(EOF);
    842 <checkRuleBacktrackFailure()>
    843 TokenType* <label> = TokenBuilder::build(Token.EOF,<label>Start,input,Token.DEFAULT_CHANNEL);
    844 <else>
    845 match(EOF);
    846 <checkRuleBacktrackFailure()>
    847 <endif>
    848 >>
    849 
    850 /** match ^(root children) in tree parser */
    851 tree(root, children, nullableChildList) ::= <<
    852 <root:element()>
    853 <if(nullableChildList)>
    854 if ( input.LA(1)==antlr3::Token::DOWN ) {
    855     match(input, antlr3::Token::DOWN, null);
    856     <checkRuleBacktrackFailure()>
    857     <children:element()>
    858     match(input, antlr3::Token::UP, null);
    859     <checkRuleBacktrackFailure()>
    860 }
    861 <else>
    862 match(input, antlr3::Token::DOWN, null);
    863 <checkRuleBacktrackFailure()>
    864 <children:element()>
    865 match(input, antlr3::Token::UP, null);
    866 <checkRuleBacktrackFailure()>
    867 <endif>
    868 >>
    869 
    870 /** Every predicate is used as a validating predicate (even when it is
    871  *  also hoisted into a prediction expression).
    872  */
    873 validateSemanticPredicate(pred,description) ::= <<
    874 if ( !(<evalPredicate(...)>) ) {
    875 	<ruleBacktrackFailure()>
    876 	throw new FailedPredicateException(input, "<ruleName>", "<description>");
    877 }
    878 >>
    879 
    880 // F i x e d  D F A  (if-then-else)
    881 dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    882 <if(!semPredState)>
    883 <tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
    884 <endif>
    885 <edges; separator="\nelse ">
    886 else
    887 {
    888 <if(eotPredictsAlt)>
    889 	alt<decisionNumber> = <eotPredictsAlt>;<\n>
    890 <else>
    891 	<ruleBacktrackFailure()>
    892 	NoViableAltException nvae(input.getPosition(), "<description>", <decisionNumber>, <stateNumber>);<\n>
    893 	<@noViableAltException()>
    894 	throw nvae;<\n>
    895 <endif>
    896 }
    897 >>
    898 
    899 /** Same as a normal DFA state except that we don't examine lookahead
    900  *  for the bypass alternative.  It delays error detection but this
    901  *  is faster, smaller, and more what people expect.  For (X)? people
    902  *  expect "if ( LA(1)==X ) match(X);" and that's it.
    903  */
    904 dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    905 <if(!semPredState)>
    906 <tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);
    907 <endif>
    908 <edges; separator="\nelse ">
    909 >>
    910 
    911 /** A DFA state that is actually the loopback decision of a closure
    912  *  loop.  If end-of-token (EOT) predicts any of the targets then it
    913  *  should act like a default clause (i.e., no error can be generated).
    914  *  This is used only in the lexer so that for ('a')* on the end of a rule
    915  *  anything other than 'a' predicts exiting.
    916  */
    917 dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    918 <if(!semPredState)>
    919 <tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);
    920 <endif>
    921 <edges; separator="\nelse "><\n>
    922 <if(eotPredictsAlt)>
    923 else
    924 {
    925 	alt<decisionNumber> = <eotPredictsAlt>;
    926 }<\n>
    927 <endif>
    928 >>
    929 
    930 /** An accept state indicates a unique alternative has been predicted */
    931 dfaAcceptState(alt) ::= "alt<decisionNumber> = <alt>;"
    932 
    933 /** A simple edge with an expression.  If the expression is satisfied,
    934  *  enter to the target state.  To handle gated productions, we may
    935  *  have to evaluate some predicates for this edge.
    936  */
    937 dfaEdge(labelExpr, targetState, predicates) ::= <<
    938 if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>)
    939 {
    940 	<targetState>
    941 }
    942 >>
    943 
    944 // F i x e d  D F A  (switch case)
    945 
    946 /** A DFA state where a SWITCH may be generated.  The code generator
    947  *  decides if this is possible: CodeGenerator.canGenerateSwitch().
    948  */
    949 dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    950 switch ( input.LA(<k>) ) {
    951 <edges; separator="\n">
    952 default:
    953 <if(eotPredictsAlt)>
    954 	alt<decisionNumber> = <eotPredictsAlt>;
    955 <else>
    956 	NoViableAltException nvae( input.getPosition(), "<description>", <decisionNumber>, <stateNumber> );<\n>
    957 	<@noViableAltException()>
    958 	throw nvae;<\n>
    959 <endif>
    960 }<\n>
    961 >>
    962 
    963 dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    964 switch ( input.LA(<k>) ) {
    965 	<edges; separator="\n">
    966 }<\n>
    967 >>
    968 
    969 dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    970 switch ( input.LA(<k>) ) {
    971 <edges; separator="\n"><\n>
    972 <if(eotPredictsAlt)>
    973 default:
    974 	alt<decisionNumber> = <eotPredictsAlt>;
    975 	break;<\n>
    976 <endif>
    977 }<\n>
    978 >>
    979 
    980 dfaEdgeSwitch(labels, targetState) ::= <<
    981 <labels:{case <it>:}; separator="\n"> {
    982 	<targetState>
    983 } break;
    984 >>
    985 
    986 // C y c l i c  D F A
    987 
    988 /** The code to initiate execution of a cyclic DFA; this is used
    989  *  in the rule to predict an alt just like the fixed DFA case.
    990  *  The <name> attribute is inherited via the parser, lexer, ...
    991  */
    992 dfaDecision(decisionNumber,description) ::= <<
    993 // dfaDecision
    994 alt<decisionNumber> = predictDFA<decisionNumber>(input);
    995 >>
    996 
    997 /** The overall cyclic DFA chunk; contains all the DFA states */
    998 cyclicDFA(dfa) ::= <<
    999 /* cyclicDFA=<dfa>
   1000 */
   1001 // cyclic    = <dfa.cyclic>
   1002 // numstates = <dfa.numberOfStates>
   1003 
   1004 // startState = <dfa.startState>
   1005 // startState.numberOfTransitions = <dfa.startState.NumberOfTransitions>
   1006 // startState.lookaheadDepth = <dfa.startState.LookaheadDepth>
   1007 
   1008 const static short <name>dfa<dfa.decisionNumber>_eot[<dfa.numberOfStates>] = {
   1009 	<dfa.eot; wrap="\n     ", separator=",", null="-1">
   1010 };
   1011 const static short <name>dfa<dfa.decisionNumber>_eof[<dfa.numberOfStates>] = {
   1012 	<dfa.eof; wrap="\n     ", separator=",", null="-1">
   1013 };
   1014 const static unichar <name>dfa<dfa.decisionNumber>_min[<dfa.numberOfStates>] = {
   1015 	<dfa.min; wrap="\n     ", separator=",", null="0">
   1016 };
   1017 const static unichar <name>dfa<dfa.decisionNumber>_max[<dfa.numberOfStates>] = {
   1018 	<dfa.max; wrap="\n     ", separator=",", null="0">
   1019 };
   1020 const static short <name>dfa<dfa.decisionNumber>_accept[<dfa.numberOfStates>] = {
   1021 	<dfa.accept; wrap="\n     ", separator=",", null="-1">
   1022 };
   1023 const static short <name>dfa<dfa.decisionNumber>_special[<dfa.numberOfStates>] = {
   1024 	<dfa.special; wrap="\n     ", separator=",", null="-1">
   1025 };
   1026 <dfa.edgeTransitionClassMap.keys:{ table |
   1027 const static short <name>dfa<dfa.decisionNumber>_transition<i0>[] = {
   1028 	<table; separator=", ", wrap="\n	", null="-1">
   1029 };
   1030 }; null="">
   1031 const static short <name>dfa<dfa.decisionNumber>_transition[] = {
   1032 	<dfa.transitionEdgeTables:{whichTable|<name>dfa<dfa.decisionNumber>_transition<whichTable>,}; separator="\n", null="0 /* fixme? */">
   1033 };
   1034 	<! add attribute for the DFA !>
   1035 	DFA\<char_type> dfa<dfa.decisionNumber>;
   1036 <! this should go in the initializer of the thing
   1037 - (id) init
   1038 {
   1039 	if ((self = [super init]) != nil) {
   1040 		eot = <name>dfa<dfa.decisionNumber>_eot;
   1041 		eof = <name>dfa<dfa.decisionNumber>_eof;
   1042 		min = <name>dfa<dfa.decisionNumber>_min;
   1043 		max = <name>dfa<dfa.decisionNumber>_max;
   1044 		accept = <name>dfa<dfa.decisionNumber>_accept;
   1045 		special = <name>dfa<dfa.decisionNumber>_special;
   1046 		if (!(transition = calloc(<dfa.numberOfStates>, sizeof(void*)))) {
   1047 			[self release];
   1048 			return nil;
   1049 		}
   1050 		<dfa.transitionEdgeTables:{whichTable|transition[<i0>] = <name>dfa<dfa.decisionNumber>_transition<whichTable>;}; separator="\n", null="">
   1051 	}
   1052 	return self;
   1053 }
   1054 !>
   1055 
   1056 <if(dfa.specialStateSTs)>
   1057 int specialStateTransition( int state )
   1058 {
   1059 	int s = state;
   1060 	switch ( s ) {
   1061  		<dfa.specialStateSTs:{state |
   1062 		case <i0> : <! compressed special state numbers 0..n-1 !>
   1063 		<state>}; separator="\n">
   1064 	}
   1065 <if(backtracking)>
   1066 	if ( recognizer.isBacktracking() ) {
   1067 		recognizer.setFailed();
   1068 		return -1;
   1069 	}<\n>
   1070 <endif>
   1071 	noViableAlt(s, input);
   1072 }<\n>
   1073 <endif>
   1074 
   1075 
   1076 <\n>
   1077 
   1078 // <dfa.description>
   1079 decision_type predictDFA<dfa.decisionNumber>( StreamType& input )
   1080 {
   1081 	/* mark current location (rewind automatically when the rewinder goes
   1082 	 * out of scope */
   1083 	antlr3::Rewinder\<position_type> markPoint(input.getPosition());
   1084 	goto s0;	// goto start...
   1085 	// ...
   1086 	throw NoViableAltException( input.getPosition(), "<dfa.description>", <dfa.decisionNumber>, 0 /* fixme */ );<\n>
   1087 }<\n>
   1088 >>
   1089 
   1090 /** A state in a cyclic DFA */
   1091 cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<
   1092 // cyclicDFAState
   1093 s<stateNumber>: {
   1094 	<if(semPredState)>
   1095 	input.rewind();<\n>
   1096 	<else>
   1097 	<tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(1);
   1098 	<endif>
   1099 	<edges>
   1100 	<if(needErrorClause)>
   1101 	throw NoViableAltException( input.getPosition(), "<description>", <decisionNumber>, <stateNumber> );<\n>
   1102 	<endif><\n>
   1103 }<\n>
   1104 >>
   1105 
   1106 /** Just like a fixed DFA edge, test the lookahead and indicate what
   1107  *  state to jump to next if successful.
   1108  */
   1109 cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
   1110 // cyclicDFAEdge
   1111 if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>)
   1112 {
   1113 	input.consume();
   1114 	goto s<targetStateNumber>;
   1115 }<\n>
   1116 >>
   1117 
   1118 /** An edge pointing at end-of-token; essentially matches any char;
   1119  *  always jump to the target.
   1120  */
   1121 eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= "goto s<targetStateNumber>;"
   1122 
   1123 // D F A  E X P R E S S I O N S
   1124 
   1125 andPredicates(left,right) ::= "(<left> && <right>)"
   1126 
   1127 orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)"
   1128 
   1129 notPredicate(pred) ::= "!(<pred>)"
   1130 
   1131 evalPredicate(pred,description) ::= "<pred>"
   1132 
   1133 evalSynPredicate(pred,description) ::= "<pred>()"
   1134 
   1135 lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>"
   1136 
   1137 /** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
   1138  *  somewhere.  Must ask for the lookahead directly.
   1139  */
   1140 isolatedLookaheadTest(atom,k,atomAsInt) ::= "input.LA(<k>)==<atom>"
   1141 
   1142 lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <<
   1143 (LA<decisionNumber>_<stateNumber>\>=<lower> && LA<decisionNumber>_<stateNumber>\<=<upper>)
   1144 >>
   1145 
   1146 isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>)\>=<lower> && input.LA(<k>)\<=<upper>)"
   1147 
   1148 setTest(ranges) ::= "<ranges; separator=\"||\">"
   1149 
   1150 // A T T R I B U T E S
   1151 
   1152 globalAttributeScope(scope) ::= <<
   1153 <if(scope.attributes)>
   1154 protected static class <scope.name> {
   1155     <scope.attributes:{<it.decl>;}; separator="\n">
   1156 }
   1157 protected Stack <scope.name>_stack = new Stack();<\n>
   1158 <endif>
   1159 >>
   1160 
   1161 ruleAttributeScope(scope) ::= <<
   1162 <if(scope.attributes)>
   1163 protected static class <scope.name>_scope {
   1164     <scope.attributes:{<it.decl>;}; separator="\n">
   1165 }
   1166 protected Stack <scope.name>_stack = new Stack();<\n>
   1167 <endif>
   1168 >>
   1169 
   1170 returnType() ::= <<
   1171 <if(ruleDescriptor.hasMultipleReturnValues)>
   1172 <ruleDescriptor.name>_return
   1173 <else>
   1174 <if(ruleDescriptor.singleValueReturnType)>
   1175 <ruleDescriptor.singleValueReturnType>
   1176 <else>
   1177 void
   1178 <endif>
   1179 <endif>
   1180 >>
   1181 
   1182 ruleLabelType(referencedRule) ::= <<
   1183 <if(referencedRule.hasMultipleReturnValues)>
   1184 <referencedRule.name>_return
   1185 <else>
   1186 <if(referencedRule.singleValueReturnType)>
   1187 <referencedRule.singleValueReturnType>
   1188 <else>
   1189 void
   1190 <endif>
   1191 <endif>
   1192 >>
   1193 
   1194 /** Using a type to init value map, try to init a type; if not in table
   1195  *  must be an object, default value is "null".
   1196  */
   1197 initValue(typeName) ::= <<
   1198 <javaTypeInitMap.(typeName)>
   1199 >>
   1200 
   1201 ruleLabelDef(label) ::= <<
   1202 <ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n>
   1203 >>
   1204 
   1205 returnScope(scope) ::= <<
   1206 <if(ruleDescriptor.hasMultipleReturnValues)>
   1207 public static class <returnType()> {
   1208     <labelType> start, stop;
   1209 <if(buildAST)>
   1210     <ASTLabelType> tree;
   1211 <else>
   1212 <if(buildTemplate)>
   1213     StringTemplate st;
   1214 <endif>
   1215 <endif>
   1216     <scope.attributes:{<it.decl>;}; separator="\n">
   1217 };
   1218 <endif>
   1219 >>
   1220 
   1221 parameterScope(scope) ::= <<
   1222 <scope.attributes:{<it.decl>}; separator=", ">
   1223 >>
   1224 
   1225 /** Used in codegen.g to translate $x.y references.
   1226  *  I could have left actions as StringTemplates to be inserted in
   1227  *  the output (so they could use attributes inherited from surrounding
   1228  *  templates), but really wanted to pass in AttributeScope and Attribute
   1229  *  objects so this translation could query them.  So, translation of
   1230  *  $x.y to executable code occurs before recognizerST.toString() occurs.
   1231  *  I.e., actions are just text strings during final code generation.
   1232  */
   1233 globalAttributeRef(scope,attr) ::= <<
   1234 ((<scope>)<scope>_stack.peek()).<attr.name>
   1235 >>
   1236 
   1237 parameterAttributeRef(attr) ::= "<attr.name>"
   1238 
   1239 scopeAttributeRef(scope,attr,index,negIndex) ::= <<
   1240 <if(negIndex)>
   1241 ((<scope>_scope)<scope>_stack.elementAt(<scope>_stack.size()-<negIndex>-1)).<attr.name>
   1242 <else>
   1243 <if(index)>
   1244 ((<scope>_scope)<scope>_stack.elementAt(<index>)).<attr.name>
   1245 <else>
   1246 ((<scope>_scope)<scope>_stack.peek()).<attr.name>
   1247 <endif>
   1248 <endif>
   1249 >>
   1250 
   1251 /** $x is either global scope or x is rule with dynamic scope; refers
   1252  *  to stack itself not top of stack.  This is useful for predicates
   1253  *  like {$function.size()>0 && $function::name.equals("foo")}?
   1254  */
   1255 isolatedDynamicScopeRef(scope) ::= "<scope>_stack"
   1256 
   1257 /** reference an attribute of rule; might only have single return value */
   1258 ruleLabelRef(referencedRule,scope,attr) ::= <<
   1259 <if(referencedRule.singleValueReturnType)>
   1260 <scope>
   1261 <else>
   1262 <scope>.<attr.name>
   1263 <endif>
   1264 >>
   1265 
   1266 returnAttributeRef(ruleDescriptor,attr) ::= <<
   1267 <if(ruleDescriptor.singleValueReturnType)>
   1268 <attr.name>
   1269 <else>
   1270 retval.<attr.name>
   1271 <endif>
   1272 >>
   1273 
   1274 /** How to translate $tokenLabel */
   1275 tokenLabelRef(label) ::= "<label>"
   1276 
   1277 /** ids+=ID {$ids} or e+=expr {$e} */
   1278 listLabelRef(label) ::= "list_<label>"
   1279 
   1280 // not sure the next are the right approach; and they are evaluated early;
   1281 // they cannot see TREE_PARSER or PARSER attributes for example. :(
   1282 
   1283 tokenLabelPropertyRef_text(scope,attr) ::= "<scope>.getText()"
   1284 tokenLabelPropertyRef_type(scope,attr) ::= "<scope>.getType()"
   1285 tokenLabelPropertyRef_line(scope,attr) ::= "<scope>.getLine()"
   1286 tokenLabelPropertyRef_pos(scope,attr) ::= "<scope>.getCharPositionInLine()"
   1287 tokenLabelPropertyRef_channel(scope,attr) ::= "<scope>.getChannel()"
   1288 tokenLabelPropertyRef_index(scope,attr) ::= "<scope>.getTokenIndex()"
   1289 tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
   1290 
   1291 ruleLabelPropertyRef_start(scope,attr) ::= "<scope>.start"
   1292 ruleLabelPropertyRef_stop(scope,attr) ::= "<scope>.stop"
   1293 ruleLabelPropertyRef_tree(scope,attr) ::= "<scope>.tree"
   1294 ruleLabelPropertyRef_text(scope,attr) ::= "input.toString(<scope>.start,<scope>.stop)"
   1295 ruleLabelPropertyRef_st(scope,attr) ::= "<scope>.st"
   1296 
   1297 /** Isolated $RULE ref ok in lexer as it's a Token */
   1298 lexerRuleLabel(label) ::= "<label>"
   1299 
   1300 lexerRuleLabelPropertyRef_type(scope,attr) ::= "<scope>.getType()"
   1301 lexerRuleLabelPropertyRef_line(scope,attr) ::= "<scope>.getLine()"
   1302 lexerRuleLabelPropertyRef_pos(scope,attr) ::= "<scope>.getCharPositionInLine()"
   1303 lexerRuleLabelPropertyRef_channel(scope,attr) ::= "<scope>.getChannel()"
   1304 lexerRuleLabelPropertyRef_index(scope,attr) ::= "<scope>.getTokenIndex()"
   1305 lexerRuleLabelPropertyRef_text(scope,attr) ::= "<scope>.getText()"
   1306 
   1307 // Somebody may ref $template or $tree or $stop within a rule:
   1308 rulePropertyRef_start(scope,attr) ::= "((<labelType>)retval.start)"
   1309 rulePropertyRef_stop(scope,attr) ::= "((<labelType>)retval.stop)"
   1310 rulePropertyRef_tree(scope,attr) ::= "((<ASTLabelType>)retval.tree)"
   1311 rulePropertyRef_text(scope,attr) ::= "input.toString(retval.start,input.LT(-1))"
   1312 rulePropertyRef_st(scope,attr) ::= "retval.st"
   1313 
   1314 // A C T I O N S
   1315 
   1316 emit(type) ::= "emit(<type>);"
   1317 
   1318 setType(type) ::= "setType(<type>);"
   1319 
   1320 /** How to execute an action */
   1321 execAction(action) ::= <<
   1322 <if(backtracking)>
   1323 <if(actions.(actionScope).synpredgate)>
   1324 if ( <actions.(actionScope).synpredgate> )
   1325 {
   1326 	<action>
   1327 }
   1328 <else>
   1329 if ( backtracking == 0 )
   1330 {
   1331 	<action>
   1332 }
   1333 <endif>
   1334 <else>
   1335 <action>
   1336 <endif>
   1337 >>
   1338 
   1339 // M I S C (properties, etc...)
   1340 
   1341 bitset(name, words64) ::= <<
   1342 public static final BitSet <name> = new BitSet(new long[]{<words64:{<it>L};separator=",">});<\n>
   1343 >>
   1344 
   1345 tokenPrefix() ::= "TOK_"
   1346 codeFileExtension() ::= ".cpp"
   1347 // used in CPPTarget.java to generate the headerfile extension
   1348 headerFileExtension() ::= ".h"
   1349 
   1350 true() ::= "true"
   1351 false() ::= "false"
   1352