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