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