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