Ruby.stg revision 324c4644fee44b9898524c09511bd33c3f12e2df
1/******************************************************************************
2 *********************  M A J O R   C O M P O N E N T S  **********************
3 ******************************************************************************/
4
5// System.Boolean.ToString() returns "True" and "False", but the proper C# literals are "true" and "false"
6// The Java version of Boolean returns "true" and "false", so they map to themselves here.
7booleanLiteral ::= [
8	"True":"true",
9	"False":"false",
10	"true":"true",
11	"false":"false",
12	default:"false"
13]
14
15/** The overall file structure of a recognizer; stores methods
16  * for rules and cyclic DFAs plus support code.
17  */
18outputFile(LEXER, PARSER, TREE_PARSER, actionScope, actions, docComment, recognizer, name,
19  tokens, tokenNames, rules, cyclicDFAs, bitsets, buildTemplate, buildAST, rewriteMode,
20  profile, backtracking, synpreds, memoize, numRules, fileName, ANTLRVersion, generatedTimestamp,
21  trace, scopes, superClass, literals) ::=
22<<
23#!/usr/bin/env ruby
24#
25# <fileName>
26# --
27# Generated using ANTLR version: <ANTLRVersion>
28# Ruby runtime library version: <runtimeLibraryVersion()>
29# Input grammar file: <fileName>
30# Generated at: <generatedTimestamp>
31#
32
33# ~~~\> start load path setup
34this_directory = File.expand_path( File.dirname( __FILE__ ) )
35$LOAD_PATH.unshift( this_directory ) unless $LOAD_PATH.include?( this_directory )
36
37antlr_load_failed = proc do
38  load_path = $LOAD_PATH.map { |dir| '  - ' \<\< dir }.join( $/ )
39  raise LoadError, \<\<-END.strip!
40
41Failed to load the ANTLR3 runtime library (version <runtimeLibraryVersion()>):
42
43Ensure the library has been installed on your system and is available
44on the load path. If rubygems is available on your system, this can
45be done with the command:
46
47  gem install antlr3
48
49Current load path:
50#{ load_path }
51
52  END
53end
54
55defined?( ANTLR3 ) or begin
56
57  # 1: try to load the ruby antlr3 runtime library from the system path
58  require 'antlr3'
59
60rescue LoadError
61
62  # 2: try to load rubygems if it isn't already loaded
63  defined?( Gem ) or begin
64    require 'rubygems'
65  rescue LoadError
66    antlr_load_failed.call
67  end
68
69  # 3: try to activate the antlr3 gem
70  begin
71    Gem.activate( 'antlr3', '~> <runtimeLibraryVersion()>' )
72  rescue Gem::LoadError
73    antlr_load_failed.call
74  end
75
76  require 'antlr3'
77
78end
79# \<~~~ end load path setup
80
81<placeAction(scope="all", name="header")>
82<placeAction(scope=actionScope,name="header")>
83
84<if(recognizer.grammar.grammarIsRoot)>
85<rootGrammarOutputFile()>
86<else>
87<delegateGrammarOutputFile()>
88<endif>
89
90<placeAction(scope=actionScope,name="footer")>
91<placeAction(scope="all", name="footer")>
92
93<if(actions.(actionScope).main)>
94if __FILE__ == $0 and ARGV.first != '--'
95  <placeAction(scope=actionScope,name="main")>
96end
97<endif>
98>>
99
100tokenDataModule() ::= <<
101# TokenData defines all of the token type integer values
102# as constants, which will be included in all
103# ANTLR-generated recognizers.
104const_defined?( :TokenData ) or TokenData = ANTLR3::TokenScheme.new
105
106module TokenData
107<if(tokens)>
108
109  # define the token constants
110  define_tokens( <tokens:{it | :<it.name> => <it.type>}; anchor, wrap="\n", separator=", "> )
111
112<endif>
113<if(tokenNames)>
114
115  # register the proper human-readable name or literal value
116  # for each token type
117  #
118  # this is necessary because anonymous tokens, which are
119  # created from literal values in the grammar, do not
120  # have descriptive names
121  register_names( <tokenNames:{it | <it>}; separator=", ", anchor, wrap="\n"> )
122
123<endif>
124
125  <placeAction(scope="token",name="scheme")>
126  <placeAction(scope="token",name="members")>
127end<\n>
128>>
129
130rootGrammarOutputFile() ::= <<
131module <recognizer.grammar.name>
132  <placeAction(scope="module",name="head")>
133  <tokenDataModule()>
134  <recognizer>
135  <placeAction(scope="module",name="foot")>
136end
137>>
138
139delegateGrammarOutputFile() ::= <<
140require '<recognizer.grammar.delegator.recognizerName>'
141
142<delegateGrammarModuleHead(gram=recognizer.grammar.delegator)>
143  <recognizer>
144<delegateGrammarModuleTail(gram=recognizer.grammar.delegator)>
145>>
146
147delegateGrammarModuleHead(gram) ::= <<
148<if(gram.grammarIsRoot)>
149module <gram.name>
150<else>
151<delegateGrammarModuleHead(gram=gram.delegator)><\n>
152class <gram.name>
153<endif>
154>>
155
156delegateGrammarModuleTail(gram) ::= <<
157<if(gram.grammarIsRoot)>
158end # module <gram.name>
159<else>
160end # class <gram.name>
161<delegateGrammarModuleTail(gram=gram.delegator)><\n>
162<endif>
163>>
164/* * * * * * * * * * R E C O G N I Z E R   C L A S S E S * * * * * * * * * */
165
166parser(
167  grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets,
168  ASTLabelType="Object", superClass="ANTLR3::Parser", labelType="ANTLR3::Token",
169  members={<actions.parser.members>}
170) ::= <<
171<if(grammar.grammarIsRoot)><autoloadDelegates()><endif>
172
173class <if(grammar.grammarIsRoot)>Parser<else><grammar.name><endif> \< <superClass>
174  <parserBody(inputStreamType="ANTLR3::TokenStream", rewriteElementType="Token", actionScope="parser", ...)>
175end # class <if(grammar.grammarIsRoot)>Parser<else><grammar.name><endif> \< <superClass>
176<if(!actions.(actionScope).main)>
177
178at_exit { <if(grammar.grammarIsRoot)>Parser<else><grammar.name><endif>.main( ARGV ) } if __FILE__ == $0
179<endif>
180>>
181
182/** How to generate a tree parser; same as parser except the
183  * input stream is a different type.
184  */
185treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules, numRules, bitsets, filterMode, labelType={<ASTLabelType>}, ASTLabelType="Object", superClass="ANTLR3::TreeParser", members={<actions.treeparser.members>}) ::= <<
186<if(grammar.grammarIsRoot)><autoloadDelegates()><endif>
187
188class <if(grammar.grammarIsRoot)>TreeParser<else><grammar.name><endif> \< <superClass>
189  <parserBody(inputStreamType="TreeNodeStream", rewriteElementType="Node", actionScope="treeparser", ...)>
190end # class <if(grammar.grammarIsRoot)>TreeParser<else><grammar.name><endif> \< <superClass>
191<if(!actions.(actionScope).main)>
192
193at_exit { <if(grammar.grammarIsRoot)>TreeParser<else><grammar.name><endif>.main( ARGV ) } if __FILE__ == $0
194<endif>
195>>
196
197parserBody(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets, inputStreamType, superClass, filterMode, labelType, members, rewriteElementType, actionScope, ASTLabelType="Object") ::= <<
198@grammar_home = <grammar.name>
199<if(!grammar.grammarIsRoot)><autoloadDelegates()><\n><endif>
200<@mixins()>
201
202RULE_METHODS = [ <rules:{r|:<r.ruleName>}; separator=", ", wrap="\n", anchor> ].freeze
203
204<scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeClass()><\n><endif>}>
205<rules:{it | <ruleAttributeScopeClass(.ruleDescriptor.ruleScope)>}>
206<if(grammar.delegators)>
207masters( <grammar.delegators:{d|:<d.name>}; separator=", "> )<\n>
208<endif>
209<if(grammar.directDelegates)>
210imports( <grammar.directDelegates:{d|:<d.name>}; separator=", "> )<\n>
211<endif>
212
213include TokenData
214
215begin
216  generated_using( "<fileName>", "<ANTLRVersion>", "<runtimeLibraryVersion()>" )
217rescue NoMethodError => error
218  # ignore
219end
220
221<if(!grammar.grammarIsRoot)>
222require '<grammar.composite.rootGrammar.recognizerName>'
223include <grammar.composite.rootGrammar.name>::TokenData<\n><\n>
224<endif>
225<parserConstructor()>
226<@additionalMembers()>
227<members>
228# - - - - - - - - - - - - Rules - - - - - - - - - - - - -
229<rules:{it | <it><\n>}>
230
231<if(grammar.delegatedRules)>
232# - - - - - - - - - - Delegated Rules - - - - - - - - - - -
233<grammar.delegatedRules:{ruleDescriptor|<delegateRule(ruleDescriptor)><\n>}>
234<endif>
235<if(cyclicDFAs)>
236# - - - - - - - - - - DFA definitions - - - - - - - - - - -
237<cyclicDFAs:{it | <cyclicDFA(it)>}>
238
239private
240
241def initialize_dfas
242  super rescue nil
243  <cyclicDFAs:{it | <cyclicDFAInit(it)>}>
244end
245
246<endif>
247<bitsets:{it | TOKENS_FOLLOWING_<it.name>_IN_<it.inName>_<it.tokenIndex> = Set[ <it.tokenTypes:{it | <it>}; separator=", "> ]<\n>}>
248>>
249
250parserConstructor() ::= <<
251def initialize( <grammar.delegators:{g|<g:delegateName()>, }>input, options = {} )
252  super( input, options )
253<if(memoize)><if(grammar.grammarIsRoot)>
254  @state.rule_memory = {}
255<endif><endif>
256  <scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeStack()><\n><endif>}><rules:{it | <ruleAttributeScopeStack(.ruleDescriptor.ruleScope)>}>
257  <placeAction(scope=actionScope,name="init")>
258  <grammar.delegators:{g|@<g:delegateName()> = <g:delegateName()><\n>}><grammar.directDelegates:{g|@<g:delegateName()> = <newDelegate(g)><\n>}><last(grammar.delegators):{g|@parent = @<g:delegateName()><\n>}><@init()>
259end
260>>
261
262
263/* * * * * * * * * * * * * R U L E   M E T H O D S * * * * * * * * * * * * */
264
265/** A simpler version of a rule template that is specific to the
266  * imaginary rules created for syntactic predicates.  As they
267  * never have return values nor parameters etc..., just give
268  * simplest possible method.  Don't do any of the normal
269  * memoization stuff in here either; it's a waste. As
270  * predicates cannot be inlined into the invoking rule, they
271  * need to be in a rule by themselves.
272  */
273synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::= <<
274#
275# syntactic predicate <ruleName>
276#
277# (in <fileName>)
278# <description>
279#
280# This is an imaginary rule inserted by ANTLR to
281# implement a syntactic predicate decision
282#
283def <ruleName><if(ruleDescriptor.parameterScope)>( <ruleDescriptor.parameterScope:parameterScope()> )<endif>
284  <traceIn()><ruleLabelDefs()>
285  <block>
286ensure
287  <traceOut()>
288end
289>>
290
291
292/** How to generate code for a rule.  This includes any return
293  * type data aggregates required for multiple return values.
294  */
295rule(ruleName, ruleDescriptor, block, emptyRule, description, exceptions, finally, memoize) ::= <<
296<returnScope(scope=ruleDescriptor.returnScope)>
297
298#
299# parser rule <ruleName>
300#
301# (in <fileName>)
302# <description>
303#
304def <ruleName><if(ruleDescriptor.parameterScope)>( <ruleDescriptor.parameterScope:parameterScope()> )<endif>
305  <traceIn()><ruleScopeSetUp()><ruleDeclarations()><ruleLabelDefs()><action(name="init", code=ruleDescriptor.actions.init)>
306  <@body><ruleBody()><@end>
307
308  return <ruleReturnValue()>
309end
310<if(ruleDescriptor.modifier)>
311
312<ruleDescriptor.modifier> :<ruleName> rescue nil<\n>
313<endif>
314>>
315
316delegateRule(ruleDescriptor) ::= <<
317# delegated rule <ruleDescriptor.name>
318def <ruleDescriptor.name><if(ruleDescriptor.parameterScope)>( <ruleDescriptor.parameterScope:parameterScope()> )<endif>
319  <methodCall(del=ruleDescriptor.grammar, n=ruleDescriptor.name, args={<ruleDescriptor.parameterScope.attributes:{it | <it.name>}>})>
320end
321>>
322// HELPERS
323
324recognizerClassName() ::= <<
325<if(TREE_PARSER)>TreeParser<elseif(PARSER)>Parser<else>Lexer<endif>
326>>
327
328initializeDirectDelegate() ::= <<
329@<g:delegateName()> = <g.name>::<recognizerClassName()>.new(
330  <trunc(g.delegators):{p|<p:delegateName()>, }>self, input, options.merge( :state => @state )
331)
332>>
333
334initializeDelegator() ::= <<
335@<g:delegateName()> = <g:delegateName()>
336>>
337
338altSwitchCase(altNum,alt) ::= <<
339when <altNum>
340  <@prealt()>
341  <alt>
342>>
343
344blockBody() ::= <<
345<@decision><decision><@end>
346case alt_<decisionNumber>
347<alts:{a | <altSwitchCase(i,a)>}; separator="\n">
348end
349>>
350
351catch(decl, action) ::= <<
352# - - - - - - @catch <e.decl> - - - - - -
353rescue <e.decl>
354  <e.action><\n>
355>>
356
357closureBlockLoop() ::= <<
358while true # decision <decisionNumber>
359  alt_<decisionNumber> = <maxAlt>
360  <@decisionBody><decision><@end>
361  case alt_<decisionNumber>
362  <alts:{a | <altSwitchCase(i,a)>}; separator="\n">
363  else
364    break # out of loop for decision <decisionNumber>
365  end
366end # loop for decision <decisionNumber>
367>>
368
369delegateName(d) ::= <<
370<if(d.label)><d.label; format="label"><else><d.name; format="snakecase"><endif>
371>>
372
373element(e) ::= <<
374<e.el><\n>
375>>
376
377execForcedAction(action) ::= "<action>"
378
379globalAttributeScopeClass(scope) ::= <<
380<if(scope.attributes)>@@<scope.name> = Scope( <scope.attributes:{it | <it.decl; format="rubyString">}; separator=", "> )<\n><endif>
381>>
382
383globalAttributeScopeStack(scope) ::= <<
384<if(scope.attributes)>@<scope.name>_stack = []<\n><endif>
385>>
386
387noRewrite(rewriteBlockLevel, treeLevel) ::= ""
388
389parameterScope(scope) ::= <<
390<scope.attributes:{it | <it.decl>}; separator=", ">
391>>
392
393positiveClosureBlockLoop() ::= <<
394match_count_<decisionNumber> = 0
395while true
396  alt_<decisionNumber> = <maxAlt>
397  <@decisionBody><decision><@end>
398  case alt_<decisionNumber>
399  <alts:{a | <altSwitchCase(i,a)>}; separator="\n">
400  else
401    match_count_<decisionNumber> > 0 and break
402    <ruleBacktrackFailure()>
403    eee = EarlyExit(<decisionNumber>)
404    <@earlyExitException()><\n>
405    raise eee
406  end
407  match_count_<decisionNumber> += 1
408end<\n>
409>>
410
411returnScope(scope) ::= <<
412<if(ruleDescriptor.hasMultipleReturnValues)>
413<ruleDescriptor:returnStructName(r=it)> = define_return_scope <scope.attributes:{it | :<it.decl>}; separator=", ">
414<endif>
415>>
416
417returnStructName(r) ::= "<r.name; format=\"camelcase\">ReturnValue"
418
419ruleAttributeScopeClass ::= globalAttributeScopeClass
420ruleAttributeScopeStack ::= globalAttributeScopeStack
421
422ruleBacktrackFailure() ::= <<
423<if(backtracking)>
424@state.backtracking > 0 and raise( ANTLR3::Error::BacktrackingFailed )<\n>
425<endif>
426>>
427
428ruleBody() ::= <<
429<if(memoize)><if(backtracking)>
430success = false # flag used for memoization<\n>
431<endif><endif>
432begin
433  <ruleMemoization(ruleName)><block><ruleCleanUp()><(ruleDescriptor.actions.after):execAction()>
434<if(memoize)><if(backtracking)>
435  success = true<\n>
436<endif><endif>
437<if(exceptions)>
438  <exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
439<else>
440<if(!emptyRule)>
441<if(actions.(actionScope).rulecatch)>
442
443# - - - - - - - - @rulecatch - - - - - - - -
444<actions.(actionScope).rulecatch>
445<else>
446rescue ANTLR3::Error::RecognitionError => re
447  report_error(re)
448  recover(re)
449  <@setErrorReturnValue()>
450<endif>
451<endif>
452<endif>
453
454ensure
455  <traceOut()><memoize()><ruleScopeCleanUp()><finally>
456end
457>>
458
459ruleReturnValue() ::= <%
460<if(!ruleDescriptor.isSynPred)>
461<if(ruleDescriptor.hasReturnValue)>
462<if(ruleDescriptor.hasSingleReturnValue)>
463<ruleDescriptor.singleValueReturnName>
464<else>
465return_value
466<endif>
467<endif>
468<endif>
469%>
470
471
472ruleDeclarations() ::= <<
473<if(ruleDescriptor.hasMultipleReturnValues)>
474return_value = <returnStructName(r=ruleDescriptor)>.new
475
476# $rule.start = the first token seen before matching
477return_value.start = @input.look<\n>
478<else>
479<ruleDescriptor.returnScope.attributes:{a|<a.name> = <if(a.initValue)><a.initValue><else>nil<endif><\n>}>
480<endif>
481<if(memoize)>
482<ruleDescriptor.name>_start_index = @input.index<\n>
483<endif>
484>>
485
486ruleLabelDef(label) ::= <<
487<label.label.text; format="label"> = nil<\n>
488>>
489
490ruleLabelDefs() ::= <<
491<[
492    ruleDescriptor.tokenLabels,
493    ruleDescriptor.tokenListLabels,
494    ruleDescriptor.wildcardTreeLabels,
495    ruleDescriptor.wildcardTreeListLabels,
496    ruleDescriptor.ruleLabels,
497    ruleDescriptor.ruleListLabels
498 ]:
499 {<it.label.text; format="label"> = nil<\n>}
500><[
501    ruleDescriptor.tokenListLabels,
502    ruleDescriptor.ruleListLabels,
503    ruleDescriptor.wildcardTreeListLabels
504  ]:
505  {list_of_<it.label.text; format="label"> = []<\n>}
506>
507>>
508
509/* * * * * * * * * * * * * R U L E   H E L P E R S * * * * * * * * * * * * */
510
511traceIn() ::= <<
512<if(trace)>
513trace_in( __method__, <ruleDescriptor.index> )<\n>
514<else>
515# -> uncomment the next line to manually enable rule tracing
516# trace_in( __method__, <ruleDescriptor.index> )<\n>
517<endif>
518>>
519
520traceOut() ::= <<
521<if(trace)>
522trace_out( __method__, <ruleDescriptor.index> )<\n>
523<else>
524# -> uncomment the next line to manually enable rule tracing
525# trace_out( __method__, <ruleDescriptor.index> )<\n>
526<endif>
527>>
528
529ruleCleanUp() ::= <<
530<if(ruleDescriptor.hasMultipleReturnValues)>
531<if(!TREE_PARSER)>
532# - - - - - - - rule clean up - - - - - - - -
533return_value.stop = @input.look( -1 )<\n>
534<endif>
535<endif>
536>>
537
538ruleMemoization(name) ::= <<
539<if(memoize)>
540# rule memoization
541if @state.backtracking > 0 and already_parsed_rule?( __method__ )
542  success = true
543  return <ruleReturnValue()>
544end<\n>
545<endif>
546>>
547
548
549ruleScopeSetUp() ::= <<
550<ruleDescriptor.useScopes:{it | @<it>_stack.push( @@<it>.new )<\n>}><ruleDescriptor.ruleScope:{it | @<it.name>_stack.push( @@<it.name>.new )<\n>}>
551>>
552
553ruleScopeCleanUp() ::= <<
554<ruleDescriptor.useScopes:{it | @<it>_stack.pop<\n>}><ruleDescriptor.ruleScope:{it | @<it.name>_stack.pop<\n>}>
555>>
556
557memoize() ::= <<
558<if(memoize)><if(backtracking)>
559memoize( __method__, <ruleDescriptor.name>_start_index, success ) if @state.backtracking > 0<\n>
560<endif><endif>
561>>
562
563/** helper template to format a ruby method call */
564methodCall(n, del, args) ::= <<
565<if(del)>@<del:delegateName()>.<endif><n><if(args)>( <args; separator=", "> )<endif>
566>>
567
568/* * * * * * * * * * * * * L E X E R   P A R T S * * * * * * * * * * * * * */
569
570actionGate() ::= "@state.backtracking == 0"
571
572/** A (...) subrule with multiple alternatives */
573block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
574# at line <description>
575alt_<decisionNumber> = <maxAlt>
576<decls>
577<@body><blockBody()><@end>
578>>
579
580/** A rule block with multiple alternatives */
581ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
582# at line <description>
583alt_<decisionNumber> = <maxAlt>
584<decls>
585<@decision><decision><@end>
586case alt_<decisionNumber>
587<alts:{a | <altSwitchCase(i,a)>}; separator="\n">
588end
589>>
590
591ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
592<decls>
593<@prealt()>
594<alts>
595>>
596
597/** A special case of a (...) subrule with a single alternative */
598blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
599# at line <description>
600<decls>
601<@prealt()>
602<alts>
603>>
604
605/** A (..)+ block with 0 or more alternatives */
606positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
607# at file <description>
608<decls>
609<@loopBody>
610<positiveClosureBlockLoop()>
611<@end>
612>>
613
614positiveClosureBlockSingleAlt ::= positiveClosureBlock
615
616/** A (..)* block with 0 or more alternatives */
617closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
618# at line <description>
619<decls>
620<@loopBody>
621<closureBlockLoop()>
622<@end>
623>>
624
625closureBlockSingleAlt ::= closureBlock
626
627/** Optional blocks (x)? are translated to (x|) by before code
628  * generation so we can just use the normal block template
629  */
630optionalBlock ::= block
631
632optionalBlockSingleAlt ::= block
633
634/** An alternative is just a list of elements; at outermost
635  * level
636  */
637alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
638# at line <description>
639<elements:element()><rew>
640>>
641
642/** match a token optionally with a label in front */
643tokenRef(token,label,elementIndex,terminalOptions) ::= <<
644<if(label)><label; format="label"> = <endif>match( <token>, TOKENS_FOLLOWING_<token>_IN_<ruleName>_<elementIndex> )
645>>
646
647/** ids+=ID */
648tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
649<tokenRef(...)>
650<addToList(elem={<label; format="label">},...)>
651>>
652
653/* TRY THIS:
654tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
655list_of_<label; format="label"> << match( <token>, TOKENS_FOLLOWING_<token>_IN_<ruleName>_<elementIndex> )
656>>
657*/
658
659addToList(label,elem) ::= <<
660list_of_<label; format="label"> \<\< <elem><\n>
661>>
662
663listLabel ::= addToList
664
665/** For now, sets are interval tests and must be tested inline */
666matchSet(s,label,elementIndex,terminalOptions,postmatchCode) ::= <<
667<if(label)>
668<label; format="label"> = @input.look<\n>
669<endif>
670if <s>
671  @input.consume
672  <postmatchCode>
673<if(!LEXER)>
674  @state.error_recovery = false<\n>
675<endif>
676else
677  <ruleBacktrackFailure()>
678  mse = MismatchedSet( nil )
679  <@mismatchedSetException()>
680<if(LEXER)>
681  recover mse
682  raise mse<\n>
683<else>
684  raise mse<\n>
685<endif>
686end
687<\n>
688>>
689
690
691matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
692<matchSet(...)>
693<addToList(elem={<label; format="label">},...)>
694>>
695
696matchRuleBlockSet ::= matchSet
697
698wildcard(token,label,elementIndex,terminalOptions) ::= <<
699<if(label)>
700<label; format="label"> = @input.look<\n>
701<endif>
702match_any
703>>
704
705/* TRY THIS:
706wildcard(label,elementIndex) ::= <<
707<if(label)><label; format="label"> = <endif>match_any
708>>
709*/
710
711wildcardAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
712<wildcard(...)>
713<addToList(elem={<label; format="label">},...)>
714>>
715
716
717/** Match a rule reference by invoking it possibly with
718  * arguments and a return value or values.
719  */
720ruleRef(rule,label,elementIndex,args,scope) ::= <<
721@state.following.push( TOKENS_FOLLOWING_<rule.name>_IN_<ruleName>_<elementIndex> )
722<if(label)><label; format="label"> = <endif><methodCall(del=scope, n={<rule.name>}, args=args)>
723@state.following.pop
724>>
725
726/** ids+=ID */
727ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
728<ruleRef(...)>
729<addToList(elem={<label; format="label">},...)>
730>>
731
732/** match ^(root children) in tree parser */
733tree(root, actionsAfterRoot, children, nullableChildList, enclosingTreeLevel, treeLevel) ::= <<
734<root:element()>
735<actionsAfterRoot:element()>
736<if(nullableChildList)>
737if @input.peek == DOWN
738  match( DOWN, nil )
739  <children:element()>
740  match( UP, nil )
741end
742<else>
743match( DOWN, nil )
744<children:element()>
745match( UP, nil )
746<endif>
747>>
748
749/** Every predicate is used as a validating predicate (even when
750  * it is also hoisted into a prediction expression).
751  */
752validateSemanticPredicate(pred,description) ::= <<
753<if(backtracking)>
754unless ( <evalPredicate(...)> )
755  <ruleBacktrackFailure()>
756  raise FailedPredicate( "<ruleName>", "<description>" )
757end
758<else>
759raise FailedPredicate( "<ruleName>", "<description>" ) unless ( <evalPredicate(...)> )
760<endif>
761>>
762
763dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
764look_<decisionNumber>_<stateNumber> = @input.peek( <k> )<\n>
765<edges; separator="\nels">
766else
767<if(eotPredictsAlt)>
768  alt_<decisionNumber> = <eotPredictsAlt><\n>
769<else>
770<if(backtracking)>
771  <ruleBacktrackFailure()><\n>
772<endif>
773<@noViableAltException>
774  raise NoViableAlternative( "<description>", <decisionNumber>, <stateNumber> )<\n>
775<@end>
776<endif>
777end
778>>
779
780/** Same as a normal DFA state except that we don't examine
781  * look for the bypass alternative.  It delays error
782  * detection but this is faster, smaller, and more what people
783  * expect.  For (X)? people expect "if ( LA(1)==X ) match(X);"
784  * and that's it. *  If a semPredState, don't force look
785  * lookup; preds might not need.
786  */
787dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
788look_<decisionNumber>_<stateNumber> = @input.peek( <k> )<\n>
789<edges; separator="\nels">
790end
791>>
792
793
794/** A DFA state that is actually the loopback decision of a
795  * closure loop.  If end-of-token (EOT) predicts any of the
796  * targets then it should act like a default clause (i.e., no
797  * error can be generated). This is used only in the lexer so
798  * that for ('a')* on the end of a rule anything other than 'a'
799  * predicts exiting. *  If a semPredState, don't force
800  * look lookup; preds might not need.
801  */
802dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
803look_<decisionNumber>_<stateNumber> = @input.peek( <k> )<\n>
804<edges; separator="\nels"><\n>
805<if(eotPredictsAlt)>
806else
807  alt_<decisionNumber> = <eotPredictsAlt><\n>
808<endif>
809end
810>>
811
812
813/** An accept state indicates a unique alternative has been
814  * predicted
815  */
816dfaAcceptState(alt) ::= "alt_<decisionNumber> = <alt>"
817
818/** A simple edge with an expression.  If the expression is
819  * satisfied, enter to the target state.  To handle gated
820  * productions, we may have to evaluate some predicates for
821  * this edge.
822  */
823dfaEdge(labelExpr, targetState, predicates) ::= <<
824if ( <labelExpr> )<if(predicates)> and ( <predicates> )<endif>
825  <targetState>
826>>
827
828
829/** A DFA state where a SWITCH may be generated.  The code
830  * generator decides if this is possible:
831  * CodeGenerator.canGenerateSwitch().
832  */
833dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
834case look_<decisionNumber> = @input.peek( <k> )
835<edges; separator="\n">
836else
837<if(eotPredictsAlt)>
838  alt_<decisionNumber> = <eotPredictsAlt><\n>
839<else>
840<if(backtracking)>
841  <ruleBacktrackFailure()><\n>
842<endif>
843<@noViableAltException>
844  raise NoViableAlternative( "<description>", <decisionNumber>, <stateNumber> )<\n>
845<@end>
846<endif>
847end
848>>
849
850
851dfaOptionalBlockStateSwitch(k, edges, eotPredictsAlt, description, stateNumber, semPredState) ::= <<
852case look_<decisionNumber> = @input.peek( <k> )
853<edges; separator="\n">
854end
855>>
856
857dfaLoopbackStateSwitch(k, edges, eotPredictsAlt, description, stateNumber, semPredState) ::= <<
858case look_<decisionNumber> = @input.peek( <k> )
859<edges; separator="\n">
860<if(eotPredictsAlt)>
861else
862  alt_<decisionNumber> = <eotPredictsAlt>
863<endif>
864end
865>>
866
867dfaEdgeSwitch(labels, targetState) ::= <<
868when <labels:{it | <it>}; separator=", "> then <targetState>
869>>
870
871/** The code to initiate execution of a cyclic DFA; this is used
872  * in the rule to predict an alt just like the fixed DFA case.
873  * The <name> attribute is inherited via the parser, lexer, ...
874  */
875dfaDecision(decisionNumber, description) ::= <<
876alt_<decisionNumber> = @dfa<decisionNumber>.predict( @input )
877>>
878
879/** Generate the tables and support code needed for the DFAState
880  * object argument.  Unless there is a semantic predicate (or
881  * syn pred, which become sem preds), all states should be
882  * encoded in the state tables. Consequently,
883  * cyclicDFAState/cyclicDFAEdge,eotDFAEdge templates are not
884  * used except for special DFA states that cannot be encoded as
885  * a transition table.
886  */
887cyclicDFA(dfa) ::= <<
888class DFA<dfa.decisionNumber> \< ANTLR3::DFA
889  EOT = unpack( <dfa.javaCompressedEOT; anchor, separator=", ", wrap="\n"> )
890  EOF = unpack( <dfa.javaCompressedEOF; anchor, separator=", ", wrap="\n"> )
891  MIN = unpack( <dfa.javaCompressedMin; anchor, separator=", ", wrap="\n"> )
892  MAX = unpack( <dfa.javaCompressedMax; anchor, separator=", ", wrap="\n"> )
893  ACCEPT = unpack( <dfa.javaCompressedAccept; anchor, separator=", ", wrap="\n"> )
894  SPECIAL = unpack( <dfa.javaCompressedSpecial; anchor, separator=", ", wrap="\n"> )
895  TRANSITION = [
896    <dfa.javaCompressedTransition:{s|unpack( <s; wrap="\n", anchor, separator=", "> )}; separator=",\n">
897  ].freeze
898
899  ( 0 ... MIN.length ).zip( MIN, MAX ) do | i, a, z |
900    if a \> 0 and z \< 0
901      MAX[ i ] %= 0x10000
902    end
903  end
904
905  @decision = <dfa.decisionNumber>
906
907  <@errorMethod()>
908<if(dfa.description)>
909
910  def description
911    \<\<-'__dfa_description__'.strip!
912      <dfa.description>
913    __dfa_description__
914  end<\n>
915<endif>
916end<\n>
917>>
918
919
920specialStateTransitionMethod(dfa) ::= <<
921def special_state_transition_for_dfa<dfa.decisionNumber>(s, input)
922  case s
923  <dfa.specialStateSTs:{state|when <i0>
924  <state>}; separator="\n">
925  end
926<if(backtracking)>
927  @state.backtracking > 0 and raise ANTLR3::Error::BacktrackingFailed<\n>
928<endif>
929  nva = ANTLR3::Error::NoViableAlternative.new( @dfa<dfa.decisionNumber>.description, <dfa.decisionNumber>, s, input )
930  @dfa<dfa.decisionNumber>.error( nva )
931  raise nva
932end
933>>
934
935cyclicDFASynpred( name ) ::= <<
936def <name>() @recognizer.<name> end<\n>
937>>
938
939cyclicDFAInit(dfa) ::= <<
940<if(dfa.specialStateSTs)>
941@dfa<dfa.decisionNumber> = DFA<dfa.decisionNumber>.new( self, <dfa.decisionNumber> ) do |s|
942  case s
943  <dfa.specialStateSTs:{state|when <i0>
944  <state>}; separator="\n">
945  end
946
947  if s \< 0
948<if(backtracking)>
949    @state.backtracking > 0 and raise ANTLR3::Error::BacktrackingFailed<\n>
950<endif>
951    nva = ANTLR3::Error::NoViableAlternative.new( @dfa<dfa.decisionNumber>.description, <dfa.decisionNumber>, s, input )
952    @dfa<dfa.decisionNumber>.error( nva )
953    raise nva
954  end
955
956  s
957end<\n>
958<else>
959@dfa<dfa.decisionNumber> = DFA<dfa.decisionNumber>.new( self, <dfa.decisionNumber> )<\n>
960<endif>
961>>
962
963
964/** A special state in a cyclic DFA; special means has a
965  * semantic predicate or it's a huge set of symbols to check.
966  */
967cyclicDFAState(decisionNumber, stateNumber, edges, needErrorClause, semPredState) ::= <<
968look_<decisionNumber>_<stateNumber> = @input.peek
969<if(semPredState)>
970index_<decisionNumber>_<stateNumber> = @input.index
971@input.rewind( @input.last_marker, false )<\n>
972<endif>
973s = -1
974<edges; separator="els">end
975<if(semPredState)> <! return input cursor to state before we rewound !>
976@input.seek( index_<decisionNumber>_<stateNumber> )<\n>
977<endif>
978>>
979
980/** Just like a fixed DFA edge, test the look and indicate
981  * what state to jump to next if successful.  Again, this is
982  * for special states.
983  */
984cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
985if ( <labelExpr> )<if(predicates)> and ( <predicates> )<endif>
986  s = <targetStateNumber><\n>
987>>
988
989/** An edge pointing at end-of-token; essentially matches any
990  * char; always jump to the target.
991  */
992eotDFAEdge(targetStateNumber, edgeNumber, predicates) ::= <<
993e
994  s = <targetStateNumber><\n>
995>>
996
997andPredicates(left,right) ::= "( <left> ) and ( <right> )"
998
999orPredicates(operands) ::= "( <first(operands)> )<rest(operands):{o|  or ( <o> )}>"
1000
1001notPredicate(pred) ::= "not ( <pred> )"
1002
1003evalPredicate(pred,description) ::= "( <pred> )"
1004
1005evalSynPredicate(pred,description) ::= <<
1006syntactic_predicate?( :<pred:{it | <it>}> )
1007>>
1008
1009lookaheadTest(atom, k, atomAsInt) ::= "look_<decisionNumber>_<stateNumber> == <atom>"
1010
1011/** Sometimes a look test cannot assume that LA(k) is in a
1012  * temp variable somewhere.  Must ask for the look
1013  * directly.
1014  */
1015isolatedLookaheadTest(atom, k, atomAsInt) ::= "@input.peek(<k>) == <atom>"
1016
1017lookaheadRangeTest(lower, upper, k, rangeNumber, lowerAsInt, upperAsInt) ::= <<
1018look_<decisionNumber>_<stateNumber>.between?( <lower>, <upper> )
1019>>
1020
1021isolatedLookaheadRangeTest(lower, upper, k, rangeNumber, lowerAsInt, upperAsInt) ::= <<
1022@input.peek( <k> ).between?( <lower>, <upper> )
1023>>
1024
1025setTest(ranges) ::= <<
1026<ranges; separator=" || ">
1027>>
1028
1029parameterAttributeRef(attr) ::= "<attr.name>"
1030
1031parameterSetAttributeRef(attr,expr) ::= "<attr.name> = <expr>"
1032
1033scopeAttributeRef(scope, attr, index, negIndex) ::= <<
1034<if(negIndex)>
1035@<scope>_stack[ -<negIndex> ].<attr.name>
1036<else>
1037<if(index)>
1038@<scope>_stack[ <index> ].<attr.name>
1039<else>
1040@<scope>_stack.last.<attr.name>
1041<endif>
1042<endif>
1043>>
1044
1045
1046scopeSetAttributeRef(scope, attr, expr, index, negIndex) ::= <<
1047<if(negIndex)>
1048@<scope>_stack[ -<negIndex> ].<attr.name> = <expr>
1049<else>
1050<if(index)>
1051@<scope>_stack[ <index> ].<attr.name> = <expr>
1052<else>
1053@<scope>_stack.last.<attr.name> = <expr>
1054<endif>
1055<endif>
1056>>
1057
1058
1059/** $x is either global scope or x is rule with dynamic scope;
1060  * refers to stack itself not top of stack.  This is useful for
1061  * predicates like {$function.size()>0 &&
1062  * $function::name.equals("foo")}?
1063  */
1064isolatedDynamicScopeRef(scope) ::= "@<scope>_stack"
1065
1066/** reference an attribute of rule; might only have single
1067  * return value
1068  */
1069ruleLabelRef(referencedRule, scope, attr) ::= <<
1070<if(referencedRule.hasMultipleReturnValues)>
1071( <scope; format="label">.nil? ? nil : <scope; format="label">.<attr.name> )
1072<else>
1073<scope; format="label">
1074<endif>
1075>>
1076
1077returnAttributeRef(ruleDescriptor, attr) ::= <<
1078<if(ruleDescriptor.hasMultipleReturnValues)>
1079return_value.<attr.name>
1080<else>
1081<attr.name>
1082<endif>
1083>>
1084
1085returnSetAttributeRef(ruleDescriptor, attr, expr) ::= <<
1086<if(ruleDescriptor.hasMultipleReturnValues)>
1087return_value.<attr.name> = <expr>
1088<else>
1089<attr.name> = <expr>
1090<endif>
1091>>
1092
1093/** How to translate $tokenLabel */
1094tokenLabelRef(label) ::= "<label; format=\"label\">"
1095
1096/** ids+=ID {$ids} or e+=expr {$e} */
1097listLabelRef(label) ::= "list_of_<label; format=\"label\">"
1098
1099tokenLabelPropertyRef_text(scope, attr) ::= "<scope; format=\"label\">.text"
1100tokenLabelPropertyRef_type(scope, attr) ::= "<scope; format=\"label\">.type"
1101tokenLabelPropertyRef_line(scope, attr) ::= "<scope; format=\"label\">.line"
1102tokenLabelPropertyRef_pos(scope, attr) ::= "<scope; format=\"label\">.column"
1103tokenLabelPropertyRef_channel(scope, attr) ::= "<scope; format=\"label\">.channel"
1104tokenLabelPropertyRef_index(scope, attr) ::= "<scope; format=\"label\">.index"
1105tokenLabelPropertyRef_tree(scope, attr) ::= "tree_for_<scope>"
1106
1107ruleLabelPropertyRef_start(scope, attr) ::= "<scope; format=\"label\">.start"
1108ruleLabelPropertyRef_stop(scope, attr) ::= "<scope; format=\"label\">.stop"
1109ruleLabelPropertyRef_tree(scope, attr) ::= "<scope; format=\"label\">.tree"
1110
1111ruleLabelPropertyRef_text(scope, attr) ::= <<
1112<if(TREE_PARSER)>
1113(
1114  @input.token_stream.to_s(
1115    @input.tree_adaptor.token_start_index( <scope; format="label">.start ),
1116    @input.tree_adaptor.token_stop_index( <scope; format="label">.start )
1117  ) if <scope; format="label">
1118)
1119<else>
1120( <scope; format="label"> && @input.to_s( <scope; format="label">.start, <scope; format="label">.stop ) )
1121<endif>
1122>>
1123ruleLabelPropertyRef_st(scope, attr) ::= "( <scope; format=\"label\"> && <scope; format=\"label\">.template )"
1124
1125/******************************************************************************
1126 *****************  L E X E R - O N L Y   T E M P L A T E S  ******************
1127 ******************************************************************************/
1128
1129lexerSynpred(name) ::= ""
1130
1131lexer(grammar, name, tokens, scopes, rules, numRules, labelType="ANTLR3::Token", filterMode, superClass="ANTLR3::Lexer") ::= <<
1132<if(grammar.grammarIsRoot)><autoloadDelegates()><endif>
1133
1134class <if(grammar.delegator)><grammar.name><else>Lexer<endif> \< <superClass>
1135  @grammar_home = <grammar.name>
1136<if(!grammar.grammarIsRoot)>
1137  <autoloadDelegates()><\n>
1138<endif>
1139  include TokenData
1140<if(filterMode)>
1141  include ANTLR3::FilterMode<\n>
1142<endif>
1143  <scopes:{it | <if(it.isDynamicGlobalScope)><globalAttributeScopeClass()><\n><endif>}>
1144
1145  begin
1146    generated_using( "<fileName>", "<ANTLRVersion>", "<runtimeLibraryVersion()>" )
1147  rescue NoMethodError => error
1148    # ignore
1149  end
1150
1151  RULE_NAMES   = [ <trunc(rules):{r|"<r.ruleName>"}; separator=", ", wrap="\n", anchor> ].freeze
1152  RULE_METHODS = [ <trunc(rules):{r|:<r.ruleName; format="lexerRule">}; separator=", ", wrap="\n", anchor> ].freeze
1153
1154<if(grammar.delegators)>
1155  masters( <grammar.delegators:{d|:<d.name>}; separator=", "> )<\n>
1156<endif>
1157<if(grammar.directDelegates)>
1158  imports( <grammar.directDelegates:{d|:<d.name>}; separator=", "> )<\n>
1159<endif>
1160
1161  def initialize( <grammar.delegators:{g|<g:delegateName()>, }>input=nil, options = {} )
1162    super( input, options )
1163<if(memoize)>
1164<if(grammar.grammarIsRoot)>
1165    @state.rule_memory = {}<\n>
1166<endif>
1167<endif>
1168    <grammar.delegators:{g|@<g:delegateName()> = <g:delegateName()><\n>}><grammar.directDelegates:{g|@<g:delegateName()> = <newDelegate(g)><\n>}><last(grammar.delegators):{g|@parent = @<g:delegateName()><\n>}><placeAction(scope="lexer",name="init")>
1169  end
1170
1171  <placeAction(scope="lexer",name="members")>
1172
1173  # - - - - - - - - - - - lexer rules - - - - - - - - - - - -
1174  <rules:{it | <it><\n>}>
1175<if(grammar.delegatedRules)>
1176
1177  # - - - - - - - - - - delegated rules - - - - - - - - - - -
1178  <grammar.delegatedRules:{ruleDescriptor|<delegateLexerRule(ruleDescriptor)><\n><\n>}>
1179<endif>
1180<if(cyclicDFAs)>
1181
1182  # - - - - - - - - - - DFA definitions - - - - - - - - - - -
1183  <cyclicDFAs:cyclicDFA()>
1184
1185  private
1186
1187  def initialize_dfas
1188    super rescue nil
1189    <cyclicDFAs:cyclicDFAInit()>
1190  end
1191
1192<endif>
1193end # class <if(grammar.delegator)><grammar.name><else>Lexer<endif> \< <superClass>
1194<if(!actions.(actionScope).main)>
1195
1196at_exit { <if(grammar.delegator)><grammar.name><else>Lexer<endif>.main( ARGV ) } if __FILE__ == $0
1197<endif>
1198>>
1199
1200
1201lexerRuleLabelDefs() ::= <<
1202<if([ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels,ruleDescriptor.ruleLabels,ruleDescriptor.charLabels,ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels])>
1203# - - - - label initialization - - - -
1204<[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels,ruleDescriptor.ruleLabels,ruleDescriptor.charLabels]:{it | <it.label.text; format="label"> = nil<\n>}>
1205<[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]:{it | list_of_<it.label.text; format="label"> = [] unless defined?(list_of_<it.label.text; format="label">)<\n>}>
1206<endif>
1207>>
1208
1209
1210/** How to generate a rule in the lexer; naked blocks are used
1211  * for fragment rules.
1212  */
1213lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= <<
1214# lexer rule <ruleName; format="lexerRule"> (<ruleName>)
1215# (in <fileName>)
1216def <ruleName; format="lexerRule"><if(ruleDescriptor.parameterScope)>( <ruleDescriptor.parameterScope:parameterScope()> )<endif>
1217  <traceIn()><ruleScopeSetUp()><ruleDeclarations()><if(memoize)>
1218<if(backtracking)>
1219
1220  # backtracking success
1221  success = false<\n>
1222<endif>
1223<endif>
1224<if(nakedBlock)>
1225  <ruleMemoization({<ruleName; format="lexerRule">})><lexerRuleLabelDefs()><action(name="init", code=ruleDescriptor.actions.init)>
1226
1227  # - - - - main rule block - - - -
1228  <block>
1229<else>
1230
1231  type = <ruleName>
1232  channel = ANTLR3::DEFAULT_CHANNEL
1233  <ruleMemoization(ruleName)><lexerRuleLabelDefs()><action(name="init", code=ruleDescriptor.actions.init)>
1234
1235  # - - - - main rule block - - - -
1236  <block>
1237  <ruleCleanUp()>
1238
1239  @state.type = type
1240  @state.channel = channel
1241<(ruleDescriptor.actions.after):execAction()>
1242<endif>
1243<if(memoize)><if(backtracking)>
1244  success = false<\n>
1245<endif><endif>
1246ensure
1247  <traceOut()><ruleScopeCleanUp()><memoize()>
1248end
1249<! <if(ruleDescriptor.modifier)>
1250
1251<ruleDescriptor.modifier> :<ruleName; format="lexerRule"><\n>
1252<endif> !>
1253>>
1254
1255
1256/** Isolated $RULE ref ok in lexer as it's a Token */
1257lexerRuleLabel(label) ::= "<label; format=\"label\">"
1258lexerRuleLabelPropertyRef_line(scope, attr) ::= "<scope; format=\"label\">.line"
1259lexerRuleLabelPropertyRef_type(scope, attr) ::= "<scope; format=\"label\">.type"
1260lexerRuleLabelPropertyRef_pos(scope, attr) ::= "<scope; format=\"label\">.column"
1261lexerRuleLabelPropertyRef_channel(scope, attr) ::= "<scope; format=\"label\">.channel"
1262lexerRuleLabelPropertyRef_index(scope, attr) ::= "<scope; format=\"label\">.index"
1263lexerRuleLabelPropertyRef_text(scope, attr) ::= "<scope; format=\"label\">.text"
1264
1265
1266/** How to generate code for the implicitly-defined lexer
1267  * grammar rule that chooses between lexer rules.
1268  */
1269tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
1270# main rule used to study the input at the current position,
1271# and choose the proper lexer rule to call in order to
1272# fetch the next token
1273#
1274# usually, you don't make direct calls to this method,
1275# but instead use the next_token method, which will
1276# build and emit the actual next token
1277def <ruleName; format="lexerRule">
1278  <block>
1279end
1280>>
1281
1282lexerRulePropertyRef_text(scope, attr) ::= "self.text"
1283lexerRulePropertyRef_type(scope, attr) ::= "type"
1284lexerRulePropertyRef_line(scope, attr) ::= "@state.token_start_line"
1285lexerRulePropertyRef_pos(scope, attr)  ::= "@state.token_start_column"
1286
1287/** Undefined, but present for consistency with Token
1288  * attributes; set to -1
1289  */
1290lexerRulePropertyRef_index(scope, attr) ::= "-1"
1291lexerRulePropertyRef_channel(scope, attr) ::= "channel"
1292lexerRulePropertyRef_start(scope, attr) ::= "@state.token_start_position"
1293lexerRulePropertyRef_stop(scope, attr) ::= "( self.character_index - 1 )"
1294
1295/** A lexer rule reference */
1296lexerRuleRef(rule,label,args,elementIndex,scope) ::= <<
1297<if(label)>
1298<label; format="label">_start_<elementIndex> = self.character_index
1299<methodCall(n={<rule.name; format="lexerRule">},del=scope,args=args)>
1300<label; format="label"> = create_token do |t|
1301  t.input   = @input
1302  t.type    = ANTLR3::INVALID_TOKEN_TYPE
1303  t.channel = ANTLR3::DEFAULT_CHANNEL
1304  t.start   = <label; format="label">_start_<elementIndex>
1305  t.stop    = self.character_index - 1
1306end
1307<else>
1308<methodCall(n={<rule.name; format="lexerRule">}, del=scope, args=args)>
1309<endif>
1310>>
1311
1312
1313/** i+=INT in lexer */
1314lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
1315<lexerRuleRef(...)>
1316<addToList(elem={<label; format="label">},...)>
1317>>
1318
1319
1320/** Match . wildcard in lexer */
1321wildcardChar(label, elementIndex) ::= <<
1322<if(label)>
1323<label; format="label"> = @input.peek<\n>
1324<endif>
1325match_any
1326>>
1327
1328wildcardCharListLabel(label, elementIndex) ::= <<
1329<wildcardChar(...)>
1330<addToList(elem={<label; format="label">},...)>
1331>>
1332
1333/** match a character */
1334charRef(char,label) ::= <<
1335<if(label)>
1336<label; format="label"> = @input.peek<\n>
1337<endif>
1338match( <char> )
1339>>
1340
1341/** match a character range */
1342charRangeRef(a,b,label) ::= <<
1343<if(label)>
1344<label; format="label"> = @input.peek<\n>
1345<endif>
1346match_range( <a>, <b> )
1347>>
1348
1349filteringNextToken() ::= ""
1350filteringActionGate() ::= "@state.backtracking == 1"
1351
1352/** Match a string literal */
1353lexerStringRef(string,label,elementIndex) ::= <<
1354<if(label)>
1355<label; format="label">_start = self.character_index
1356match( <string> )
1357<label; format="label"> = create_token do |t|
1358  t.input   = @input
1359  t.type    = ANTLR3::INVALID_TOKEN_TYPE
1360  t.channel = ANTLR3::DEFAULT_CHANNEL
1361  t.start   = <label; format="label">_start
1362  t.stop    = character_index - 1
1363end
1364<else>
1365match( <string> )
1366<endif>
1367>>
1368
1369
1370/** EOF in the lexer */
1371lexerMatchEOF(label,elementIndex) ::= <<
1372<if(label)>
1373<label; format="label">_start_<elementIndex> = character_index
1374match( ANTLR3::EOF )
1375<label; format="label"> = create_token do |t|
1376  t.input   = @input
1377  t.type    = ANTLR3::INVALID_TOKEN_TYPE
1378  t.channel = ANTLR3::DEFAULT_CHANNEL
1379  t.start   = <label; format="label">_start_<elementIndex>
1380  t.stop    = character_index - 1
1381end<\n>
1382<else>
1383match( ANTLR3::EOF )<\n>
1384<endif>
1385>>
1386
1387// used for left-recursive rules
1388recRuleDefArg()                       ::= "int <recRuleArg()>"
1389recRuleArg()                          ::= "_p"
1390recRuleAltPredicate(ruleName,opPrec)  ::= "<recRuleArg()> \<= <opPrec>"
1391recRuleSetResultAction()              ::= "root_0=$<ruleName>_primary.tree;"
1392recRuleSetReturnAction(src,name)      ::= "$<name>=$<src>.<name>;"
1393
1394/** $start in parser rule */
1395rulePropertyRef_start(scope, attr) ::= "return_value.start"
1396
1397/** $stop in parser rule */
1398rulePropertyRef_stop(scope, attr) ::= "return_value.stop"
1399
1400/** $tree in parser rule */
1401rulePropertyRef_tree(scope, attr) ::= "return_value.tree"
1402
1403/** $text in parser rule */
1404rulePropertyRef_text(scope, attr) ::= "@input.to_s( return_value.start, @input.look( -1 ) )"
1405
1406/** $template in parser rule */
1407rulePropertyRef_st(scope, attr) ::= "return_value.template"
1408
1409ruleSetPropertyRef_tree(scope, attr, expr) ::= "return_value.tree = <expr>"
1410
1411ruleSetPropertyRef_st(scope, attr, expr) ::= "return_value.template = <expr>"
1412
1413/** How to execute an action */
1414execAction(action) ::= <<
1415<if(backtracking)>
1416# syntactic predicate action gate test
1417if <actions.(actionScope).synpredgate>
1418  # --> action
1419  <action>
1420  # \<-- action
1421end
1422<else>
1423# --> action
1424<action>
1425# \<-- action
1426<endif>
1427>>
1428
1429codeFileExtension() ::= ".rb"
1430
1431true()  ::= "true"
1432false() ::= "false"
1433
1434action(name, code) ::= <<
1435<if(code)>
1436# - - - - @<name> action - - - -
1437<code><\n>
1438<endif>
1439>>
1440
1441autoloadDelegates() ::= <<
1442<if(grammar.directDelegates)>
1443<grammar.directDelegates:{it | autoload :<it.name>, "<it.recognizerName>"<\n>}>
1444<endif>
1445>>
1446
1447delegateLexerRule(ruleDescriptor) ::= <<
1448# delegated lexer rule <ruleDescriptor.name; format="lexerRule"> (<ruleDescriptor.name> in the grammar)
1449def <ruleDescriptor.name; format="lexerRule"><if(ruleDescriptor.parameterScope)>( <ruleDescriptor.parameterScope:parameterScope()> )<endif>
1450  <methodCall(del=ruleDescriptor.grammar, n={<ruleDescriptor.name; format="lexerRule">}, args=ruleDescriptor.parameterScope.attributes)>
1451end
1452>>
1453
1454rootClassName() ::= <<
1455<if(grammar.grammarIsRoot)><grammar.name><else><grammar.composite.rootGrammar.name><endif>::<if(TREE_PARSER)>TreeParser<elseif(PARSER)>Parser<else>Lexer<endif>
1456>>
1457
1458grammarClassName() ::= <<
1459<gram.name>::<if(TREE_PARSER)>TreeParser<elseif(PARSER)>Parser<else>Lexer<endif>
1460>>
1461
1462newDelegate(gram) ::= <<
1463<gram.name>.new( <trunc(gram.delegators):{p|<p:delegateName()>, }>
1464  self, @input, :state => @state<@delegateOptions()>
1465)
1466>>
1467
1468placeAction(scope, name) ::= <<
1469<if(actions.(scope).(name))>
1470# - - - - - - begin action @<scope>::<name> - - - - - -
1471<if(fileName)># <fileName><\n><endif>
1472<actions.(scope).(name)>
1473# - - - - - - end action @<scope>::<name> - - - - - - -<\n>
1474<endif>
1475>>
1476
1477runtimeLibraryVersion() ::= "1.8.1"
1478