1/*
2 * [The "BSD license"]
3 * Copyright (c) 2007-2008 Johannes Luber
4 * Copyright (c) 2005-2007 Kunle Odutola
5 * Copyright (c) 2011 Sam Harwell
6 * Copyright (c) 2011 Terence Parr
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32csharpVisibilityMap ::= [
33	"private":"private",
34	"protected":"protected",
35	"public":"public",
36	"fragment":"private",
37	default:"private"
38]
39
40/** The overall file structure of a recognizer; stores methods for rules
41 *  and cyclic DFAs plus support code.
42 */
43outputFile(	LEXER,PARSER,TREE_PARSER, actionScope, actions,
44			docComment, recognizer,
45			name, tokens, tokenNames, rules, cyclicDFAs,
46			bitsets, buildTemplate, buildAST, rewriteMode, profile,
47			backtracking, synpreds, memoize, numRules,
48			fileName, ANTLRVersion, generatedTimestamp, trace,
49			scopes, superClass, literals) ::=
50<<
51//------------------------------------------------------------------------------
52// \<auto-generated>
53//     This code was generated by a tool.
54//     ANTLR Version: <ANTLRVersion>
55//
56//     Changes to this file may cause incorrect behavior and will be lost if
57//     the code is regenerated.
58// \</auto-generated>
59//------------------------------------------------------------------------------
60
61// $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>
62
63<if(trace)>
64#define ANTLR_TRACE
65<endif>
66<@debugPreprocessor()>
67// The variable 'variable' is assigned but its value is never used.
68#pragma warning disable 168, 219
69// Unreachable code detected.
70#pragma warning disable 162
71// Missing XML comment for publicly visible type or member 'Type_or_Member'
72#pragma warning disable 1591
73
74<actions.(actionScope).header>
75
76<@imports>
77using System.Collections.Generic;
78using Antlr.Runtime;
79using Antlr.Runtime.Misc;
80<if(TREE_PARSER)>
81using Antlr.Runtime.Tree;
82using RewriteRuleITokenStream = Antlr.Runtime.Tree.RewriteRuleTokenStream;
83<endif>
84using ConditionalAttribute = System.Diagnostics.ConditionalAttribute;
85<@end>
86<if(actions.(actionScope).namespace)>
87namespace <actions.(actionScope).namespace>
88{
89<endif>
90<docComment>
91<recognizer>
92<if(actions.(actionScope).namespace)>
93
94} // namespace <actions.(actionScope).namespace>
95<endif>
96>>
97
98lexerInputStreamType() ::= <<
99<actions.(actionScope).inputStreamType; null="ICharStream">
100>>
101
102lexer(grammar, name, tokens, scopes, rules, numRules, filterMode, labelType="CommonToken",
103      superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Lexer<endif>}) ::= <<
104[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<ANTLRVersion>")]
105[System.CLSCompliant(false)]
106<parserModifier(grammar=grammar, actions=actions)> partial class <grammar.recognizerName> : <@superClassName><superClass><@end>
107{
108	<tokens:{it|public const int <it.name; format="id">=<it.type>;}; separator="\n">
109	<scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
110	<actions.lexer.members>
111
112    // delegates
113    <grammar.delegates:
114         {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
115    // delegators
116    <grammar.delegators:
117         {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
118    <last(grammar.delegators):{g|private <g.recognizerName> gParent;}>
119
120	<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>()<! needed by subclasses !>
121	{
122		OnCreated();
123	}
124
125	<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<lexerInputStreamType()> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}> )
126		: this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>)
127	{
128	}
129
130	<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<lexerInputStreamType()> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
131		: base(input, state)
132	{
133<if(memoize)>
134<if(grammar.grammarIsRoot)>
135		state.ruleMemo = new System.Collections.Generic.Dictionary\<int, int>[<numRules>+1];<\n><! index from 1..n !>
136<endif>
137<endif>
138		<grammar.directDelegates:
139		 {g|<g:delegateName()> = new <g.recognizerName>(input, this.state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
140		<grammar.delegators:
141		 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
142		<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
143
144		OnCreated();
145	}
146	public override string GrammarFileName { get { return "<fileName>"; } }
147
148	private static readonly bool[] decisionCanBacktrack = new bool[0];
149
150<if(grammar.hasDelegates)>
151	public override <lexerInputStreamType()> CharStream
152	{
153		get
154		{
155			return base.CharStream;
156		}
157		set
158		{
159			base.CharStream = value;
160			<grammar.directDelegates:
161			 {g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
162			<grammar.delegators:
163			 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
164			<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
165		}
166	}
167
168<endif>
169<if(filterMode)>
170	<filteringNextToken()>
171<endif>
172
173	[Conditional("ANTLR_TRACE")]
174	protected virtual void OnCreated() {}
175	[Conditional("ANTLR_TRACE")]
176	protected virtual void EnterRule(string ruleName, int ruleIndex) {}
177	[Conditional("ANTLR_TRACE")]
178	protected virtual void LeaveRule(string ruleName, int ruleIndex) {}
179
180    <rules; separator="\n">
181
182	<insertLexerSynpreds(synpreds)>
183
184	#region DFA
185	<cyclicDFAs:{dfa | DFA<dfa.decisionNumber> dfa<dfa.decisionNumber>;}; separator="\n">
186
187	protected override void InitDFAs()
188	{
189		base.InitDFAs();
190		<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>(this<if(dfa.specialStateSTs)>, SpecialStateTransition<dfa.decisionNumber><endif>);}; separator="\n">
191	}
192
193	<cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>
194	#endregion
195
196}
197>>
198
199/** A override of Lexer.nextToken() that backtracks over mTokens() looking
200 *  for matches.  No error can be generated upon error; just rewind, consume
201 *  a token and then try again.  backtracking needs to be set as well.
202 *  Make rule memoization happen only at levels above 1 as we start mTokens
203 *  at backtracking==1.
204 */
205filteringNextToken() ::= <<
206public override IToken NextToken()
207{
208	while (true)
209	{
210		if (input.LA(1) == CharStreamConstants.EndOfFile)
211		{
212			IToken eof = new CommonToken((ICharStream)input, CharStreamConstants.EndOfFile, TokenChannels.Default, input.Index, input.Index);
213			eof.Line = Line;
214			eof.CharPositionInLine = CharPositionInLine;
215			return eof;
216		}
217		state.token = null;
218		state.channel = TokenChannels.Default;
219		state.tokenStartCharIndex = input.Index;
220		state.tokenStartCharPositionInLine = input.CharPositionInLine;
221		state.tokenStartLine = input.Line;
222		state.text = null;
223		try
224		{
225			int m = input.Mark();
226			state.backtracking=1;<! means we won't throw slow exception !>
227			state.failed=false;
228			mTokens();
229			state.backtracking=0;
230			<! mTokens backtracks with synpred at backtracking==2
231			   and we set the synpredgate to allow actions at level 1. !>
232			if (state.failed)
233			{
234				input.Rewind(m);
235				input.Consume();<! advance one char and try again !>
236			}
237			else
238			{
239				Emit();
240				return state.token;
241			}
242		}
243		catch (RecognitionException re)
244		{
245			// shouldn't happen in backtracking mode, but...
246			ReportError(re);
247			Recover(re);
248		}
249	}
250}
251
252public override void Memoize(IIntStream input, int ruleIndex, int ruleStartIndex)
253{
254	if (state.backtracking > 1)
255		base.Memoize(input, ruleIndex, ruleStartIndex);
256}
257
258public override bool AlreadyParsedRule(IIntStream input, int ruleIndex)
259{
260	if (state.backtracking > 1)
261		return base.AlreadyParsedRule(input, ruleIndex);
262
263	return false;
264}
265>>
266
267actionGate() ::= "state.backtracking == 0"
268
269filteringActionGate() ::= "state.backtracking == 1"
270
271/** How to generate a parser */
272genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
273              bitsets, inputStreamType, superClass,
274              labelType, members, rewriteElementType,
275              filterMode, ASTLabelType="object") ::= <<
276[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<ANTLRVersion>")]
277[System.CLSCompliant(false)]
278<parserModifier(grammar=grammar, actions=actions)> partial class <grammar.recognizerName> : <@superClassName><superClass><@end>
279{
280<if(grammar.grammarIsRoot)>
281	internal static readonly string[] tokenNames = new string[] {
282		"\<invalid>", "\<EOR>", "\<DOWN>", "\<UP>", <tokenNames; separator=", ">
283	};
284<endif>
285	<tokens:{it|public const int <it.name; format="id">=<it.type>;}; separator="\n">
286
287<if(grammar.delegates)>
288	// delegates
289	<grammar.delegates:
290		 {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
291<endif>
292<if(grammar.delegators)>
293	// delegators
294	<grammar.delegators:
295		 {g|private <g.recognizerName> <g:delegateName()>;}; separator="\n">
296	<last(grammar.delegators):{g|private <g.recognizerName> gParent;}>
297<endif>
298
299	<scopes:{it|<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
300	<@members()>
301
302	public override string[] TokenNames { get { return <grammar.composite.rootGrammar.recognizerName>.tokenNames; } }
303	public override string GrammarFileName { get { return "<fileName>"; } }
304
305	<members>
306
307	[Conditional("ANTLR_TRACE")]
308	protected virtual void OnCreated() {}
309	[Conditional("ANTLR_TRACE")]
310	protected virtual void EnterRule(string ruleName, int ruleIndex) {}
311	[Conditional("ANTLR_TRACE")]
312	protected virtual void LeaveRule(string ruleName, int ruleIndex) {}
313
314	#region Rules
315	<rules; separator="\n">
316	#endregion Rules
317
318<if(grammar.delegatedRules)>
319<! generate rule/method definitions for imported rules so they
320   appear to be defined in this recognizer. !>
321	#region Delegated rules
322<grammar.delegatedRules:{ruleDescriptor|
323	<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> <returnType(ruleDescriptor)> <ruleDescriptor.name; format="id">(<ruleDescriptor.parameterScope:parameterScope()>) <!throws RecognitionException !>{ <if(ruleDescriptor.hasReturnValue)>return <endif><ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name; format="id">(<ruleDescriptor.parameterScope.attributes:{a|<a.name; format="id">}; separator=", ">); \}}; separator="\n">
324	#endregion Delegated rules
325<endif>
326
327	<insertSynpreds(synpreds)>
328
329<if(cyclicDFAs)>
330	#region DFA
331	<cyclicDFAs:{dfa | private DFA<dfa.decisionNumber> dfa<dfa.decisionNumber>;}; separator="\n">
332
333	protected override void InitDFAs()
334	{
335		base.InitDFAs();
336		<cyclicDFAs:{dfa | dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>( this<if(dfa.specialStateSTs)>, SpecialStateTransition<dfa.decisionNumber><endif> );}; separator="\n">
337	}
338
339	<cyclicDFAs:cyclicDFA()><! dump tables for all DFA !>
340	#endregion DFA
341<endif>
342
343<if(bitsets)>
344	#region Follow sets
345	private static class Follow
346	{
347		<bitsets:{it|<bitset(name={_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>}; separator="\n">
348	}
349	#endregion Follow sets
350<endif>
351}
352>>
353
354@genericParser.members() ::= <<
355#if ANTLR_DEBUG
356	private static readonly bool[] decisionCanBacktrack =
357		new bool[]
358		{
359			false, // invalid decision
360			<grammar.decisions:{d | <d.dfa.hasSynPred>}; wrap="\n", separator=", ">
361		};
362#else
363	private static readonly bool[] decisionCanBacktrack = new bool[0];
364#endif
365<! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !>
366<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<inputStreamType> input<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
367	: this(input, new RecognizerSharedState()<grammar.delegators:{g|, <g:delegateName()>}>)
368{
369}
370<actions.(actionScope).ctorModifier; null="public"> <grammar.recognizerName>(<inputStreamType> input, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
371	: base(input, state)
372{
373	<parserCtorBody()>
374<if(grammar.directDelegates)>
375	<grammar.directDelegates:
376	 {g|<g:delegateName()> = new <g.recognizerName>(input, state<trunc(g.delegators):{p|, <p:delegateName()>}>, this);}; separator="\n">
377<endif>
378<if(grammar.indirectDelegates)>
379	<grammar.indirectDelegates:{g | <g:delegateName()> = <g.delegator:delegateName()>.<g:delegateName()>;}; separator="\n">
380<endif>
381<if(grammar.delegators)>
382	<last(grammar.delegators):{g|gParent = <g:delegateName()>;}>
383<endif>
384	OnCreated();
385}
386>>
387
388// imported grammars are 'public' (can't be internal because their return scope classes must be accessible)
389parserModifier(grammar, actions) ::= <<
390<if(grammar.grammarIsRoot)><actions.(actionScope).modifier; null="public"><else>public<endif>
391>>
392
393parserCtorBody() ::= <<
394<if(memoize)>
395<if(grammar.grammarIsRoot)>
396this.state.ruleMemo = new System.Collections.Generic.Dictionary\<int, int>[<length(grammar.allImportedRules)>+1];<\n><! index from 1..n !>
397<endif>
398<endif>
399<grammar.delegators:
400 {g|this.<g:delegateName()> = <g:delegateName()>;}; separator="\n">
401>>
402
403parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets,
404       ASTLabelType="object", superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Parser<endif>}, labelType="IToken",
405       members={<actions.parser.members>}) ::= <<
406<genericParser(inputStreamType="ITokenStream", rewriteElementType="IToken", ...)>
407>>
408
409/** How to generate a tree parser; same as parser except the input
410 *  stream is a different type.
411 */
412treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules,
413           numRules, bitsets, filterMode, labelType={<ASTLabelType>}, ASTLabelType="object",
414           superClass={<if(actions.(actionScope).superClass)><actions.(actionScope).superClass><else>Antlr.Runtime.Tree.<if(filterMode)><if(buildAST)>TreeRewriter<else>TreeFilter<endif><else>TreeParser<endif><endif>},
415           members={<actions.treeparser.members>}) ::= <<
416<genericParser(inputStreamType="ITreeNodeStream", rewriteElementType="Node", ...)>
417>>
418
419/** A simpler version of a rule template that is specific to the imaginary
420 *  rules created for syntactic predicates.  As they never have return values
421 *  nor parameters etc..., just give simplest possible method.  Don't do
422 *  any of the normal memoization stuff in here either; it's a waste.
423 *  As predicates cannot be inlined into the invoking rule, they need to
424 *  be in a rule by themselves.
425 */
426synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::=
427<<
428[Conditional("ANTLR_TRACE")]
429protected virtual void EnterRule_<ruleName>_fragment() {}
430[Conditional("ANTLR_TRACE")]
431protected virtual void LeaveRule_<ruleName>_fragment() {}
432
433// $ANTLR start <ruleName>
434public <!final !>void <ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope()>)
435{
436	<ruleLabelDefs()>
437	EnterRule_<ruleName>_fragment();
438	EnterRule("<ruleName>_fragment", <ruleDescriptor.index>);
439	TraceIn("<ruleName>_fragment", <ruleDescriptor.index>);
440	try
441	{
442		<block>
443	}
444	finally
445	{
446		TraceOut("<ruleName>_fragment", <ruleDescriptor.index>);
447		LeaveRule("<ruleName>_fragment", <ruleDescriptor.index>);
448		LeaveRule_<ruleName>_fragment();
449	}
450}
451// $ANTLR end <ruleName>
452>>
453
454insertLexerSynpreds(synpreds) ::= <<
455<insertSynpreds(synpreds)>
456>>
457
458insertSynpreds(synpreds) ::= <<
459<if(synpreds)>
460#region Synpreds
461private bool EvaluatePredicate(System.Action fragment)
462{
463	bool success = false;
464	state.backtracking++;
465	<@start()>
466	try { DebugBeginBacktrack(state.backtracking);
467	int start = input.Mark();
468	try
469	{
470		fragment();
471	}
472	catch ( RecognitionException re )
473	{
474		System.Console.Error.WriteLine("impossible: "+re);
475	}
476	success = !state.failed;
477	input.Rewind(start);
478	} finally { DebugEndBacktrack(state.backtracking, success); }
479	<@stop()>
480	state.backtracking--;
481	state.failed=false;
482	return success;
483}
484#endregion Synpreds
485<endif>
486>>
487
488ruleMemoization(name) ::= <<
489<if(memoize)>
490if (state.backtracking > 0 && AlreadyParsedRule(input, <ruleDescriptor.index>)) { <returnFromRule()> }
491<endif>
492>>
493
494/** How to test for failure and return from rule */
495checkRuleBacktrackFailure() ::= <<
496<if(backtracking)>if (state.failed) <returnFromRule()><endif>
497>>
498
499/** This rule has failed, exit indicating failure during backtrack */
500ruleBacktrackFailure() ::= <<
501<if(backtracking)>if (state.backtracking>0) {state.failed=true; <returnFromRule()>}<endif>
502>>
503
504/** How to generate code for a rule.  This includes any return type
505 *  data aggregates required for multiple return values.
506 */
507rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<
508<ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
509<returnScope(ruleDescriptor.returnScope)>
510
511[Conditional("ANTLR_TRACE")]
512protected virtual void EnterRule_<ruleName>() {}
513[Conditional("ANTLR_TRACE")]
514protected virtual void LeaveRule_<ruleName>() {}
515
516// $ANTLR start "<ruleName>"
517// <fileName>:<description>
518[GrammarRule("<ruleName>")]
519<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> <returnType(ruleDescriptor)> <ruleName; format="id">(<ruleDescriptor.parameterScope:parameterScope()>)
520{
521	EnterRule_<ruleName>();
522	EnterRule("<ruleName>", <ruleDescriptor.index>);
523	TraceIn("<ruleName>", <ruleDescriptor.index>);
524    <ruleScopeSetUp()>
525    <ruleDeclarations()>
526    <ruleLabelDefs()>
527    <ruleDescriptor.actions.init>
528	try { DebugEnterRule(GrammarFileName, "<ruleName>");
529	DebugLocation(<ruleDescriptor.tree.line>, <ruleDescriptor.EORNode.charPositionInLine>);
530	<@preamble()>
531	try
532	{
533		<ruleMemoization(name=ruleName)>
534		<block>
535		<ruleCleanUp()>
536		<(ruleDescriptor.actions.after):execAction()>
537	}
538<if(exceptions)>
539	<exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
540<else>
541<if(!emptyRule)>
542<if(actions.(actionScope).rulecatch)>
543	<actions.(actionScope).rulecatch>
544<else>
545	catch (RecognitionException re)
546	{
547		ReportError(re);
548		Recover(input,re);
549	<@setErrorReturnValue()>
550	}
551<endif>
552<endif>
553<endif>
554	finally
555	{
556		TraceOut("<ruleName>", <ruleDescriptor.index>);
557		LeaveRule("<ruleName>", <ruleDescriptor.index>);
558		LeaveRule_<ruleName>();
559        <memoize()>
560        <ruleScopeCleanUp()>
561        <finally>
562    }
563 	DebugLocation(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.charPositionInLine>);
564	} finally { DebugExitRule(GrammarFileName, "<ruleName>"); }
565	<@postamble()>
566	<returnFromRule()><\n>
567}
568// $ANTLR end "<ruleName>"
569>>
570
571// imported grammars need to have internal rules
572ruleModifier(grammar,ruleDescriptor) ::= <<
573<if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>internal<endif>
574>>
575
576// imported grammars need to have public return scopes
577returnScopeModifier(grammar,ruleDescriptor) ::= <<
578<if(grammar.grammarIsRoot)><csharpVisibilityMap.(ruleDescriptor.modifier); null="private"><else>public<endif>
579>>
580
581catch(decl,action) ::= <<
582catch (<e.decl>)
583{
584	<e.action>
585}
586>>
587
588ruleDeclarations() ::= <<
589<if(ruleDescriptor.hasMultipleReturnValues)>
590<returnType(ruleDescriptor)> retval = new <returnType(ruleDescriptor)>();
591retval.Start = (<labelType>)input.LT(1);
592<else>
593<ruleDescriptor.returnScope.attributes:{ a |
594<a.type> <a.name; format="id"> = <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
595}>
596<endif>
597<if(memoize)>
598int <ruleDescriptor.name>_StartIndex = input.Index;
599<endif>
600>>
601
602ruleScopeSetUp() ::= <<
603<ruleDescriptor.useScopes:{it|<it>_stack.Push(new <it>_scope());<it>_scopeInit(<it>_stack.Peek());}; separator="\n">
604<ruleDescriptor.ruleScope:{it|<it.name>_stack.Push(new <it.name>_scope());<it.name>_scopeInit(<it.name>_stack.Peek());}; separator="\n">
605>>
606
607ruleScopeCleanUp() ::= <<
608<ruleDescriptor.useScopes:{it|<it>_scopeAfter(<it>_stack.Peek());<it>_stack.Pop();}; separator="\n">
609<ruleDescriptor.ruleScope:{it|<it.name>_scopeAfter(<it.name>_stack.Peek());<it.name>_stack.Pop();}; separator="\n">
610>>
611
612ruleLabelDefs() ::= <<
613<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels,ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels]
614    :{it|<labelType> <it.label.text> = default(<labelType>);}; separator="\n"
615>
616<ruleDescriptor.tokenListLabels
617    :{it|List\<<labelType>\> list_<it.label.text> = null;}; separator="\n"
618>
619<[ruleDescriptor.ruleListLabels,ruleDescriptor.wildcardTreeListLabels]
620    :{it|List\<<ASTLabelType>\> list_<it.label.text> = null;}; separator="\n"
621>
622<ruleDescriptor.ruleLabels:ruleLabelDef(); separator="\n">
623<ruleDescriptor.ruleListLabels:ruleLabelDef(); separator="\n">
624>>
625
626lexerRuleLabelDefs() ::= <<
627<[ruleDescriptor.tokenLabels,
628  ruleDescriptor.tokenListLabels,
629  ruleDescriptor.ruleLabels]
630    :{it|<labelType> <it.label.text> = default(<labelType>);}; separator="\n"
631>
632<[ruleDescriptor.charListLabels,
633  ruleDescriptor.charLabels]
634	:{it|int <it.label.text> = 0;}; separator="\n"
635>
636<[ruleDescriptor.tokenListLabels,
637  ruleDescriptor.ruleListLabels]
638    :{it|List\<<labelType>\> list_<it.label.text> = null;}; separator="\n"
639>
640<ruleDescriptor.charListLabels:{it|List\<int\> list_<it.label.text> = null;}; separator="\n"
641>
642>>
643
644returnFromRule() ::= <%
645return
646<if(!ruleDescriptor.isSynPred)>
647<if(ruleDescriptor.hasReturnValue)>
648<if(ruleDescriptor.hasSingleReturnValue)>
649<! This comment is a hack to make sure the following
650   single space appears in the output. !> <ruleDescriptor.singleValueReturnName>
651<else>
652<!!> retval
653<endif>
654<endif>
655<endif>
656;
657%>
658
659ruleCleanUp() ::= <<
660<if(ruleDescriptor.hasMultipleReturnValues)>
661<if(!TREE_PARSER)>
662retval.Stop = (<labelType>)input.LT(-1);
663<endif>
664<endif>
665>>
666
667memoize() ::= <<
668<if(memoize)>
669<if(backtracking)>
670if (state.backtracking > 0) { Memoize(input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex); }
671<endif>
672<endif>
673>>
674
675/** How to generate a rule in the lexer; naked blocks are used for
676 *  fragment rules.
677 */
678lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= <<
679
680[Conditional("ANTLR_TRACE")]
681protected virtual void EnterRule_<ruleName>() {}
682[Conditional("ANTLR_TRACE")]
683protected virtual void LeaveRule_<ruleName>() {}
684
685// $ANTLR start "<ruleName>"
686[GrammarRule("<ruleName>")]
687<ruleModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> void m<ruleName>(<ruleDescriptor.parameterScope:parameterScope()>)
688{
689	EnterRule_<ruleName>();
690	EnterRule("<ruleName>", <ruleDescriptor.index>);
691	TraceIn("<ruleName>", <ruleDescriptor.index>);
692    <ruleScopeSetUp()>
693    <ruleDeclarations()>
694		try
695		{
696<if(nakedBlock)>
697		<ruleMemoization(name=ruleName)>
698		<lexerRuleLabelDefs()>
699		<ruleDescriptor.actions.init>
700		<block>
701<else>
702		int _type = <ruleName>;
703		int _channel = DefaultTokenChannel;
704		<ruleMemoization(name=ruleName)>
705		<lexerRuleLabelDefs()>
706		<ruleDescriptor.actions.init>
707		<block>
708		<ruleCleanUp()>
709		state.type = _type;
710		state.channel = _channel;
711		<(ruleDescriptor.actions.after):execAction()>
712<endif>
713	}
714	finally
715	{
716		TraceOut("<ruleName>", <ruleDescriptor.index>);
717		LeaveRule("<ruleName>", <ruleDescriptor.index>);
718		LeaveRule_<ruleName>();
719        <ruleScopeCleanUp()>
720        <memoize()>
721    }
722}
723// $ANTLR end "<ruleName>"
724>>
725
726/** How to generate code for the implicitly-defined lexer grammar rule
727 *  that chooses between lexer rules.
728 */
729tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
730
731public override void mTokens()
732{
733	<block><\n>
734}
735>>
736
737// S U B R U L E S
738
739/** A (...) subrule with multiple alternatives */
740block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
741// <fileName>:<description>
742int alt<decisionNumber>=<maxAlt>;
743<decls>
744<@predecision()>
745try { DebugEnterSubRule(<decisionNumber>);
746try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
747<decision>
748} finally { DebugExitDecision(<decisionNumber>); }
749<@postdecision()>
750<@prebranch()>
751switch (alt<decisionNumber>)
752{
753<alts:{a|<altSwitchCase(i,a)>}>
754}
755} finally { DebugExitSubRule(<decisionNumber>); }
756<@postbranch()>
757>>
758
759/** A rule block with multiple alternatives */
760ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
761// <fileName>:<description>
762int alt<decisionNumber>=<maxAlt>;
763<decls>
764<@predecision()>
765try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
766<decision>
767} finally { DebugExitDecision(<decisionNumber>); }
768<@postdecision()>
769switch (alt<decisionNumber>)
770{
771<alts:{a|<altSwitchCase(i,a)>}>
772}
773>>
774
775ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
776// <fileName>:<description>
777<decls>
778<@prealt()>
779DebugEnterAlt(1);
780<alts>
781<@postalt()>
782>>
783
784/** A special case of a (...) subrule with a single alternative */
785blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
786// <fileName>:<description>
787<decls>
788<@prealt()>
789DebugEnterAlt(1);
790<alts>
791<@postalt()>
792>>
793
794/** A (..)+ block with 1 or more alternatives */
795positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
796// <fileName>:<description>
797int cnt<decisionNumber>=0;
798<decls>
799<@preloop()>
800try { DebugEnterSubRule(<decisionNumber>);
801while (true)
802{
803	int alt<decisionNumber>=<maxAlt>;
804	<@predecision()>
805	try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
806	<decision>
807	} finally { DebugExitDecision(<decisionNumber>); }
808	<@postdecision()>
809	switch (alt<decisionNumber>)
810	{
811	<alts:{a|<altSwitchCase(i,a)>}>
812	default:
813		if (cnt<decisionNumber> >= 1)
814			goto loop<decisionNumber>;
815
816		<ruleBacktrackFailure()>
817		EarlyExitException eee<decisionNumber> = new EarlyExitException( <decisionNumber>, input );
818		DebugRecognitionException(eee<decisionNumber>);
819		<@earlyExitException()>
820		throw eee<decisionNumber>;
821	}
822	cnt<decisionNumber>++;
823}
824loop<decisionNumber>:
825	;
826
827} finally { DebugExitSubRule(<decisionNumber>); }
828<@postloop()>
829>>
830
831positiveClosureBlockSingleAlt ::= positiveClosureBlock
832
833/** A (..)* block with 1 or more alternatives */
834closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
835// <fileName>:<description>
836<decls>
837<@preloop()>
838try { DebugEnterSubRule(<decisionNumber>);
839while (true)
840{
841	int alt<decisionNumber>=<maxAlt>;
842	<@predecision()>
843	try { DebugEnterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);
844	<decision>
845	} finally { DebugExitDecision(<decisionNumber>); }
846	<@postdecision()>
847	switch ( alt<decisionNumber> )
848	{
849	<alts:{a|<altSwitchCase(i,a)>}>
850	default:
851		goto loop<decisionNumber>;
852	}
853}
854
855loop<decisionNumber>:
856	;
857
858} finally { DebugExitSubRule(<decisionNumber>); }
859<@postloop()>
860>>
861
862closureBlockSingleAlt ::= closureBlock
863
864/** Optional blocks (x)? are translated to (x|) by before code generation
865 *  so we can just use the normal block template
866 */
867optionalBlock ::= block
868
869optionalBlockSingleAlt ::= block
870
871/** A case in a switch that jumps to an alternative given the alternative
872 *  number.  A DFA predicts the alternative and then a simple switch
873 *  does the jump to the code that actually matches that alternative.
874 */
875altSwitchCase(altNum,alt) ::= <<
876case <altNum>:
877	<@prealt()>
878	DebugEnterAlt(<altNum>);
879	<alt>
880	break;<\n>
881>>
882
883/** An alternative is just a list of elements; at outermost level */
884alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
885// <fileName>:<description>
886{
887<@declarations()>
888<elements:element()>
889<rew>
890<@cleanup()>
891}
892>>
893
894/** What to emit when there is no rewrite.  For auto build
895 *  mode, does nothing.
896 */
897noRewrite(rewriteBlockLevel, treeLevel) ::= ""
898
899// E L E M E N T S
900
901/** Dump the elements one per line */
902element(it) ::= <%
903<@prematch()>
904DebugLocation(<it.line>, <it.pos>);<\n>
905<it.el><\n>
906%>
907
908/** match a token optionally with a label in front */
909tokenRef(token,label,elementIndex,terminalOptions) ::= <<
910<if(label)><label>=(<labelType>)<endif>Match(input,<token>,Follow._<token>_in_<ruleName><elementIndex>); <checkRuleBacktrackFailure()>
911>>
912
913/** ids+=ID */
914tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
915<tokenRef(...)>
916<listLabelElem(elem=label,elemType=labelType,...)>
917>>
918
919listLabelElem(label,elem,elemType) ::= <<
920if (list_<label>==null) list_<label>=new List\<<elemType; null={<labelType>}>\>();
921list_<label>.Add(<elem>);<\n>
922>>
923
924/** match a character */
925charRef(char,label) ::= <<
926<if(label)>
927<label> = input.LA(1);<\n>
928<endif>
929Match(<char>); <checkRuleBacktrackFailure()>
930>>
931
932/** match a character range */
933charRangeRef(a,b,label) ::= <<
934<if(label)>
935<label> = input.LA(1);<\n>
936<endif>
937MatchRange(<a>,<b>); <checkRuleBacktrackFailure()>
938>>
939
940/** For now, sets are interval tests and must be tested inline */
941matchSet(s,label,terminalOptions,elementIndex,postmatchCode="") ::= <<
942<if(label)>
943<matchSetLabel()>
944<endif>
945if (<s>)
946{
947	input.Consume();
948	<postmatchCode>
949	<if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif>
950}
951else
952{
953	<ruleBacktrackFailure()>
954	MismatchedSetException mse = new MismatchedSetException(null,input);
955	DebugRecognitionException(mse);
956	<@mismatchedSetException()>
957<if(LEXER)>
958	Recover(mse);
959	throw mse;
960<else>
961	throw mse;
962	<! use following code to make it recover inline; remove throw mse;
963	recoverFromMismatchedSet(input,mse,Follow._set_in_<ruleName><elementIndex>);
964	!>
965<endif>
966}<\n>
967>>
968
969matchSetUnchecked(s,label,elementIndex,postmatchCode=false) ::= <%
970<if(label)>
971<matchSetLabel()><\n>
972<endif>
973input.Consume();<\n>
974<if(postmatchCode)>
975<postmatchCode><\n>
976<endif>
977<if(!LEXER)>state.errorRecovery=false;<endif><if(backtracking)>state.failed=false;<endif>
978%>
979
980matchSetLabel() ::= <%
981<if(LEXER)>
982<label>= input.LA(1);
983<else>
984<label>=(<labelType>)input.LT(1);
985<endif>
986%>
987
988matchRuleBlockSet ::= matchSet
989
990matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
991<matchSet(...)>
992<listLabelElem(elem=label,elemType=labelType,...)>
993>>
994
995/** Match a string literal */
996lexerStringRef(string,label,elementIndex) ::= <%
997<if(label)>
998int <label>Start = CharIndex;<\n>
999Match(<string>); <checkRuleBacktrackFailure()><\n>
1000int <label>StartLine<elementIndex> = Line;<\n>
1001int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n>
1002<label> = new <labelType>(input, TokenTypes.Invalid, TokenChannels.Default, <label>Start, CharIndex-1);<\n>
1003<label>.Line = <label>StartLine<elementIndex>;<\n>
1004<label>.CharPositionInLine = <label>StartCharPos<elementIndex>;
1005<else>
1006Match(<string>); <checkRuleBacktrackFailure()><\n>
1007<endif>
1008%>
1009
1010wildcard(token,label,elementIndex,terminalOptions) ::= <<
1011<if(label)>
1012<label>=(<labelType>)input.LT(1);<\n>
1013<endif>
1014MatchAny(input); <checkRuleBacktrackFailure()>
1015>>
1016
1017wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
1018<wildcard(...)>
1019<listLabelElem(elem=label,elemType=labelType,...)>
1020>>
1021
1022/** Match . wildcard in lexer */
1023wildcardChar(label, elementIndex) ::= <<
1024<if(label)>
1025<label> = input.LA(1);<\n>
1026<endif>
1027MatchAny(); <checkRuleBacktrackFailure()>
1028>>
1029
1030wildcardCharListLabel(label, elementIndex) ::= <<
1031<wildcardChar(...)>
1032<listLabelElem(elem=label,elemType=labelType,...)>
1033>>
1034
1035/** Match a rule reference by invoking it possibly with arguments
1036 *  and a return value or values.  The 'rule' argument was the
1037 *  target rule name, but now is type Rule, whose toString is
1038 *  same: the rule name.  Now though you can access full rule
1039 *  descriptor stuff.
1040 */
1041ruleRef(rule,label,elementIndex,args,scope) ::= <<
1042PushFollow(Follow._<rule.name>_in_<ruleName><elementIndex>);
1043<if(label)><label>=<endif><if(scope)><scope:delegateName()>.<endif><rule.name; format="id">(<args; separator=", ">);
1044PopFollow();
1045<checkRuleBacktrackFailure()>
1046>>
1047
1048/** ids+=r */
1049ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
1050<ruleRef(...)>
1051<listLabelElem(elem=label,elemType={<ASTLabelType>},...)>
1052>>
1053
1054/** A lexer rule reference.
1055 *
1056 *  The 'rule' argument was the target rule name, but now
1057 *  is type Rule, whose toString is same: the rule name.
1058 *  Now though you can access full rule descriptor stuff.
1059 */
1060lexerRuleRef(rule,label,args,elementIndex,scope) ::= <%
1061<if(label)>
1062int <label>Start<elementIndex> = CharIndex;<\n>
1063int <label>StartLine<elementIndex> = Line;<\n>
1064int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n>
1065<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()><\n>
1066<label> = new <labelType>(input, TokenTypes.Invalid, TokenChannels.Default, <label>Start<elementIndex>, CharIndex-1);<\n>
1067<label>.Line = <label>StartLine<elementIndex>;<\n>
1068<label>.CharPositionInLine = <label>StartCharPos<elementIndex>;
1069<else>
1070<if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
1071<endif>
1072%>
1073
1074/** i+=INT in lexer */
1075lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
1076<lexerRuleRef(...)>
1077<listLabelElem(elem=label,elemType=labelType,...)>
1078>>
1079
1080/** EOF in the lexer */
1081lexerMatchEOF(label,elementIndex) ::= <%
1082<if(label)>
1083int <label>Start<elementIndex> = CharIndex;<\n>
1084int <label>StartLine<elementIndex> = Line;<\n>
1085int <label>StartCharPos<elementIndex> = CharPositionInLine;<\n>
1086Match(EOF); <checkRuleBacktrackFailure()><\n>
1087<labelType> <label> = new <labelType>(input, EOF, TokenChannels.Default, <label>Start<elementIndex>, CharIndex-1);<\n>
1088<label>.Line = <label>StartLine<elementIndex>;<\n>
1089<label>.CharPositionInLine = <label>StartCharPos<elementIndex>;
1090<else>
1091Match(EOF); <checkRuleBacktrackFailure()>
1092<endif>
1093%>
1094
1095// used for left-recursive rules
1096recRuleDefArg()                       ::= "int <recRuleArg()>"
1097recRuleArg()                          ::= "_p"
1098recRuleAltPredicate(ruleName,opPrec)  ::= "<recRuleArg()> \<= <opPrec>"
1099recRuleSetResultAction()              ::= "root_0=$<ruleName>_primary.tree;"
1100recRuleSetReturnAction(src,name)      ::= "$<name>=$<src>.<name>;"
1101
1102/** match ^(root children) in tree parser */
1103tree(root, actionsAfterRoot, children, nullableChildList,
1104     enclosingTreeLevel, treeLevel) ::= <<
1105<root:element()>
1106<actionsAfterRoot:element()>
1107<if(nullableChildList)>
1108if (input.LA(1) == TokenTypes.Down)
1109{
1110	Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()>
1111	<children:element()>
1112	Match(input, TokenTypes.Up, null); <checkRuleBacktrackFailure()>
1113}
1114<else>
1115Match(input, TokenTypes.Down, null); <checkRuleBacktrackFailure()>
1116<children:element()>
1117Match(input, TokenTypes.Up, null); <checkRuleBacktrackFailure()>
1118<endif>
1119>>
1120
1121/** Every predicate is used as a validating predicate (even when it is
1122 *  also hoisted into a prediction expression).
1123 */
1124validateSemanticPredicate(pred,description) ::= <<
1125if (!(<evalPredicate(...)>))
1126{
1127	<ruleBacktrackFailure()>
1128	throw new FailedPredicateException(input, "<ruleName>", "<description>");
1129}
1130>>
1131
1132// F i x e d  D F A  (if-then-else)
1133
1134dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
1135int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
1136<edges; separator="\nelse ">
1137else
1138{
1139<if(eotPredictsAlt)>
1140	alt<decisionNumber> = <eotPredictsAlt>;
1141<else>
1142	<ruleBacktrackFailure()>
1143	NoViableAltException nvae = new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);
1144	DebugRecognitionException(nvae);
1145	<@noViableAltException()>
1146	throw nvae;
1147<endif>
1148}
1149>>
1150
1151/** Same as a normal DFA state except that we don't examine lookahead
1152 *  for the bypass alternative.  It delays error detection but this
1153 *  is faster, smaller, and more what people expect.  For (X)? people
1154 *  expect "if ( LA(1)==X ) match(X);" and that's it.
1155 */
1156dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
1157int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
1158<edges; separator="\nelse ">
1159>>
1160
1161/** A DFA state that is actually the loopback decision of a closure
1162 *  loop.  If end-of-token (EOT) predicts any of the targets then it
1163 *  should act like a default clause (i.e., no error can be generated).
1164 *  This is used only in the lexer so that for ('a')* on the end of a rule
1165 *  anything other than 'a' predicts exiting.
1166 */
1167dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
1168int LA<decisionNumber>_<stateNumber> = input.LA(<k>);<\n>
1169<edges; separator="\nelse "><\n>
1170<if(eotPredictsAlt)>
1171<if(!edges)>
1172alt<decisionNumber> = <eotPredictsAlt>;<! if no edges, don't gen ELSE !>
1173<else>
1174else
1175{
1176	alt<decisionNumber> = <eotPredictsAlt>;
1177}<\n>
1178<endif>
1179<endif>
1180>>
1181
1182/** An accept state indicates a unique alternative has been predicted */
1183dfaAcceptState(alt) ::= "alt<decisionNumber> = <alt>;"
1184
1185/** A simple edge with an expression.  If the expression is satisfied,
1186 *  enter to the target state.  To handle gated productions, we may
1187 *  have to evaluate some predicates for this edge.
1188 */
1189dfaEdge(labelExpr, targetState, predicates) ::= <<
1190if ((<labelExpr>)<if(predicates)> && (<predicates>)<endif>)
1191{
1192	<targetState>
1193}
1194>>
1195
1196// F i x e d  D F A  (switch case)
1197
1198/** A DFA state where a SWITCH may be generated.  The code generator
1199 *  decides if this is possible: CodeGenerator.canGenerateSwitch().
1200 */
1201dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
1202switch (input.LA(<k>))
1203{
1204<edges; separator="\n">
1205default:
1206<if(eotPredictsAlt)>
1207	alt<decisionNumber>=<eotPredictsAlt>;
1208	break;<\n>
1209<else>
1210	{
1211		<ruleBacktrackFailure()>
1212		NoViableAltException nvae = new NoViableAltException("<description>", <decisionNumber>, <stateNumber>, input);
1213		DebugRecognitionException(nvae);
1214		<@noViableAltException()>
1215		throw nvae;
1216	}
1217<endif>
1218}<\n>
1219>>
1220
1221dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
1222switch (input.LA(<k>))
1223{
1224<edges; separator="\n">
1225}<\n>
1226>>
1227
1228dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
1229switch (input.LA(<k>))
1230{
1231<edges; separator="\n">
1232<if(eotPredictsAlt)>
1233default:
1234	alt<decisionNumber>=<eotPredictsAlt>;
1235	break;<\n>
1236<endif>
1237}<\n>
1238>>
1239
1240dfaEdgeSwitch(labels, targetState) ::= <<
1241<labels:{it|case <it>:}; separator="\n">
1242	{
1243	<targetState>
1244	}
1245	break;
1246>>
1247
1248// C y c l i c  D F A
1249
1250/** The code to initiate execution of a cyclic DFA; this is used
1251 *  in the rule to predict an alt just like the fixed DFA case.
1252 *  The <name> attribute is inherited via the parser, lexer, ...
1253 */
1254dfaDecision(decisionNumber,description) ::= <<
1255try
1256{
1257	alt<decisionNumber> = dfa<decisionNumber>.Predict(input);
1258}
1259catch (NoViableAltException nvae)
1260{
1261	DebugRecognitionException(nvae);
1262	throw;
1263}
1264>>
1265
1266/* Dump DFA tables as run-length-encoded Strings of octal values.
1267 * Can't use hex as compiler translates them before compilation.
1268 * These strings are split into multiple, concatenated strings.
1269 * Java puts them back together at compile time thankfully.
1270 * Java cannot handle large static arrays, so we're stuck with this
1271 * encode/decode approach.  See analysis and runtime DFA for
1272 * the encoding methods.
1273 */
1274cyclicDFA(dfa) ::= <<
1275private class DFA<dfa.decisionNumber> : DFA
1276{
1277	private const string DFA<dfa.decisionNumber>_eotS =
1278		"<dfa.javaCompressedEOT; wrap="\"+\n\t\t\"">";
1279	private const string DFA<dfa.decisionNumber>_eofS =
1280		"<dfa.javaCompressedEOF; wrap="\"+\n\t\t\"">";
1281	private const string DFA<dfa.decisionNumber>_minS =
1282		"<dfa.javaCompressedMin; wrap="\"+\n\t\t\"">";
1283	private const string DFA<dfa.decisionNumber>_maxS =
1284		"<dfa.javaCompressedMax; wrap="\"+\n\t\t\"">";
1285	private const string DFA<dfa.decisionNumber>_acceptS =
1286		"<dfa.javaCompressedAccept; wrap="\"+\n\t\t\"">";
1287	private const string DFA<dfa.decisionNumber>_specialS =
1288		"<dfa.javaCompressedSpecial; wrap="\"+\n\t\t\"">}>";
1289	private static readonly string[] DFA<dfa.decisionNumber>_transitionS =
1290		{
1291			<dfa.javaCompressedTransition:{s|"<s; wrap="\"+\n\"">"}; separator=",\n">
1292		};
1293
1294	private static readonly short[] DFA<dfa.decisionNumber>_eot = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_eotS);
1295	private static readonly short[] DFA<dfa.decisionNumber>_eof = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_eofS);
1296	private static readonly char[] DFA<dfa.decisionNumber>_min = DFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_minS);
1297	private static readonly char[] DFA<dfa.decisionNumber>_max = DFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_maxS);
1298	private static readonly short[] DFA<dfa.decisionNumber>_accept = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_acceptS);
1299	private static readonly short[] DFA<dfa.decisionNumber>_special = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_specialS);
1300	private static readonly short[][] DFA<dfa.decisionNumber>_transition;
1301
1302	static DFA<dfa.decisionNumber>()
1303	{
1304		int numStates = DFA<dfa.decisionNumber>_transitionS.Length;
1305		DFA<dfa.decisionNumber>_transition = new short[numStates][];
1306		for ( int i=0; i \< numStates; i++ )
1307		{
1308			DFA<dfa.decisionNumber>_transition[i] = DFA.UnpackEncodedString(DFA<dfa.decisionNumber>_transitionS[i]);
1309		}
1310	}
1311
1312	public DFA<dfa.decisionNumber>( BaseRecognizer recognizer<if(dfa.specialStateSTs)>, SpecialStateTransitionHandler specialStateTransition<endif> )
1313<if(dfa.specialStateSTs)>
1314		: base(specialStateTransition)
1315<endif>
1316	{
1317		this.recognizer = recognizer;
1318		this.decisionNumber = <dfa.decisionNumber>;
1319		this.eot = DFA<dfa.decisionNumber>_eot;
1320		this.eof = DFA<dfa.decisionNumber>_eof;
1321		this.min = DFA<dfa.decisionNumber>_min;
1322		this.max = DFA<dfa.decisionNumber>_max;
1323		this.accept = DFA<dfa.decisionNumber>_accept;
1324		this.special = DFA<dfa.decisionNumber>_special;
1325		this.transition = DFA<dfa.decisionNumber>_transition;
1326	}
1327
1328	public override string Description { get { return "<dfa.description>"; } }
1329
1330	public override void Error(NoViableAltException nvae)
1331	{
1332		DebugRecognitionException(nvae);
1333	}
1334}<\n>
1335<if(dfa.specialStateSTs)>
1336private int SpecialStateTransition<dfa.decisionNumber>(DFA dfa, int s, IIntStream _input)<! throws NoViableAltException!>
1337{
1338	<if(LEXER)>
1339	IIntStream input = _input;
1340	<endif>
1341	<if(PARSER)>
1342	ITokenStream input = (ITokenStream)_input;
1343	<endif>
1344	<if(TREE_PARSER)>
1345	ITreeNodeStream input = (ITreeNodeStream)_input;
1346	<endif>
1347	int _s = s;
1348	switch (s)
1349	{
1350	<dfa.specialStateSTs:{state |
1351	case <i0>:<! compressed special state numbers 0..n-1 !>
1352		<state>}; separator="\n">
1353	}
1354<if(backtracking)>
1355	if (state.backtracking > 0) {state.failed=true; return -1;}
1356<endif>
1357	NoViableAltException nvae = new NoViableAltException(dfa.Description, <dfa.decisionNumber>, _s, input);
1358	dfa.Error(nvae);
1359	throw nvae;
1360}
1361<endif>
1362>>
1363
1364/** A state in a cyclic DFA; it's a special state and part of a big switch on
1365 *  state.
1366 */
1367cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<
1368int LA<decisionNumber>_<stateNumber> = input.LA(1);<\n>
1369<if(semPredState)>
1370<! get next lookahead symbol to test edges, then rewind !>
1371<\n>int index<decisionNumber>_<stateNumber> = input.Index;
1372input.Rewind();
1373<endif>
1374s = -1;
1375<edges; separator="\nelse ">
1376<if(semPredState)>
1377<! return input cursor to state before we rewound !>
1378<\n>input.Seek(index<decisionNumber>_<stateNumber>);
1379<endif>
1380if (s >= 0) return s;
1381break;
1382>>
1383
1384/** Just like a fixed DFA edge, test the lookahead and indicate what
1385 *  state to jump to next if successful.
1386 */
1387cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
1388if ((<labelExpr>)<if(predicates)> && (<predicates>)<endif>) {s = <targetStateNumber>;}<\n>
1389>>
1390
1391/** An edge pointing at end-of-token; essentially matches any char;
1392 *  always jump to the target.
1393 */
1394eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= <<
1395s = <targetStateNumber>;<\n>
1396>>
1397
1398
1399// D F A  E X P R E S S I O N S
1400
1401andPredicates(left,right) ::= "(<left>&&<right>)"
1402
1403orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)"
1404
1405notPredicate(pred) ::= "!(<evalPredicate(...)>)"
1406
1407evalPredicate(pred,description) ::= "(<pred>)"
1408
1409evalSynPredicate(pred,description) ::= "EvaluatePredicate(<pred>_fragment)"
1410
1411lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber>==<atom>"
1412
1413/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
1414 *  somewhere.  Must ask for the lookahead directly.
1415 */
1416isolatedLookaheadTest(atom,k,atomAsInt) ::= "input.LA(<k>)==<atom>"
1417
1418lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <%
1419(LA<decisionNumber>_<stateNumber><ge()><lower> && LA<decisionNumber>_<stateNumber><le()><upper>)
1420%>
1421
1422isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>)<ge()><lower> && input.LA(<k>)<le()><upper>)"
1423
1424le() ::= "\<="
1425ge() ::= ">="
1426
1427setTest(ranges) ::= <<
1428<ranges; separator="||">
1429>>
1430
1431// A T T R I B U T E S
1432
1433attributeScope(scope) ::= <<
1434<if(scope.attributes)>
1435protected sealed partial class <scope.name>_scope
1436{
1437	<scope.attributes:{it|public <it.decl>;}; separator="\n">
1438}
1439<if(scope.actions.scopeinit)>
1440protected void <scope.name>_scopeInit( <scope.name>_scope scope )
1441{
1442	<scope.actions.scopeinit>
1443}
1444<else>
1445protected virtual void <scope.name>_scopeInit( <scope.name>_scope scope ) {}
1446<endif>
1447<if(scope.actions.scopeafter)>
1448protected void <scope.name>_scopeAfter( <scope.name>_scope scope )
1449{
1450	<scope.actions.scopeafter>
1451}
1452<else>
1453protected virtual void <scope.name>_scopeAfter( <scope.name>_scope scope ) {}
1454<endif>
1455protected readonly ListStack\<<scope.name>_scope\> <scope.name>_stack = new ListStack\<<scope.name>_scope\>();
1456<endif>
1457>>
1458
1459globalAttributeScope(scope) ::= <<
1460<attributeScope(...)>
1461>>
1462
1463ruleAttributeScope(scope) ::= <<
1464<attributeScope(...)>
1465>>
1466
1467returnStructName(it) ::= "<it.name>_return"
1468
1469returnType(ruleDescriptor) ::= <%
1470<if(ruleDescriptor.returnScope.attributes && ruleDescriptor.hasMultipleReturnValues)>
1471	<ruleDescriptor.grammar.recognizerName>.<ruleDescriptor:returnStructName()>
1472<elseif(ruleDescriptor.hasMultipleReturnValues)>
1473	<ruleReturnBaseType()>
1474<elseif(ruleDescriptor.hasSingleReturnValue)>
1475	<ruleDescriptor.singleValueReturnType>
1476<else>
1477	void
1478<endif>
1479%>
1480
1481/** Generate the C# type associated with a single or multiple return
1482 *  values.
1483 */
1484ruleLabelType(referencedRule) ::= <%
1485<if(referencedRule.returnScope.attributes&&referencedRule.hasMultipleReturnValues)>
1486	<referencedRule.grammar.recognizerName>.<referencedRule:returnStructName()>
1487<elseif(referencedRule.hasMultipleReturnValues)>
1488	<ruleReturnBaseType()>
1489<elseif(referencedRule.hasSingleReturnValue)>
1490	<referencedRule.singleValueReturnType>
1491<else>
1492	void
1493<endif>
1494%>
1495
1496delegateName(it) ::= <<
1497<if(it.label)><it.label><else>g<it.name><endif>
1498>>
1499
1500/** Using a type to init value map, try to init a type; if not in table
1501 *  must be an object, default value is "null".
1502 */
1503initValue(typeName) ::= <<
1504default(<typeName>)
1505>>
1506
1507/** Define a rule label including default value */
1508ruleLabelDef(label) ::= <%
1509<ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;
1510%>
1511
1512/** Define a return struct for a rule if the code needs to access its
1513 *  start/stop tokens, tree stuff, attributes, ...  Leave a hole for
1514 *  subgroups to stick in members.
1515 */
1516returnScope(scope) ::= <<
1517<if(scope.attributes && ruleDescriptor.hasMultipleReturnValues)>
1518<returnScopeModifier(grammar=grammar,ruleDescriptor=ruleDescriptor)> sealed partial class <ruleDescriptor:returnStructName()> : <ruleReturnBaseType()><@ruleReturnInterfaces()>
1519{
1520	<scope.attributes:{it|public <it.decl>;}; separator="\n">
1521	<@ruleReturnMembers()>
1522}
1523<endif>
1524>>
1525
1526ruleReturnBaseType() ::= <%
1527<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope\<<labelType>>
1528%>
1529
1530@returnScope.ruleReturnMembers() ::= <<
1531>>
1532
1533parameterScope(scope) ::= <<
1534<scope.attributes:{it|<it.decl>}; separator=", ">
1535>>
1536
1537parameterAttributeRef(attr) ::= <<
1538<attr.name; format="id">
1539>>
1540
1541parameterSetAttributeRef(attr,expr) ::= <<
1542<attr.name; format="id"> =<expr>;
1543>>
1544
1545scopeAttributeRef(scope,attr,index,negIndex) ::= <%
1546<if(negIndex)>
1547<scope>_stack[<scope>_stack.Count - <negIndex> - 1].<attr.name; format="id">
1548<else>
1549<if(index)>
1550<scope>_stack[<index>].<attr.name; format="id">
1551<else>
1552<scope>_stack.Peek().<attr.name; format="id">
1553<endif>
1554<endif>
1555%>
1556
1557scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <%
1558<if(negIndex)>
1559<scope>_stack[<scope>_stack.Count - <negIndex> - 1].<attr.name; format="id"> = <expr>;
1560<else>
1561<if(index)>
1562<scope>_stack[<index>].<attr.name; format="id"> = <expr>;
1563<else>
1564<scope>_stack.Peek().<attr.name; format="id"> = <expr>;
1565<endif>
1566<endif>
1567%>
1568
1569/** $x is either global scope or x is rule with dynamic scope; refers
1570 *  to stack itself not top of stack.  This is useful for predicates
1571 *  like {$function.Count>0 && $function::name.Equals("foo")}?
1572 */
1573isolatedDynamicScopeRef(scope) ::= "<scope>_stack"
1574
1575/** reference an attribute of rule; might only have single return value */
1576ruleLabelRef(referencedRule,scope,attr) ::= <%
1577<if(referencedRule.hasMultipleReturnValues)>
1578(<scope>!=null?<scope>.<attr.name; format="id">:<initValue(attr.type)>)
1579<else>
1580<scope>
1581<endif>
1582%>
1583
1584returnAttributeRef(ruleDescriptor,attr) ::= <%
1585<if(ruleDescriptor.hasMultipleReturnValues)>
1586retval.<attr.name; format="id">
1587<else>
1588<attr.name; format="id">
1589<endif>
1590%>
1591
1592returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <%
1593<if(ruleDescriptor.hasMultipleReturnValues)>
1594retval.<attr.name; format="id"> =<expr>;
1595<else>
1596<attr.name; format="id"> =<expr>;
1597<endif>
1598%>
1599
1600/** How to translate $tokenLabel */
1601tokenLabelRef(label) ::= "<label>"
1602
1603/** ids+=ID {$ids} or e+=expr {$e} */
1604listLabelRef(label) ::= "list_<label>"
1605
1606
1607// not sure the next are the right approach
1608
1609tokenLabelPropertyRef_text(scope,attr) ::= "(<scope>!=null?<scope>.Text:null)"
1610tokenLabelPropertyRef_type(scope,attr) ::= "(<scope>!=null?<scope>.Type:0)"
1611tokenLabelPropertyRef_line(scope,attr) ::= "(<scope>!=null?<scope>.Line:0)"
1612tokenLabelPropertyRef_pos(scope,attr) ::= "(<scope>!=null?<scope>.CharPositionInLine:0)"
1613tokenLabelPropertyRef_channel(scope,attr) ::= "(<scope>!=null?<scope>.Channel:0)"
1614tokenLabelPropertyRef_index(scope,attr) ::= "(<scope>!=null?<scope>.TokenIndex:0)"
1615tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
1616tokenLabelPropertyRef_int(scope,attr) ::= "(<scope>!=null?int.Parse(<scope>.Text):0)"
1617
1618ruleLabelPropertyRef_start(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Start):default(<labelType>))"
1619ruleLabelPropertyRef_stop(scope,attr) ::= "(<scope>!=null?((<labelType>)<scope>.Stop):default(<labelType>))"
1620ruleLabelPropertyRef_tree(scope,attr) ::= "(<scope>!=null?((<ASTLabelType>)<scope>.Tree):default(<ASTLabelType>))"
1621ruleLabelPropertyRef_text(scope,attr) ::= <%
1622<if(TREE_PARSER)>
1623(<scope>!=null?(input.TokenStream.ToString(
1624  input.TreeAdaptor.GetTokenStartIndex(<scope>.Start),
1625  input.TreeAdaptor.GetTokenStopIndex(<scope>.Start))):null)
1626<else>
1627(<scope>!=null?input.ToString(<scope>.Start,<scope>.Stop):null)
1628<endif>
1629%>
1630
1631ruleLabelPropertyRef_st(scope,attr) ::= "(<scope>!=null?<scope>.Template:null)"
1632
1633/** Isolated $RULE ref ok in lexer as it's a Token */
1634lexerRuleLabel(label) ::= "<label>"
1635
1636lexerRuleLabelPropertyRef_type(scope,attr) ::=
1637    "(<scope>!=null?<scope>.Type:0)"
1638
1639lexerRuleLabelPropertyRef_line(scope,attr) ::=
1640    "(<scope>!=null?<scope>.Line:0)"
1641
1642lexerRuleLabelPropertyRef_pos(scope,attr) ::=
1643    "(<scope>!=null?<scope>.CharPositionInLine:-1)"
1644
1645lexerRuleLabelPropertyRef_channel(scope,attr) ::=
1646    "(<scope>!=null?<scope>.Channel:0)"
1647
1648lexerRuleLabelPropertyRef_index(scope,attr) ::=
1649    "(<scope>!=null?<scope>.TokenIndex:0)"
1650
1651lexerRuleLabelPropertyRef_text(scope,attr) ::=
1652    "(<scope>!=null?<scope>.Text:null)"
1653
1654lexerRuleLabelPropertyRef_int(scope,attr) ::=
1655    "(<scope>!=null?int.Parse(<scope>.Text):0)"
1656
1657// Somebody may ref $template or $tree or $stop within a rule:
1658rulePropertyRef_start(scope,attr) ::= "retval.Start"
1659rulePropertyRef_stop(scope,attr) ::= "retval.Stop"
1660rulePropertyRef_tree(scope,attr) ::= "retval.Tree"
1661rulePropertyRef_text(scope,attr) ::= <%
1662<if(TREE_PARSER)>
1663input.TokenStream.ToString(
1664  input.TreeAdaptor.GetTokenStartIndex(retval.Start),
1665  input.TreeAdaptor.GetTokenStopIndex(retval.Start))
1666<else>
1667input.ToString(retval.Start,input.LT(-1))
1668<endif>
1669%>
1670rulePropertyRef_st(scope,attr) ::= "retval.Template"
1671
1672lexerRulePropertyRef_text(scope,attr) ::= "Text"
1673lexerRulePropertyRef_type(scope,attr) ::= "_type"
1674lexerRulePropertyRef_line(scope,attr) ::= "state.tokenStartLine"
1675lexerRulePropertyRef_pos(scope,attr) ::= "state.tokenStartCharPositionInLine"
1676lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
1677lexerRulePropertyRef_channel(scope,attr) ::= "_channel"
1678lexerRulePropertyRef_start(scope,attr) ::= "state.tokenStartCharIndex"
1679lexerRulePropertyRef_stop(scope,attr) ::= "(CharIndex-1)"
1680lexerRulePropertyRef_int(scope,attr) ::= "int.Parse(<scope>.Text)"
1681
1682// setting $st and $tree is allowed in local rule. everything else
1683// is flagged as error
1684ruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.Tree = <expr>;"
1685ruleSetPropertyRef_st(scope,attr,expr) ::= "retval.Template =<expr>;"
1686
1687/** How to execute an action (only when not backtracking) */
1688execAction(action) ::= <%
1689<if(backtracking)>
1690if (<actions.(actionScope).synpredgate>)<\n>
1691{<\n>
1692<@indentedAction()><\n>
1693}
1694<else>
1695<action>
1696<endif>
1697%>
1698
1699@execAction.indentedAction() ::= <<
1700	<action>
1701>>
1702
1703/** How to always execute an action even when backtracking */
1704execForcedAction(action) ::= "<action>"
1705
1706// M I S C (properties, etc...)
1707
1708bitset(name, words64) ::= <<
1709public static readonly BitSet <name> = new BitSet(new ulong[]{<words64:{it|<it>UL};separator=",">});
1710>>
1711
1712codeFileExtension() ::= ".cs"
1713
1714true_value() ::= "true"
1715false_value() ::= "false"
1716