Home | History | Annotate | Download | only in Java
      1 /*
      2  [The "BSD license"]
      3  Copyright (c) 2010 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 
     29 javaTypeInitMap ::= [
     30 	"int":"0",
     31 	"long":"0",
     32 	"float":"0.0f",
     33 	"double":"0.0",
     34 	"boolean":"false",
     35 	"byte":"0",
     36 	"short":"0",
     37 	"char":"0",
     38 	default:"null" // anything other than an atomic type
     39 ]
     40 
     41 // System.Boolean.ToString() returns "True" and "False", but the proper C# literals are "true" and "false"
     42 // The Java version of Boolean returns "true" and "false", so they map to themselves here.
     43 booleanLiteral ::= [
     44 	"True":"true",
     45 	"False":"false",
     46 	"true":"true",
     47 	"false":"false",
     48 	default:"false"
     49 ]
     50 
     51 /** The overall file structure of a recognizer; stores methods for rules
     52  *  and cyclic DFAs plus support code.
     53  */
     54 outputFile(LEXER,PARSER,TREE_PARSER, actionScope, actions,
     55            docComment, recognizer,
     56            name, tokens, tokenNames, rules, cyclicDFAs,
     57 	   bitsets, buildTemplate, buildAST, rewriteMode, profile,
     58 	   backtracking, synpreds, memoize, numRules,
     59 	   fileName, ANTLRVersion, generatedTimestamp, trace,
     60 	   scopes, superClass, literals) ::=
     61 <<
     62 // $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>
     63 <actions.(actionScope).header>
     64 
     65 <@imports>
     66 import org.antlr.runtime.*;
     67 <if(TREE_PARSER)>
     68 import org.antlr.runtime.tree.*;
     69 <endif>
     70 import java.util.Stack;
     71 import java.util.List;
     72 import java.util.ArrayList;
     73 <if(backtracking)>
     74 import java.util.Map;
     75 import java.util.HashMap;
     76 <endif>
     77 <@end>
     78 
     79 <docComment>
     80 @SuppressWarnings("all")
     81 <recognizer>
     82 
     83 >>
     84 
     85 lexer(grammar, name, tokens, scopes, rules, numRules, filterMode, labelType="CommonToken",
     86       superClass="Lexer") ::= <<
     87 public class <grammar.recognizerName> extends <@superClassName><superClass><@end> {
     88 	<tokens:{it | public static final int <it.name>=<it.type>;}; separator="\n">
     89 	<scopes:{it |<if(it.isDynamicGlobalScope)><globalAttributeScope(it)><endif>}>
     90 	<actions.lexer.members>
     91 
     92 	// delegates
     93 	<grammar.delegates:
     94 		{g|public <g.recognizerName> <g:delegateName()>;}; separator="\n">
     95 	// delegators
     96 	<grammar.delegators:
     97 		{g|public <g.recognizerName> <g:delegateName()>;}; separator="\n">
     98 	<last(grammar.delegators):{g|public <g.recognizerName> gParent;}>
     99 	public <superClass>[] getDelegates() {
    100 		return new <superClass>[] {<grammar.delegates: {g|<g:delegateName()>}; separator = ", ">};
    101 	}
    102 
    103 	public <grammar.recognizerName>() {} <! needed by subclasses !>
    104 	public <grammar.recognizerName>(CharStream input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
    105 		this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>);
    106 	}
    107 	public <grammar.recognizerName>(CharStream input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
    108 		super(input,state);
    109 <if(memoize)>
    110 <if(grammar.grammarIsRoot)>
    111 		state.ruleMemo = new HashMap[<numRules>+1];<\n><! index from 1..n !>
    112 <endif>
    113 <endif>
    114 		<grammar.directDelegates:
    115 			{g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
    116 		<grammar.delegators:
    117 			{g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
    118 		<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
    119 	}
    120 	@Override public String getGrammarFileName() { return "<fileName>"; }
    121 
    122 <if(filterMode)>
    123 	<filteringNextToken()>
    124 <endif>
    125 	<rules; separator="\n\n">
    126 
    127 	<synpreds:{p | <lexerSynpred(p)>}>
    128 
    129 	<cyclicDFAs:{dfa | protected DFA<dfa.decisionNumber> dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this);}; separator="\n">
    130 	<cyclicDFAs:cyclicDFA(); separator="\n\n"><! dump tables for all DFA !>
    131 
    132 }
    133 >>
    134 
    135 /** A override of Lexer.nextToken() that backtracks over mTokens() looking
    136  *  for matches.  No error can be generated upon error; just rewind, consume
    137  *  a token and then try again.  backtracking needs to be set as well.
    138  *  Make rule memoization happen only at levels above 1 as we start mTokens
    139  *  at backtracking==1.
    140  */
    141 filteringNextToken() ::= <<
    142 @Override
    143 public Token nextToken() {
    144 	while (true) {
    145 		if ( input.LA(1)==CharStream.EOF ) {
    146 			Token eof = new CommonToken(input,Token.EOF,
    147 										Token.DEFAULT_CHANNEL,
    148 										input.index(),input.index());
    149 			eof.setLine(getLine());
    150 			eof.setCharPositionInLine(getCharPositionInLine());
    151 			return eof;
    152 		}
    153 		state.token = null;
    154 	state.channel = Token.DEFAULT_CHANNEL;
    155 		state.tokenStartCharIndex = input.index();
    156 		state.tokenStartCharPositionInLine = input.getCharPositionInLine();
    157 		state.tokenStartLine = input.getLine();
    158 	state.text = null;
    159 		try {
    160 			int m = input.mark();
    161 			state.backtracking=1; <! means we won't throw slow exception !>
    162 			state.failed=false;
    163 			mTokens();
    164 			state.backtracking=0;
    165 			<! mTokens backtracks with synpred at backtracking==2
    166 				and we set the synpredgate to allow actions at level 1. !>
    167 			if ( state.failed ) {
    168 				input.rewind(m);
    169 				input.consume(); <! advance one char and try again !>
    170 			}
    171 			else {
    172 				emit();
    173 				return state.token;
    174 			}
    175 		}
    176 		catch (RecognitionException re) {
    177 			// shouldn't happen in backtracking mode, but...
    178 			reportError(re);
    179 			recover(re);
    180 		}
    181 	}
    182 }
    183 
    184 @Override
    185 public void memoize(IntStream input,
    186 		int ruleIndex,
    187 		int ruleStartIndex)
    188 {
    189 if ( state.backtracking>1 ) super.memoize(input, ruleIndex, ruleStartIndex);
    190 }
    191 
    192 @Override
    193 public boolean alreadyParsedRule(IntStream input, int ruleIndex) {
    194 if ( state.backtracking>1 ) return super.alreadyParsedRule(input, ruleIndex);
    195 return false;
    196 }
    197 >>
    198 
    199 actionGate() ::= "state.backtracking==0"
    200 
    201 filteringActionGate() ::= "state.backtracking==1"
    202 
    203 /** How to generate a parser */
    204 genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
    205               bitsets, inputStreamType, superClass,
    206               labelType, members, rewriteElementType,
    207               filterMode, ASTLabelType="Object") ::= <<
    208 public class <grammar.recognizerName> extends <@superClassName><superClass><@end> {
    209 <if(grammar.grammarIsRoot)>
    210 	public static final String[] tokenNames = new String[] {
    211 		"\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ", wrap="\n\t\t">
    212 	};
    213 <endif>
    214 	<tokens:{it |public static final int <it.name>=<it.type>;}; separator="\n">
    215 
    216 	// delegates
    217 	<grammar.delegates: {g|public <g.recognizerName> <g:delegateName()>;}; separator="\n">
    218 	public <superClass>[] getDelegates() {
    219 		return new <superClass>[] {<grammar.delegates: {g|<g:delegateName()>}; separator = ", ">};
    220 	}
    221 
    222 	// delegators
    223 	<grammar.delegators:
    224 		{g|public <g.recognizerName> <g:delegateName()>;}; separator="\n">
    225 	<last(grammar.delegators):{g|public <g.recognizerName> gParent;}>
    226 
    227 	<scopes:{it |<if(it.isDynamicGlobalScope)><globalAttributeScope(it)><endif>}>
    228 
    229 <@members>
    230 	<! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !>
    231 	public <grammar.recognizerName>(<inputStreamType> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
    232 		this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>);
    233 	}
    234 	public <grammar.recognizerName>(<inputStreamType> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
    235 		super(input, state);
    236 		<parserCtorBody()>
    237 		<grammar.directDelegates:
    238 			{g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
    239 		<grammar.indirectDelegates:{g | <g:delegateName()> = <g.delegator:delegateName()>.<g:delegateName()>;}; separator="\n">
    240 		<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
    241 	}
    242 <@end>
    243 
    244 	@Override public String[] getTokenNames() { return <grammar.composite.rootGrammar.recognizerName>.tokenNames; }
    245 	@Override public String getGrammarFileName() { return "<fileName>"; }
    246 
    247 	<members>
    248 
    249 	<rules; separator="\n\n">
    250 
    251 <! generate rule/method definitions for imported rules so they
    252    appear to be defined in this recognizer. !>
    253 	// Delegated rules
    254 <grammar.delegatedRules:{ruleDescriptor|
    255 	public <returnType(ruleDescriptor)> <ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope()>) throws <ruleDescriptor.throwsSpec; separator=", "> { <if(ruleDescriptor.hasReturnValue)>return <endif><ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name>(<if(ruleDescriptor.parameterScope)><ruleDescriptor.parameterScope.attributes:{a|<a.name>}; separator=", "><endif>); \}}; separator="\n">
    256 
    257 	<synpreds:{p | <synpred(p)>}>
    258 
    259 	<cyclicDFAs:{dfa | protected DFA<dfa.decisionNumber> dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this);}; separator="\n">
    260 	<cyclicDFAs:cyclicDFA(); separator="\n\n"><! dump tables for all DFA !>
    261 
    262 	<bitsets:{it | <bitset(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>},
    263 							words64=it.bits)>}; separator="\n">
    264 }
    265 >>
    266 
    267 parserCtorBody() ::= <<
    268 <if(memoize)>
    269 <if(grammar.grammarIsRoot)>
    270 this.state.ruleMemo = new HashMap[<length(grammar.allImportedRules)>+1];<\n><! index from 1..n !>
    271 <endif>
    272 <endif>
    273 <grammar.delegators:
    274 	{g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
    275 >>
    276 
    277 parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets,
    278        ASTLabelType="Object", superClass="Parser", labelType="Token",
    279        members={<actions.parser.members>}) ::= <<
    280 <genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
    281               bitsets, "TokenStream", superClass,
    282               labelType, members, "Token",
    283               false, ASTLabelType)>
    284 >>
    285 
    286 /** How to generate a tree parser; same as parser except the input
    287  *  stream is a different type.
    288  */
    289 treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules,
    290            numRules, bitsets, filterMode, labelType={<ASTLabelType>}, ASTLabelType="Object",
    291            superClass={<if(filterMode)><if(buildAST)>TreeRewriter<else>TreeFilter<endif><else>TreeParser<endif>},
    292            members={<actions.treeparser.members>}
    293            ) ::= <<
    294 <genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
    295               bitsets, "TreeNodeStream", superClass,
    296               labelType, members, "Node",
    297               filterMode, ASTLabelType)>
    298 >>
    299 
    300 /** A simpler version of a rule template that is specific to the imaginary
    301  *  rules created for syntactic predicates.  As they never have return values
    302  *  nor parameters etc..., just give simplest possible method.  Don't do
    303  *  any of the normal memoization stuff in here either; it's a waste.
    304  *  As predicates cannot be inlined into the invoking rule, they need to
    305  *  be in a rule by themselves.
    306  */
    307 synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::=
    308 <<
    309 // $ANTLR start <ruleName>
    310 public final void <ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope()>) throws <ruleDescriptor.throwsSpec:{x|<x>}; separator=", "> {
    311 	<ruleLabelDefs()>
    312 <if(trace)>
    313 	traceIn("<ruleName>_fragment", <ruleDescriptor.index>);
    314 	try {
    315 		<block>
    316 	}
    317 	finally {
    318 		traceOut("<ruleName>_fragment", <ruleDescriptor.index>);
    319 	}
    320 <else>
    321 	<block>
    322 <endif>
    323 }
    324 // $ANTLR end <ruleName>
    325 >>
    326 
    327 synpred(name) ::= <<
    328 public final boolean <name>() {
    329 	state.backtracking++;
    330 	<@start()>
    331 	int start = input.mark();
    332 	try {
    333 		<name>_fragment(); // can never throw exception
    334 	} catch (RecognitionException re) {
    335 		System.err.println("impossible: "+re);
    336 	}
    337 	boolean success = !state.failed;
    338 	input.rewind(start);
    339 	<@stop()>
    340 	state.backtracking--;
    341 	state.failed=false;
    342 	return success;
    343 }<\n>
    344 >>
    345 
    346 lexerSynpred(name) ::= <<
    347 <synpred(name)>
    348 >>
    349 
    350 ruleMemoization(name) ::= <<
    351 <if(memoize)>
    352 if ( state.backtracking>0 && alreadyParsedRule(input, <ruleDescriptor.index>) ) { <returnStatement(({<ruleReturnValue()>}))> }
    353 <endif>
    354 >>
    355 
    356 /** How to test for failure and return from rule */
    357 checkRuleBacktrackFailure() ::= <<
    358 <if(backtracking)>if (state.failed) <returnStatement(({<ruleReturnValue()>}))><endif>
    359 >>
    360 
    361 /** This rule has failed, exit indicating failure during backtrack */
    362 ruleBacktrackFailure() ::= <<
    363 <if(backtracking)>if (state.backtracking>0) {state.failed=true; <returnStatement(({<ruleReturnValue()>}))>}<endif>
    364 >>
    365 
    366 /** How to generate code for a rule.  This includes any return type
    367  *  data aggregates required for multiple return values.
    368  */
    369 rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<
    370 <ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
    371 <returnScope(scope=ruleDescriptor.returnScope)>
    372 
    373 // $ANTLR start "<ruleName>"
    374 // <fileName>:<description>
    375 <if(isPredefinedRewriteRule.(ruleName) && filterMode && buildAST)>
    376 @Override
    377 <endif>
    378 public final <returnType(ruleDescriptor)> <ruleName>(<ruleDescriptor.parameterScope:parameterScope()>) throws <ruleDescriptor.throwsSpec:{x|<x>}; separator=", "> {
    379 	<if(trace)>traceIn("<ruleName>", <ruleDescriptor.index>);<endif>
    380 	<ruleScopeSetUp()>
    381 	<ruleDeclarations()>
    382 	<ruleLabelDefs()>
    383 	<ruleDescriptor.actions.init>
    384 	<@preamble()>
    385 	try {
    386 		<ruleMemoization(name=ruleName)>
    387 		<block>
    388 		<ruleCleanUp()>
    389 		<(ruleDescriptor.actions.after):execAction()>
    390 	}
    391 <if(exceptions)>
    392 	<exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
    393 <else>
    394 <if(!emptyRule)>
    395 <if(actions.(actionScope).rulecatch)>
    396 	<actions.(actionScope).rulecatch>
    397 <else>
    398 	catch (RecognitionException re) {
    399 		reportError(re);
    400 		recover(input,re);
    401 		<@setErrorReturnValue()>
    402 	}
    403 <endif>
    404 <endif>
    405 <endif>
    406 	finally {
    407 		// do for sure before leaving
    408 		<if(trace)>traceOut("<ruleName>", <ruleDescriptor.index>);<endif>
    409 		<memoize()>
    410 		<ruleScopeCleanUp()>
    411 		<finally>
    412 	}
    413 	<@postamble()>
    414 	<returnStatement(({<ruleReturnValue()>}), false)>
    415 }
    416 // $ANTLR end "<ruleName>"
    417 >>
    418 
    419 returnStatement(returnValue, force=true) ::= <%
    420 <if(!isEmptyString.(returnValue))>
    421 	return <returnValue>;
    422 <elseif(force)>
    423 	return;
    424 <endif>
    425 %>
    426 
    427 catch(decl,action) ::= <<
    428 catch (<e.decl>) {
    429 	<e.action>
    430 }
    431 >>
    432 
    433 ruleDeclarations() ::= <<
    434 <if(ruleDescriptor.hasMultipleReturnValues)>
    435 <returnType(ruleDescriptor)> retval = new <returnType(ruleDescriptor)>();
    436 retval.start = input.LT(1);
    437 <elseif(ruleDescriptor.returnScope)>
    438 <ruleDescriptor.returnScope.attributes:{ a |
    439 <a.type> <a.name> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
    440 }>
    441 <endif>
    442 <if(memoize)>
    443 int <ruleDescriptor.name>_StartIndex = input.index();
    444 <endif>
    445 >>
    446 
    447 ruleScopeSetUp() ::= <<
    448 <ruleDescriptor.useScopes:{it |<it>_stack.push(new <it>_scope());}; separator="\n">
    449 <ruleDescriptor.ruleScope:{it |<it.name>_stack.push(new <it.name>_scope());}; separator="\n">
    450 >>
    451 
    452 ruleScopeCleanUp() ::= <<
    453 <ruleDescriptor.useScopes:{it |<it>_stack.pop();}; separator="\n">
    454 <ruleDescriptor.ruleScope:{it |<it.name>_stack.pop();}; separator="\n">
    455 >>
    456 
    457 
    458 ruleLabelDefs() ::= <<
    459 <[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels,
    460   ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels]
    461 	:{it |<labelType> <it.label.text>=null;}; separator="\n"
    462 >
    463 <[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels,ruleDescriptor.wildcardTreeListLabels]
    464 	:{it |List\<Object> list_<it.label.text>=null;}; separator="\n"
    465 >
    466 <ruleDescriptor.ruleLabels:ruleLabelDef(); separator="\n">
    467 <ruleDescriptor.ruleListLabels:{ll|RuleReturnScope <ll.label.text> = null;}; separator="\n">
    468 >>
    469 
    470 lexerRuleLabelDefs() ::= <<
    471 <[ruleDescriptor.tokenLabels,
    472   ruleDescriptor.tokenListLabels,
    473   ruleDescriptor.ruleLabels]
    474 	:{it |<labelType> <it.label.text>=null;}; separator="\n"
    475 >
    476 <ruleDescriptor.charLabels:{it |int <it.label.text>;}; separator="\n">
    477 <[ruleDescriptor.tokenListLabels,
    478   ruleDescriptor.ruleListLabels]
    479 	:{it |List\<Object> list_<it.label.text>=null;}; separator="\n"
    480 >
    481 >>
    482 
    483 ruleReturnValue() ::= <%
    484 <if(!ruleDescriptor.isSynPred)>
    485 <if(ruleDescriptor.hasReturnValue)>
    486 <if(ruleDescriptor.hasSingleReturnValue)>
    487 <ruleDescriptor.singleValueReturnName>
    488 <else>
    489 retval
    490 <endif>
    491 <endif>
    492 <endif>
    493 %>
    494 
    495 ruleCleanUp() ::= <<
    496 <if(ruleDescriptor.hasMultipleReturnValues)>
    497 <if(!TREE_PARSER)>
    498 retval.stop = input.LT(-1);
    499 <endif>
    500 <endif>
    501 >>
    502 
    503 memoize() ::= <<
    504 <if(memoize)>
    505 <if(backtracking)>
    506 if ( state.backtracking>0 ) { memoize(input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex); }
    507 <endif>
    508 <endif>
    509 >>
    510 
    511 /** How to generate a rule in the lexer; naked blocks are used for
    512  *  fragment rules.
    513  */
    514 lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= <<
    515 // $ANTLR start "<ruleName>"
    516 public final void m<ruleName>(<ruleDescriptor.parameterScope:parameterScope()>) throws RecognitionException {
    517 	<if(trace)>traceIn("<ruleName>", <ruleDescriptor.index>);<endif>
    518 	<ruleScopeSetUp()>
    519 	<ruleDeclarations()>
    520 	try {
    521 <if(nakedBlock)>
    522 		<ruleMemoization(name=ruleName)>
    523 		<lexerRuleLabelDefs()>
    524 		<ruleDescriptor.actions.init>
    525 		<block>
    526 <else>
    527 		int _type = <ruleName>;
    528 		int _channel = DEFAULT_TOKEN_CHANNEL;
    529 		<ruleMemoization(name=ruleName)>
    530 		<lexerRuleLabelDefs()>
    531 		<ruleDescriptor.actions.init>
    532 		<block>
    533 		<ruleCleanUp()>
    534 		state.type = _type;
    535 		state.channel = _channel;
    536 		<(ruleDescriptor.actions.after):execAction()>
    537 <endif>
    538 	}
    539 	finally {
    540 		// do for sure before leaving
    541 		<if(trace)>traceOut("<ruleName>", <ruleDescriptor.index>);<endif>
    542 		<ruleScopeCleanUp()>
    543 		<memoize()>
    544 	}
    545 }
    546 // $ANTLR end "<ruleName>"
    547 >>
    548 
    549 /** How to generate code for the implicitly-defined lexer grammar rule
    550  *  that chooses between lexer rules.
    551  */
    552 tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
    553 @Override
    554 public void mTokens() throws RecognitionException {
    555 	<block>
    556 }
    557 >>
    558 
    559 // S U B R U L E S
    560 
    561 /** A (...) subrule with multiple alternatives */
    562 block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    563 // <fileName>:<description>
    564 int alt<decisionNumber>=<maxAlt>;
    565 <decls>
    566 <@predecision()>
    567 <decision>
    568 <@postdecision()>
    569 <@prebranch()>
    570 switch (alt<decisionNumber>) {
    571 	<alts:{a | <altSwitchCase(i,a)>}>
    572 }
    573 <@postbranch()>
    574 >>
    575 
    576 /** A rule block with multiple alternatives */
    577 ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    578 // <fileName>:<description>
    579 int alt<decisionNumber>=<maxAlt>;
    580 <decls>
    581 <@predecision()>
    582 <decision>
    583 <@postdecision()>
    584 switch (alt<decisionNumber>) {
    585 	<alts:{a | <altSwitchCase(i,a)>}>
    586 }
    587 >>
    588 
    589 ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
    590 // <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 1 or more alternatives */
    607 positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    608 // <fileName>:<description>
    609 int cnt<decisionNumber>=0;
    610 <decls>
    611 <@preloop()>
    612 loop<decisionNumber>:
    613 while (true) {
    614 	int alt<decisionNumber>=<maxAlt>;
    615 	<@predecision()>
    616 	<decision>
    617 	<@postdecision()>
    618 	switch (alt<decisionNumber>) {
    619 	<alts:{a | <altSwitchCase(i,a)>}>
    620 	default :
    621 		if ( cnt<decisionNumber> >= 1 ) break loop<decisionNumber>;
    622 		<ruleBacktrackFailure()>
    623 		EarlyExitException eee = new EarlyExitException(<decisionNumber>, input);
    624 		<@earlyExitException()>
    625 		throw eee;
    626 	}
    627 	cnt<decisionNumber>++;
    628 }
    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 // <fileName>:<description>
    637 <decls>
    638 <@preloop()>
    639 loop<decisionNumber>:
    640 while (true) {
    641 	int alt<decisionNumber>=<maxAlt>;
    642 	<@predecision()>
    643 	<decision>
    644 	<@postdecision()>
    645 	switch (alt<decisionNumber>) {
    646 	<alts:{a | <altSwitchCase(i,a)>}>
    647 	default :
    648 		break loop<decisionNumber>;
    649 	}
    650 }
    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(altNum,alt) ::= <<
    668 case <altNum> :
    669 	<@prealt()>
    670 	<alt>
    671 	break;<\n>
    672 >>
    673 
    674 /** An alternative is just a list of elements; at outermost level */
    675 alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
    676 // <fileName>:<description>
    677 {
    678 <@declarations()>
    679 <elements:element()>
    680 <rew>
    681 <@cleanup()>
    682 }
    683 >>
    684 
    685 /** What to emit when there is no rewrite.  For auto build
    686  *  mode, does nothing.
    687  */
    688 noRewrite(rewriteBlockLevel, treeLevel) ::= ""
    689 
    690 // E L E M E N T S
    691 
    692 /** Dump the elements one per line */
    693 element(e) ::= <<
    694 <@prematch()>
    695 <e.el>
    696 >>
    697 
    698 /** match a token optionally with a label in front */
    699 tokenRef(token,label,elementIndex,terminalOptions={}) ::= <<
    700 <if(label)><label>=(<labelType>)<endif>match(input,<token>,FOLLOW_<token>_in_<ruleName><elementIndex>); <checkRuleBacktrackFailure()>
    701 >>
    702 
    703 /** ids+=ID */
    704 tokenRefAndListLabel(token,label,elementIndex,terminalOptions={}) ::= <<
    705 <tokenRef(token,label,elementIndex,terminalOptions)>
    706 <listLabel(label, label)>
    707 >>
    708 
    709 listLabel(label,elem) ::= <<
    710 if (list_<label>==null) list_<label>=new ArrayList\<Object>();
    711 list_<label>.add(<elem>);
    712 >>
    713 
    714 /** match a character */
    715 charRef(char,label) ::= <<
    716 <if(label)>
    717 <label> = input.LA(1);
    718 <endif>
    719 match(<char>); <checkRuleBacktrackFailure()>
    720 >>
    721 
    722 /** match a character range */
    723 charRangeRef(a,b,label) ::= <<
    724 <if(label)>
    725 <label> = input.LA(1);
    726 <endif>
    727 matchRange(<a>,<b>); <checkRuleBacktrackFailure()>
    728 >>
    729 
    730 /** For now, sets are interval tests and must be tested inline */
    731 matchSet(s,label,elementIndex,postmatchCode="",terminalOptions={}) ::= <<
    732 <if(label)>
    733 <if(LEXER)>
    734 <label>= input.LA(1);
    735 <else>
    736 <label>=<castToLabelType("input.LT(1)")>;
    737 <endif>
    738 <endif>
    739 if ( <s> ) {
    740 	input.consume();
    741 	<postmatchCode>
    742 <if(!LEXER)>
    743 	state.errorRecovery=false;
    744 <endif>
    745 	<if(backtracking)>state.failed=false;<endif>
    746 }
    747 else {
    748 	<ruleBacktrackFailure()>
    749 	MismatchedSetException mse = new MismatchedSetException(null,input);
    750 	<@mismatchedSetException()>
    751 <if(LEXER)>
    752 	recover(mse);
    753 	throw mse;
    754 <else>
    755 	throw mse;
    756 	<! use following code to make it recover inline; remove throw mse;
    757 	recoverFromMismatchedSet(input,mse,FOLLOW_set_in_<ruleName><elementIndex>);
    758 	!>
    759 <endif>
    760 }
    761 >>
    762 
    763 matchRuleBlockSet ::= matchSet
    764 
    765 matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
    766 <matchSet(...)>
    767 <listLabel(label, label)>
    768 >>
    769 
    770 /** Match a string literal */
    771 lexerStringRef(string,label,elementIndex="0") ::= <<
    772 <if(label)>
    773 int <label>Start = getCharIndex();
    774 match(<string>); <checkRuleBacktrackFailure()>
    775 int <label>StartLine<elementIndex> = getLine();
    776 int <label>StartCharPos<elementIndex> = getCharPositionInLine();
    777 <label> = new <labelType>(input, Token.INVALID_TOKEN_TYPE, Token.DEFAULT_CHANNEL, <label>Start, getCharIndex()-1);
    778 <label>.setLine(<label>StartLine<elementIndex>);
    779 <label>.setCharPositionInLine(<label>StartCharPos<elementIndex>);
    780 <else>
    781 match(<string>); <checkRuleBacktrackFailure()>
    782 <endif>
    783 >>
    784 
    785 wildcard(token,label,elementIndex,terminalOptions={}) ::= <<
    786 <if(label)>
    787 <label>=<castToLabelType("input.LT(1)")>;
    788 <endif>
    789 matchAny(input); <checkRuleBacktrackFailure()>
    790 >>
    791 
    792 wildcardAndListLabel(token,label,elementIndex,terminalOptions={}) ::= <<
    793 <wildcard(...)>
    794 <listLabel(label, label)>
    795 >>
    796 
    797 /** Match . wildcard in lexer */
    798 wildcardChar(label, elementIndex) ::= <<
    799 <if(label)>
    800 <label> = input.LA(1);
    801 <endif>
    802 matchAny(); <checkRuleBacktrackFailure()>
    803 >>
    804 
    805 wildcardCharListLabel(label, elementIndex) ::= <<
    806 <wildcardChar(label, elementIndex)>
    807 <listLabel(label, label)>
    808 >>
    809 
    810 /** Match a rule reference by invoking it possibly with arguments
    811  *  and a return value or values.  The 'rule' argument was the
    812  *  target rule name, but now is type Rule, whose toString is
    813  *  same: the rule name.  Now though you can access full rule
    814  *  descriptor stuff.
    815  */
    816 ruleRef(rule,label,elementIndex,args,scope) ::= <<
    817 pushFollow(FOLLOW_<rule.name>_in_<ruleName><elementIndex>);
    818 <if(label)><label>=<endif><if(scope)><scope:delegateName()>.<endif><rule.name>(<args; separator=", ">);
    819 state._fsp--;
    820 <checkRuleBacktrackFailure()>
    821 >>
    822 
    823 /** ids+=r */
    824 ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    825 <ruleRef(rule,label,elementIndex,args,scope)>
    826 <listLabel(label, label)>
    827 >>
    828 
    829 /** A lexer rule reference.
    830  *
    831  *  The 'rule' argument was the target rule name, but now
    832  *  is type Rule, whose toString is same: the rule name.
    833  *  Now though you can access full rule descriptor stuff.
    834  */
    835 lexerRuleRef(rule,label,args,elementIndex,scope) ::= <<
    836 <if(label)>
    837 int <label>Start<elementIndex> = getCharIndex();
    838 int <label>StartLine<elementIndex> = getLine();
    839 int <label>StartCharPos<elementIndex> = getCharPositionInLine();
    840 <if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
    841 <label> = new <labelType>(input, Token.INVALID_TOKEN_TYPE, Token.DEFAULT_CHANNEL, <label>Start<elementIndex>, getCharIndex()-1);
    842 <label>.setLine(<label>StartLine<elementIndex>);
    843 <label>.setCharPositionInLine(<label>StartCharPos<elementIndex>);
    844 <else>
    845 <if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
    846 <endif>
    847 >>
    848 
    849 /** i+=INT in lexer */
    850 lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
    851 <lexerRuleRef(rule,label,args,elementIndex,scope)>
    852 <listLabel(label, label)>
    853 >>
    854 
    855 /** EOF in the lexer */
    856 lexerMatchEOF(label,elementIndex) ::= <<
    857 <if(label)>
    858 int <label>Start<elementIndex> = getCharIndex();
    859 int <label>StartLine<elementIndex> = getLine();
    860 int <label>StartCharPos<elementIndex> = getCharPositionInLine();
    861 match(EOF); <checkRuleBacktrackFailure()>
    862 <labelType> <label> = new <labelType>(input, EOF, Token.DEFAULT_CHANNEL, <label>Start<elementIndex>, getCharIndex()-1);
    863 <label>.setLine(<label>StartLine<elementIndex>);
    864 <label>.setCharPositionInLine(<label>StartCharPos<elementIndex>);
    865 <else>
    866 match(EOF); <checkRuleBacktrackFailure()>
    867 <endif>
    868 >>
    869 
    870 // used for left-recursive rules
    871 recRuleDefArg()                       ::= "int <recRuleArg()>"
    872 recRuleArg()                          ::= "_p"
    873 recRuleAltPredicate(ruleName,opPrec)  ::= "<recRuleArg()> \<= <opPrec>"
    874 recRuleSetResultAction()              ::= "root_0=$<ruleName>_primary.tree;"
    875 recRuleSetReturnAction(src,name)      ::= "$<name>=$<src>.<name>;"
    876 
    877 /** match ^(root children) in tree parser */
    878 tree(root, actionsAfterRoot, children, nullableChildList,
    879      enclosingTreeLevel, treeLevel) ::= <<
    880 <root:element()>
    881 <actionsAfterRoot:element()>
    882 <if(nullableChildList)>
    883 if ( input.LA(1)==Token.DOWN ) {
    884 	match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
    885 	<children:element()>
    886 	match(input, Token.UP, null); <checkRuleBacktrackFailure()>
    887 }
    888 <else>
    889 match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
    890 <children:element()>
    891 match(input, Token.UP, null); <checkRuleBacktrackFailure()>
    892 <endif>
    893 >>
    894 
    895 /** Every predicate is used as a validating predicate (even when it is
    896  *  also hoisted into a prediction expression).
    897  */
    898 validateSemanticPredicate(pred,description) ::= <<
    899 if ( !(<evalPredicate(pred,description)>) ) {
    900 	<ruleBacktrackFailure()>
    901 	throw new FailedPredicateException(input, "<ruleName>", "<description>");
    902 }
    903 >>
    904 
    905 // F i x e d  D F A  (if-then-else)
    906 
    907 dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    908 int LA<decisionNumber>_<stateNumber> = input.LA(<k>);
    909 <edges; separator="\nelse ">
    910 <if((!isTrue.(last(edges).labelExpr)) && (!last(edges).predicates))>
    911 else {
    912 <if(eotPredictsAlt)>
    913 	alt<decisionNumber>=<eotPredictsAlt>;
    914 <else>
    915 	<ruleBacktrackFailure()>
    916 	<(nvaExceptionWrapperMap.(k))({NoViableAltException nvae =
    917 	new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);
    918 <@noViableAltException()>
    919 throw nvae;})>
    920 <endif>
    921 }
    922 <endif>
    923 >>
    924 
    925 nvaExceptionWrapperMap ::= [
    926 	"1":"wrapNvaExceptionForK1",
    927 	"2":"wrapNvaExceptionForK2",
    928 	default:"wrapNvaExceptionForKN"
    929 ]
    930 
    931 wrapNvaExceptionForK1(exceptionCode) ::= <<
    932 <exceptionCode>
    933 >>
    934 
    935 wrapNvaExceptionForK2(exceptionCode) ::= <<
    936 int nvaeMark = input.mark();
    937 try {
    938 	input.consume();
    939 	<exceptionCode>
    940 } finally {
    941 	input.rewind(nvaeMark);
    942 }
    943 >>
    944 
    945 wrapNvaExceptionForKN(exceptionCode) ::= <<
    946 int nvaeMark = input.mark();
    947 try {
    948 	for (int nvaeConsume = 0; nvaeConsume \< <k> - 1; nvaeConsume++) {
    949 		input.consume();
    950 	}
    951 	<exceptionCode>
    952 } finally {
    953 	input.rewind(nvaeMark);
    954 }
    955 >>
    956 
    957 /** Same as a normal DFA state except that we don't examine lookahead
    958  *  for the bypass alternative.  It delays error detection but this
    959  *  is faster, smaller, and more what people expect.  For (X)? people
    960  *  expect "if ( LA(1)==X ) match(X);" and that's it.
    961  */
    962 dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    963 int LA<decisionNumber>_<stateNumber> = input.LA(<k>);
    964 <edges; separator="\nelse ">
    965 >>
    966 
    967 /** A DFA state that is actually the loopback decision of a closure
    968  *  loop.  If end-of-token (EOT) predicts any of the targets then it
    969  *  should act like a default clause (i.e., no error can be generated).
    970  *  This is used only in the lexer so that for ('a')* on the end of a rule
    971  *  anything other than 'a' predicts exiting.
    972  */
    973 dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
    974 int LA<decisionNumber>_<stateNumber> = input.LA(<k>);
    975 <edges; separator="\nelse ">
    976 <if(eotPredictsAlt)>
    977 <if(!edges)>
    978 alt<decisionNumber>=<eotPredictsAlt>; <! if no edges, don't gen ELSE !>
    979 <else>
    980 else {
    981 	alt<decisionNumber>=<eotPredictsAlt>;
    982 }
    983 <endif>
    984 <endif>
    985 >>
    986 
    987 /** An accept state indicates a unique alternative has been predicted */
    988 dfaAcceptState(alt) ::= "alt<decisionNumber>=<alt>;"
    989 
    990 /** A simple edge with an expression.  If the expression is satisfied,
    991  *  enter to the target state.  To handle gated productions, we may
    992  *  have to evaluate some predicates for this edge.
    993  */
    994 dfaEdge(labelExpr, targetState, predicates) ::= <<
    995 if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>) {
    996 	<targetState>
    997 }
    998 >>
    999 
   1000 // F i x e d  D F A  (switch case)
   1001 
   1002 /** A DFA state where a SWITCH may be generated.  The code generator
   1003  *  decides if this is possible: CodeGenerator.canGenerateSwitch().
   1004  */
   1005 dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1006 switch ( input.LA(<k>) ) {
   1007 <edges; separator="\n">
   1008 default:
   1009 <if(eotPredictsAlt)>
   1010 	alt<decisionNumber>=<eotPredictsAlt>;
   1011 <else>
   1012 	<ruleBacktrackFailure()>
   1013 	<(nvaExceptionWrapperMap.(k))({NoViableAltException nvae =
   1014 	new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);
   1015 <@noViableAltException()>
   1016 throw nvae;})>
   1017 <endif>
   1018 }
   1019 >>
   1020 
   1021 dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1022 switch ( input.LA(<k>) ) {
   1023 	<edges; separator="\n">
   1024 }
   1025 >>
   1026 
   1027 dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1028 switch ( input.LA(<k>) ) {
   1029 <edges; separator="\n">
   1030 <if(eotPredictsAlt)>
   1031 default:
   1032 	alt<decisionNumber>=<eotPredictsAlt>;
   1033 	break;
   1034 <endif>
   1035 }
   1036 >>
   1037 
   1038 dfaEdgeSwitch(labels, targetState) ::= <<
   1039 <labels:{it |case <it>:}; separator="\n">
   1040 	{
   1041 	<targetState>
   1042 	}
   1043 	break;
   1044 >>
   1045 
   1046 // C y c l i c  D F A
   1047 
   1048 /** The code to initiate execution of a cyclic DFA; this is used
   1049  *  in the rule to predict an alt just like the fixed DFA case.
   1050  *  The <name> attribute is inherited via the parser, lexer, ...
   1051  */
   1052 dfaDecision(decisionNumber,description) ::= <<
   1053 alt<decisionNumber> = dfa<decisionNumber>.predict(input);
   1054 >>
   1055 
   1056 /* Dump DFA tables as run-length-encoded Strings of octal values.
   1057  * Can't use hex as compiler translates them before compilation.
   1058  * These strings are split into multiple, concatenated strings.
   1059  * Java puts them back together at compile time thankfully.
   1060  * Java cannot handle large static arrays, so we're stuck with this
   1061  * encode/decode approach.  See analysis and runtime DFA for
   1062  * the encoding methods.
   1063  */
   1064 cyclicDFA(dfa) ::= <<
   1065 static final String DFA<dfa.decisionNumber>_eotS =
   1066 	"<dfa.javaCompressedEOT; wrap="\"+\n\t\"">";
   1067 static final String DFA<dfa.decisionNumber>_eofS =
   1068 	"<dfa.javaCompressedEOF; wrap="\"+\n\t\"">";
   1069 static final String DFA<dfa.decisionNumber>_minS =
   1070 	"<dfa.javaCompressedMin; wrap="\"+\n\t\"">";
   1071 static final String DFA<dfa.decisionNumber>_maxS =
   1072 	"<dfa.javaCompressedMax; wrap="\"+\n\t\"">";
   1073 static final String DFA<dfa.decisionNumber>_acceptS =
   1074 	"<dfa.javaCompressedAccept; wrap="\"+\n\t\"">";
   1075 static final String DFA<dfa.decisionNumber>_specialS =
   1076 	"<dfa.javaCompressedSpecial; wrap="\"+\n\t\"">}>";
   1077 static final String[] DFA<dfa.decisionNumber>_transitionS = {
   1078 		<dfa.javaCompressedTransition:{s|"<s; wrap="\"+\n\"">"}; separator=",\n">
   1079 };
   1080 
   1081 static final short[] DFA<dfa.decisionNumber>_eot = DFA.unpackEncodedString(DFA<dfa.decisionNumber>_eotS);
   1082 static final short[] DFA<dfa.decisionNumber>_eof = DFA.unpackEncodedString(DFA<dfa.decisionNumber>_eofS);
   1083 static final char[] DFA<dfa.decisionNumber>_min = DFA.unpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_minS);
   1084 static final char[] DFA<dfa.decisionNumber>_max = DFA.unpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_maxS);
   1085 static final short[] DFA<dfa.decisionNumber>_accept = DFA.unpackEncodedString(DFA<dfa.decisionNumber>_acceptS);
   1086 static final short[] DFA<dfa.decisionNumber>_special = DFA.unpackEncodedString(DFA<dfa.decisionNumber>_specialS);
   1087 static final short[][] DFA<dfa.decisionNumber>_transition;
   1088 
   1089 static {
   1090 	int numStates = DFA<dfa.decisionNumber>_transitionS.length;
   1091 	DFA<dfa.decisionNumber>_transition = new short[numStates][];
   1092 	for (int i=0; i\<numStates; i++) {
   1093 		DFA<dfa.decisionNumber>_transition[i] = DFA.unpackEncodedString(DFA<dfa.decisionNumber>_transitionS[i]);
   1094 	}
   1095 }
   1096 
   1097 protected class DFA<dfa.decisionNumber> extends DFA {
   1098 
   1099 	public DFA<dfa.decisionNumber>(BaseRecognizer recognizer) {
   1100 		this.recognizer = recognizer;
   1101 		this.decisionNumber = <dfa.decisionNumber>;
   1102 		this.eot = DFA<dfa.decisionNumber>_eot;
   1103 		this.eof = DFA<dfa.decisionNumber>_eof;
   1104 		this.min = DFA<dfa.decisionNumber>_min;
   1105 		this.max = DFA<dfa.decisionNumber>_max;
   1106 		this.accept = DFA<dfa.decisionNumber>_accept;
   1107 		this.special = DFA<dfa.decisionNumber>_special;
   1108 		this.transition = DFA<dfa.decisionNumber>_transition;
   1109 	}
   1110 	@Override
   1111 	public String getDescription() {
   1112 		return "<dfa.description>";
   1113 	}
   1114 	<@errorMethod()>
   1115 <if(dfa.specialStateSTs)>
   1116 	@Override
   1117 	public int specialStateTransition(int s, IntStream _input) throws NoViableAltException {
   1118 		<if(LEXER)>
   1119 		IntStream input = _input;
   1120 		<endif>
   1121 		<if(PARSER)>
   1122 		TokenStream input = (TokenStream)_input;
   1123 		<endif>
   1124 		<if(TREE_PARSER)>
   1125 		TreeNodeStream input = (TreeNodeStream)_input;
   1126 		<endif>
   1127 		int _s = s;
   1128 		switch ( s ) {
   1129 		<dfa.specialStateSTs:{state |
   1130 		case <i0> : <! compressed special state numbers 0..n-1 !>
   1131 			<state>}; separator="\n">
   1132 		}
   1133 <if(backtracking)>
   1134 		if (state.backtracking>0) {state.failed=true; return -1;}
   1135 <endif>
   1136 		NoViableAltException nvae =
   1137 			new NoViableAltException(getDescription(), <dfa.decisionNumber>, _s, input);
   1138 		error(nvae);
   1139 		throw nvae;
   1140 	}
   1141 <endif>
   1142 }
   1143 >>
   1144 
   1145 /** A state in a cyclic DFA; it's a special state and part of a big switch on
   1146  *  state.
   1147  */
   1148 cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<
   1149 int LA<decisionNumber>_<stateNumber> = input.LA(1);
   1150 <if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>
   1151 int index<decisionNumber>_<stateNumber> = input.index();
   1152 input.rewind();
   1153 <endif>
   1154 s = -1;
   1155 <edges; separator="\nelse ">
   1156 <if(semPredState)> <! return input cursor to state before we rewound !>
   1157 input.seek(index<decisionNumber>_<stateNumber>);
   1158 <endif>
   1159 if ( s>=0 ) return s;
   1160 break;
   1161 >>
   1162 
   1163 /** Just like a fixed DFA edge, test the lookahead and indicate what
   1164  *  state to jump to next if successful.
   1165  */
   1166 cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
   1167 if ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>) {s = <targetStateNumber>;}
   1168 >>
   1169 
   1170 /** An edge pointing at end-of-token; essentially matches any char;
   1171  *  always jump to the target.
   1172  */
   1173 eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= <<
   1174 s = <targetStateNumber>;
   1175 >>
   1176 
   1177 
   1178 // D F A  E X P R E S S I O N S
   1179 
   1180 andPredicates(left,right) ::= "(<left>&&<right>)"
   1181 
   1182 orPredicates(operands) ::= "(<operands; separator=\"||\">)"
   1183 
   1184 notPredicate(pred) ::= "!(<evalPredicate(pred,{})>)"
   1185 
   1186 evalPredicate(pred,description) ::= "(<pred>)"
   1187 
   1188 evalSynPredicate(pred,description) ::= "<pred>()"
   1189 
   1190 lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>"
   1191 
   1192 /** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
   1193  *  somewhere.  Must ask for the lookahead directly.
   1194  */
   1195 isolatedLookaheadTest(atom,k,atomAsInt) ::= "input.LA(<k>)==<atom>"
   1196 
   1197 lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <%
   1198 (LA<decisionNumber>_<stateNumber> >= <lower> && LA<decisionNumber>_<stateNumber> \<= <upper>)
   1199 %>
   1200 
   1201 isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>) >= <lower> && input.LA(<k>) \<= <upper>)"
   1202 
   1203 setTest(ranges) ::= <<
   1204 <ranges; separator="||">
   1205 >>
   1206 
   1207 // A T T R I B U T E S
   1208 
   1209 globalAttributeScope(scope) ::= <<
   1210 <if(scope.attributes)>
   1211 protected static class <scope.name>_scope {
   1212 	<scope.attributes:{it |<it.decl>;}; separator="\n">
   1213 }
   1214 protected Stack\<<scope.name>_scope> <scope.name>_stack = new Stack\<<scope.name>_scope>();
   1215 <endif>
   1216 >>
   1217 
   1218 ruleAttributeScope(scope) ::= <<
   1219 <if(scope)>
   1220 <if(scope.attributes)>
   1221 protected static class <scope.name>_scope {
   1222 	<scope.attributes:{it |<it.decl>;}; separator="\n">
   1223 }
   1224 protected Stack\<<scope.name>_scope> <scope.name>_stack = new Stack\<<scope.name>_scope>();
   1225 <endif>
   1226 <endif>
   1227 >>
   1228 
   1229 returnStructName(r) ::= "<r.name>_return"
   1230 
   1231 returnType(ruleDescriptor) ::= <%
   1232 <if(ruleDescriptor.hasMultipleReturnValues)>
   1233 <ruleDescriptor.grammar.recognizerName>.<ruleDescriptor:returnStructName()>
   1234 <elseif(ruleDescriptor.hasSingleReturnValue)>
   1235 <ruleDescriptor.singleValueReturnType>
   1236 <else>
   1237 void
   1238 <endif>
   1239 %>
   1240 
   1241 /** Generate the Java type associated with a single or multiple return
   1242  *  values.
   1243  */
   1244 ruleLabelType(referencedRule) ::= <%
   1245 <if(referencedRule.hasMultipleReturnValues)>
   1246 <returnScopeBaseType()>
   1247 <elseif(referencedRule.hasSingleReturnValue)>
   1248 <referencedRule.singleValueReturnType>
   1249 <else>
   1250 void
   1251 <endif>
   1252 %>
   1253 
   1254 delegateName(d) ::= <<
   1255 <if(d.label)><d.label><else>g<d.name><endif>
   1256 >>
   1257 
   1258 /** Using a type to init value map, try to init a type; if not in table
   1259  *  must be an object, default value is "null".
   1260  */
   1261 initValue(typeName) ::= <<
   1262 <javaTypeInitMap.(typeName)>
   1263 >>
   1264 
   1265 /** Define a rule label including default value */
   1266 ruleLabelDef(label) ::= <%
   1267 <ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> =
   1268  <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;
   1269 %>
   1270 
   1271 /** Define a return struct for a rule if the code needs to access its
   1272  *  start/stop tokens, tree stuff, attributes, ...  Leave a hole for
   1273  *  subgroups to stick in members.
   1274  */
   1275 returnScope(scope) ::= <<
   1276 <if(ruleDescriptor.hasMultipleReturnValues)>
   1277 public static class <ruleDescriptor:returnStructName()> extends <returnScopeBaseType()> {
   1278 	<if(scope)><scope.attributes:{it |public <it.decl>;}; separator="\n"><endif>
   1279 	<@ruleReturnMembers()>
   1280 };
   1281 <endif>
   1282 >>
   1283 
   1284 returnScopeBaseType() ::= <%
   1285 <if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope
   1286 %>
   1287 
   1288 parameterScope(scope) ::= <<
   1289 <scope.attributes:{it |<it.decl>}; separator=", ">
   1290 >>
   1291 
   1292 parameterAttributeRef(attr) ::= "<attr.name>"
   1293 parameterSetAttributeRef(attr,expr) ::= "<attr.name> =<expr>;"
   1294 
   1295 scopeAttributeRef(scope,attr,index,negIndex) ::= <%
   1296 <if(negIndex)>
   1297 <scope>_stack.elementAt(<scope>_stack.size()-<negIndex>-1).<attr.name>
   1298 <else>
   1299 <if(index)>
   1300 <scope>_stack.elementAt(<index>).<attr.name>
   1301 <else>
   1302 <scope>_stack.peek().<attr.name>
   1303 <endif>
   1304 <endif>
   1305 %>
   1306 
   1307 scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <%
   1308 <if(negIndex)>
   1309 <scope>_stack.elementAt(<scope>_stack.size()-<negIndex>-1).<attr.name> =<expr>;
   1310 <else>
   1311 <if(index)>
   1312 <scope>_stack.elementAt(<index>).<attr.name> =<expr>;
   1313 <else>
   1314 <scope>_stack.peek().<attr.name> =<expr>;
   1315 <endif>
   1316 <endif>
   1317 %>
   1318 
   1319 /** $x is either global scope or x is rule with dynamic scope; refers
   1320  *  to stack itself not top of stack.  This is useful for predicates
   1321  *  like {$function.size()>0 && $function::name.equals("foo")}?
   1322  */
   1323 isolatedDynamicScopeRef(scope) ::= "<scope>_stack"
   1324 
   1325 /** reference an attribute of rule; might only have single return value */
   1326 ruleLabelRef(referencedRule,scope,attr) ::= <%
   1327 <if(referencedRule.hasMultipleReturnValues)>
   1328 (<scope>!=null?((<returnType(referencedRule)>)<scope>).<attr.name>:<initValue(attr.type)>)
   1329 <else>
   1330 <scope>
   1331 <endif>
   1332 %>
   1333 
   1334 returnAttributeRef(ruleDescriptor,attr) ::= <%
   1335 <if(ruleDescriptor.hasMultipleReturnValues)>
   1336 retval.<attr.name>
   1337 <else>
   1338 <attr.name>
   1339 <endif>
   1340 %>
   1341 
   1342 returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <%
   1343 <if(ruleDescriptor.hasMultipleReturnValues)>
   1344 retval.<attr.name> =<expr>;
   1345 <else>
   1346 <attr.name> =<expr>;
   1347 <endif>
   1348 %>
   1349 
   1350 /** How to translate $tokenLabel */
   1351 tokenLabelRef(label) ::= "<label>"
   1352 
   1353 /** ids+=ID {$ids} or e+=expr {$e} */
   1354 listLabelRef(label) ::= "list_<label>"
   1355 
   1356 
   1357 // not sure the next are the right approach
   1358 
   1359 tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=null?<scope>.getText():null)"
   1360 tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=null?<scope>.getType():0)"
   1361 tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=null?<scope>.getLine():0)"
   1362 tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=null?<scope>.getCharPositionInLine():0)"
   1363 tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=null?<scope>.getChannel():0)"
   1364 tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=null?<scope>.getTokenIndex():0)"
   1365 tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
   1366 tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=null?Integer.valueOf(<scope>.getText()):0)"
   1367 
   1368 ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=null?(<castToLabelType({<scope>.start})>):null)"
   1369 ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=null?(<castToLabelType({<scope>.stop})>):null)"
   1370 ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=null?((<ASTLabelType>)<scope>.getTree()):null)"
   1371 ruleLabelPropertyRef_text(scope,attr) ::= <%
   1372 <if(TREE_PARSER)>
   1373 (<scope>!=null?(input.getTokenStream().toString(
   1374   input.getTreeAdaptor().getTokenStartIndex(<scope>.start),
   1375   input.getTreeAdaptor().getTokenStopIndex(<scope>.start))):null)
   1376 <else>
   1377 (<scope>!=null?input.toString(<scope>.start,<scope>.stop):null)
   1378 <endif>
   1379 %>
   1380 
   1381 ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=null?((StringTemplate)<scope>.getTemplate()):null)"
   1382 
   1383 /** Isolated $RULE ref ok in lexer as it's a Token */
   1384 lexerRuleLabel(label) ::= "<label>"
   1385 
   1386 lexerRuleLabelPropertyRef_type(scope,attr) ::=
   1387 	"(<scope>!=null?<scope>.getType():0)"
   1388 lexerRuleLabelPropertyRef_line(scope,attr) ::=
   1389 	"(<scope>!=null?<scope>.getLine():0)"
   1390 lexerRuleLabelPropertyRef_pos(scope,attr) ::=
   1391 	"(<scope>!=null?<scope>.getCharPositionInLine():-1)"
   1392 lexerRuleLabelPropertyRef_channel(scope,attr) ::=
   1393 	"(<scope>!=null?<scope>.getChannel():0)"
   1394 lexerRuleLabelPropertyRef_index(scope,attr) ::=
   1395 	"(<scope>!=null?<scope>.getTokenIndex():0)"
   1396 lexerRuleLabelPropertyRef_text(scope,attr) ::=
   1397 	"(<scope>!=null?<scope>.getText():null)"
   1398 lexerRuleLabelPropertyRef_int(scope,attr) ::=
   1399 	"(<scope>!=null?Integer.valueOf(<scope>.getText()):0)"
   1400 
   1401 // Somebody may ref $template or $tree or $stop within a rule:
   1402 rulePropertyRef_start(scope,attr) ::= "(<castToLabelType(\"retval.start\")>)"
   1403 rulePropertyRef_stop(scope,attr) ::= "(<castToLabelType(\"retval.stop\")>)"
   1404 rulePropertyRef_tree(scope,attr) ::= "retval.tree"
   1405 rulePropertyRef_text(scope,attr) ::= <%
   1406 <if(TREE_PARSER)>
   1407 input.getTokenStream().toString(
   1408   input.getTreeAdaptor().getTokenStartIndex(retval.start),
   1409   input.getTreeAdaptor().getTokenStopIndex(retval.start))
   1410 <else>
   1411 input.toString(retval.start,input.LT(-1))
   1412 <endif>
   1413 %>
   1414 rulePropertyRef_st(scope,attr) ::= "retval.st"
   1415 
   1416 lexerRulePropertyRef_text(scope,attr) ::= "getText()"
   1417 lexerRulePropertyRef_type(scope,attr) ::= "_type"
   1418 lexerRulePropertyRef_line(scope,attr) ::= "state.tokenStartLine"
   1419 lexerRulePropertyRef_pos(scope,attr) ::= "state.tokenStartCharPositionInLine"
   1420 lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
   1421 lexerRulePropertyRef_channel(scope,attr) ::= "_channel"
   1422 lexerRulePropertyRef_start(scope,attr) ::= "state.tokenStartCharIndex"
   1423 lexerRulePropertyRef_stop(scope,attr) ::= "(getCharIndex()-1)"
   1424 lexerRulePropertyRef_int(scope,attr) ::= "Integer.valueOf(<scope>.getText())"
   1425 
   1426 // setting $st and $tree is allowed in local rule. everything else
   1427 // is flagged as error
   1428 ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.tree =<expr>;"
   1429 ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.st =<expr>;"
   1430 
   1431 /** How to execute an action (only when not backtracking) */
   1432 execAction(action) ::= <%
   1433 <if(backtracking)>
   1434 if ( <actions.(actionScope).synpredgate> ) {
   1435   <action>
   1436 }
   1437 <else>
   1438 <action>
   1439 <endif>
   1440 %>
   1441 
   1442 /** How to always execute an action even when backtracking */
   1443 execForcedAction(action) ::= "<action>"
   1444 
   1445 // M I S C (properties, etc...)
   1446 
   1447 bitset(name, words64) ::= <<
   1448 public static final BitSet <name> = new BitSet(new long[]{<words64:{it |<it>L};separator=",">});
   1449 >>
   1450 
   1451 codeFileExtension() ::= ".java"
   1452 
   1453 true_value() ::= "true"
   1454 false_value() ::= "false"
   1455 
   1456 isEmptyString ::= [
   1457 	"" : true,
   1458 	default : false
   1459 ]
   1460 
   1461 isTrue ::= [
   1462 	"true" : true,
   1463 	default : false
   1464 ]
   1465 
   1466 isDefaultLabelType ::= [
   1467 	"Token" : true,
   1468 	default : false
   1469 ]
   1470 
   1471 isPredefinedRewriteRule ::= [
   1472 	"topdown" : true,
   1473 	"bottomup" : true,
   1474 	default : false
   1475 ]
   1476 
   1477 castToLabelType(value) ::= <%
   1478 <if(!isDefaultLabelType.(labelType))>
   1479 (<labelType>)
   1480 <endif>
   1481 <value>
   1482 %>
   1483