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