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