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.
Files changed (85) hide show
  1. data/ANTLR-LICENSE.txt +26 -0
  2. data/History.txt +66 -0
  3. data/README.txt +139 -0
  4. data/bin/antlr4ruby +33 -0
  5. data/java/RubyTarget.java +524 -0
  6. data/java/antlr-full-3.2.1.jar +0 -0
  7. data/lib/antlr3.rb +176 -0
  8. data/lib/antlr3/constants.rb +88 -0
  9. data/lib/antlr3/debug.rb +701 -0
  10. data/lib/antlr3/debug/event-hub.rb +210 -0
  11. data/lib/antlr3/debug/record-event-listener.rb +25 -0
  12. data/lib/antlr3/debug/rule-tracer.rb +55 -0
  13. data/lib/antlr3/debug/socket.rb +360 -0
  14. data/lib/antlr3/debug/trace-event-listener.rb +92 -0
  15. data/lib/antlr3/dfa.rb +247 -0
  16. data/lib/antlr3/dot.rb +174 -0
  17. data/lib/antlr3/error.rb +657 -0
  18. data/lib/antlr3/main.rb +561 -0
  19. data/lib/antlr3/modes/ast-builder.rb +41 -0
  20. data/lib/antlr3/modes/filter.rb +56 -0
  21. data/lib/antlr3/profile.rb +322 -0
  22. data/lib/antlr3/recognizers.rb +1280 -0
  23. data/lib/antlr3/streams.rb +985 -0
  24. data/lib/antlr3/streams/interactive.rb +91 -0
  25. data/lib/antlr3/streams/rewrite.rb +412 -0
  26. data/lib/antlr3/test/call-stack.rb +57 -0
  27. data/lib/antlr3/test/config.rb +23 -0
  28. data/lib/antlr3/test/core-extensions.rb +269 -0
  29. data/lib/antlr3/test/diff.rb +165 -0
  30. data/lib/antlr3/test/functional.rb +207 -0
  31. data/lib/antlr3/test/grammar.rb +371 -0
  32. data/lib/antlr3/token.rb +592 -0
  33. data/lib/antlr3/tree.rb +1415 -0
  34. data/lib/antlr3/tree/debug.rb +163 -0
  35. data/lib/antlr3/tree/visitor.rb +84 -0
  36. data/lib/antlr3/tree/wizard.rb +481 -0
  37. data/lib/antlr3/util.rb +149 -0
  38. data/lib/antlr3/version.rb +27 -0
  39. data/samples/ANTLRv3Grammar.g +621 -0
  40. data/samples/Cpp.g +749 -0
  41. data/templates/AST.stg +335 -0
  42. data/templates/ASTDbg.stg +40 -0
  43. data/templates/ASTParser.stg +153 -0
  44. data/templates/ASTTreeParser.stg +272 -0
  45. data/templates/Dbg.stg +192 -0
  46. data/templates/Ruby.stg +1514 -0
  47. data/test/functional/ast-output/auto-ast.rb +797 -0
  48. data/test/functional/ast-output/construction.rb +555 -0
  49. data/test/functional/ast-output/hetero-nodes.rb +753 -0
  50. data/test/functional/ast-output/rewrites.rb +1327 -0
  51. data/test/functional/ast-output/tree-rewrite.rb +1662 -0
  52. data/test/functional/debugging/debug-mode.rb +689 -0
  53. data/test/functional/debugging/profile-mode.rb +165 -0
  54. data/test/functional/debugging/rule-tracing.rb +74 -0
  55. data/test/functional/delegation/import.rb +379 -0
  56. data/test/functional/lexer/basic.rb +559 -0
  57. data/test/functional/lexer/filter-mode.rb +245 -0
  58. data/test/functional/lexer/nuances.rb +47 -0
  59. data/test/functional/lexer/properties.rb +104 -0
  60. data/test/functional/lexer/syn-pred.rb +32 -0
  61. data/test/functional/lexer/xml.rb +206 -0
  62. data/test/functional/main/main-scripts.rb +245 -0
  63. data/test/functional/parser/actions.rb +224 -0
  64. data/test/functional/parser/backtracking.rb +244 -0
  65. data/test/functional/parser/basic.rb +282 -0
  66. data/test/functional/parser/calc.rb +98 -0
  67. data/test/functional/parser/ll-star.rb +143 -0
  68. data/test/functional/parser/nuances.rb +165 -0
  69. data/test/functional/parser/predicates.rb +103 -0
  70. data/test/functional/parser/properties.rb +242 -0
  71. data/test/functional/parser/rule-methods.rb +132 -0
  72. data/test/functional/parser/scopes.rb +274 -0
  73. data/test/functional/token-rewrite/basic.rb +318 -0
  74. data/test/functional/token-rewrite/via-parser.rb +100 -0
  75. data/test/functional/tree-parser/basic.rb +750 -0
  76. data/test/unit/sample-input/file-stream-1 +2 -0
  77. data/test/unit/sample-input/teststreams.input2 +2 -0
  78. data/test/unit/test-dfa.rb +52 -0
  79. data/test/unit/test-exceptions.rb +44 -0
  80. data/test/unit/test-recognizers.rb +55 -0
  81. data/test/unit/test-scheme.rb +62 -0
  82. data/test/unit/test-streams.rb +459 -0
  83. data/test/unit/test-tree-wizard.rb +535 -0
  84. data/test/unit/test-trees.rb +854 -0
  85. metadata +205 -0
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+ module Util
6
+
7
+ module_function
8
+
9
+ def snake_case(str)
10
+ str = str.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
11
+ str.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
12
+ str.tr!("-", "_")
13
+ str.downcase!
14
+ str
15
+ end
16
+
17
+ def tidy(here_doc, flow = false)
18
+ here_doc.gsub!(/^ *\| ?/, '')
19
+ if flow
20
+ here_doc.strip!
21
+ here_doc.gsub!(/\s+/, ' ')
22
+ end
23
+ return here_doc
24
+ end
25
+
26
+ def silence_warnings
27
+ verbosity, $VERBOSE = $VERBOSE, nil
28
+ return yield
29
+ ensure
30
+ $VERBOSE = verbosity
31
+ end
32
+
33
+ end
34
+
35
+ module ClassMacros
36
+
37
+ private
38
+
39
+ def shared_attribute( name, *additional_members )
40
+ attr_reader name
41
+
42
+ additional_writers = additional_members.inject('') do |src, attr|
43
+ src << "@#{attr} = value if @#{attr}\n"
44
+ end
45
+
46
+ file, line, = caller[1].split(':', 3)
47
+ class_eval(<<-END, file, line.to_i)
48
+ def #{name}= value
49
+ @#{name} = value
50
+
51
+ each_delegate do |del|
52
+ del.#{name} = value
53
+ end
54
+
55
+ #{additional_writers}
56
+ end
57
+ END
58
+ end
59
+
60
+ def abstract( name, message = nil )
61
+ message ||= "abstract method -- #{self.class}::#{name} has not been implemented"
62
+ file, line, = caller[1].split(':', 3)
63
+ class_eval(<<-END, file, line.to_i)
64
+ def #{name}( * )
65
+ raise TypeError, #{message.to_s.inspect}
66
+ end
67
+ END
68
+ end
69
+
70
+ def alias_accessor( alias_name, attr_name )
71
+ alias_method( alias_name, attr_name )
72
+ alias_method( :"#{alias_name}=", :"#{attr_name}=" )
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
79
+ class Integer
80
+
81
+ # Returns the lower of self or x.
82
+ #
83
+ # 4.at_least(5) #=> 5
84
+ # 6.at_least(5) #=> 6
85
+ #
86
+ # CREDIT Florian Gross
87
+
88
+ def at_least(x)
89
+ (self >= x) ? self : x
90
+ end
91
+
92
+ # Returns the greater of self or x.
93
+ #
94
+ # 4.at_most(5) #=> 4
95
+ # 6.at_most(5) #=> 5
96
+ #
97
+ # CREDIT Florian Gross
98
+
99
+ def at_most(x)
100
+ (self <= x) ? self : x
101
+ end
102
+
103
+ # Returns self if above the given lower bound, or
104
+ # within the given lower and upper bounds,
105
+ # otherwise returns the the bound of which the
106
+ # value falls outside.
107
+ #
108
+ # 4.bound(3) #=> 4
109
+ # 4.bound(5) #=> 5
110
+ # 4.bound(2,7) #=> 4
111
+ # 9.bound(2,7) #=> 7
112
+ # 1.bound(2,7) #=> 2
113
+ #
114
+ # CREDIT Trans
115
+
116
+ def bound(lower, upper=nil)
117
+ return lower if self < lower
118
+ return self unless upper
119
+ return upper if self > upper
120
+ return self
121
+ end
122
+
123
+ end
124
+
125
+
126
+ class Range
127
+ def covers?(range)
128
+ range.first >= first or return false
129
+ if exclude_end?
130
+ range.exclude_end? ? last >= range.last : last > range.last
131
+ else
132
+ range.exclude_end? ? last.succ >= range.last : last >= range.last
133
+ end
134
+ end
135
+
136
+ def covered_by?(range)
137
+ range.covers?(self)
138
+ end
139
+
140
+ def overlaps?(range)
141
+ range.include?(first) or include?(range.first)
142
+ end
143
+
144
+ def disjoint?(range)
145
+ not overlaps?(range)
146
+ end
147
+
148
+ end
149
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+
6
+ #
7
+ # The version of the ANTLR tool used while designing and
8
+ # testing the current version of this library
9
+ #
10
+ ANTLR_MAJOR_VERSION = 3
11
+ ANTLR_MINOR_VERSION = 2
12
+ ANTLR_PATCH_VERSION = 1
13
+ ANTLR_VERSION = [ANTLR_MAJOR_VERSION, ANTLR_MINOR_VERSION, ANTLR_PATCH_VERSION].freeze
14
+ ANTLR_VERSION_STRING = ANTLR_VERSION.join('.')
15
+ ANTLR_VERSION_STRING.chomp!( '.0' ) # versioning drops minor version at 0
16
+ ANTLR_VERSION_STRING.freeze
17
+
18
+ #
19
+ # The version data for the current state the library itself
20
+ #
21
+ MAJOR_VERSION = 1
22
+ MINOR_VERSION = 2
23
+ PATCH_VERSION = 3
24
+ VERSION = [MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION]
25
+ VERSION_STRING = VERSION.join('.').freeze
26
+
27
+ end
@@ -0,0 +1,621 @@
1
+ /*
2
+ [The "BSD licence"]
3
+ Copyright (c) 2005-2007 Terence Parr
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+ 3. The name of the author may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ /** ANTLR v3 grammar written in ANTLR v3 with AST construction */
30
+ grammar ANTLRv3Grammar;
31
+
32
+ options {
33
+ ASTLabelType = CommonTree;
34
+ language = Ruby;
35
+ output = AST;
36
+ }
37
+
38
+ tokens {
39
+ DOC_COMMENT;
40
+ PARSER;
41
+ LEXER;
42
+ RULE;
43
+ BLOCK;
44
+ OPTIONAL;
45
+ CLOSURE;
46
+ POSITIVE_CLOSURE;
47
+ SYNPRED;
48
+ RANGE;
49
+ CHAR_RANGE;
50
+ EPSILON;
51
+ ALT;
52
+ EOR;
53
+ EOB;
54
+ EOA; // end of alt
55
+ ID;
56
+ ARG;
57
+ ARGLIST;
58
+ RET='returns';
59
+ LEXER_GRAMMAR;
60
+ PARSER_GRAMMAR;
61
+ TREE_GRAMMAR;
62
+ COMBINED_GRAMMAR;
63
+ LABEL; // $x used in rewrite rules
64
+ TEMPLATE;
65
+ SCOPE='scope';
66
+ SEMPRED;
67
+ GATED_SEMPRED; // {p}? =>
68
+ SYN_SEMPRED; // (...) => it's a manually-specified synpred converted to sempred
69
+ BACKTRACK_SEMPRED; // auto backtracking mode syn pred converted to sempred
70
+ FRAGMENT='fragment';
71
+ TREE_BEGIN='^(';
72
+ ROOT='^';
73
+ BANG='!';
74
+ RANGE='..';
75
+ REWRITE='->';
76
+ AT='@';
77
+ LABEL_ASSIGN='=';
78
+ LIST_LABEL_ASSIGN='+=';
79
+ }
80
+
81
+ /* action -> @parser::header
82
+ {
83
+ package org.antlr.grammar.v3;
84
+ } */
85
+ /* action -> @lexer::header
86
+ {
87
+ package org.antlr.grammar.v3;
88
+ } */
89
+
90
+ @members {
91
+ attr_reader :grammar_type
92
+ }
93
+
94
+ grammar_def
95
+ : DOC_COMMENT?
96
+ ( 'lexer' { @grammar_type = LEXER_GRAMMAR } // pure lexer
97
+ | 'parser' { @grammar_type = PARSER_GRAMMAR } // pure parser
98
+ | 'tree' { @grammar_type = TREE_GRAMMAR } // a tree parser
99
+ | { @grammar_type = COMBINED_GRAMMAR } // merged parser/lexer
100
+ )
101
+ g='grammar' id ';' options_spec? tokens_spec? attr_scope* action*
102
+ rule+
103
+ EOF
104
+ -> ^( {@adaptor.create!(@grammar_type, $g) }
105
+ id DOC_COMMENT? options_spec? tokens_spec? attr_scope* action* rule+
106
+ )
107
+ ;
108
+
109
+ tokens_spec
110
+ : TOKENS token_spec+ '}' -> ^(TOKENS token_spec+)
111
+ ;
112
+
113
+ token_spec
114
+ : TOKEN_REF
115
+ ( '=' (lit=STRING_LITERAL|lit=CHAR_LITERAL) -> ^('=' TOKEN_REF $lit)
116
+ | -> TOKEN_REF
117
+ )
118
+ ';'
119
+ ;
120
+
121
+ attr_scope
122
+ : 'scope' id ACTION -> ^('scope' id ACTION)
123
+ ;
124
+
125
+ /** Match stuff like @parser::members {int i;} */
126
+ action
127
+ : '@' (action_scope_name '::')? id ACTION -> ^('@' action_scope_name? id ACTION)
128
+ ;
129
+
130
+ /** Sometimes the scope names will collide with keywords; allow them as
131
+ * ids for action scopes.
132
+ */
133
+ action_scope_name
134
+ : id
135
+ | l='lexer' -> ID[$l]
136
+ | p='parser' -> ID[$p]
137
+ ;
138
+
139
+ options_spec
140
+ : OPTIONS (option ';')+ '}' -> ^(OPTIONS option+)
141
+ ;
142
+
143
+ option
144
+ : id '=' option_value -> ^('=' id option_value)
145
+ ;
146
+
147
+ option_value
148
+ : qid
149
+ | STRING_LITERAL
150
+ | CHAR_LITERAL
151
+ | INT
152
+ | s='*' -> STRING_LITERAL[$s] // used for k=*
153
+ ;
154
+
155
+ rule
156
+ scope {
157
+ name;
158
+ }
159
+ : DOC_COMMENT?
160
+ ( modifier=('protected'|'public'|'private'|'fragment') )?
161
+ id { $rule::name = $id.text }
162
+ '!'?
163
+ ( arg=ARG_ACTION )?
164
+ ( 'returns' rt=ARG_ACTION )?
165
+ throws_spec? options_spec? rule_scope_spec? rule_action*
166
+ ':' alt_list ';'
167
+ exception_group?
168
+ -> ^( RULE id {$modifier ? @adaptor.create!($modifier) : nil} ^(ARG[$arg] $arg)? ^('returns' $rt)?
169
+ throws_spec? options_spec? rule_scope_spec? rule_action*
170
+ alt_list
171
+ exception_group?
172
+ EOR["EOR"]
173
+ )
174
+ ;
175
+
176
+ /** Match stuff like @init {int i;} */
177
+ rule_action
178
+ : '@' id ACTION -> ^('@' id ACTION)
179
+ ;
180
+
181
+ throws_spec
182
+ : 'throws' id ( ',' id )* -> ^('throws' id+)
183
+ ;
184
+
185
+ rule_scope_spec
186
+ : 'scope' ACTION -> ^('scope' ACTION)
187
+ | 'scope' id (',' id)* ';' -> ^('scope' id+)
188
+ | 'scope' ACTION
189
+ 'scope' id (',' id)* ';'
190
+ -> ^('scope' ACTION id+ )
191
+ ;
192
+
193
+ block
194
+ : lp='('
195
+ ( (opts=options_spec)? ':' )?
196
+ altpair ( '|' altpair )*
197
+ rp=')'
198
+ -> ^( BLOCK[$lp,"BLOCK"] options_spec? altpair+ EOB[$rp,"EOB"] )
199
+ ;
200
+
201
+ altpair : alternative rewrite ;
202
+
203
+ alt_list
204
+ @init {
205
+ block_root = @adaptor.create!(BLOCK, @input.look(-1), "BLOCK");
206
+ }
207
+ : altpair ( '|' altpair )* -> ^( {block_root} altpair+ EOB["eob"] )
208
+ ;
209
+
210
+ alternative
211
+ @init {
212
+ first_token = @input.look(1)
213
+ prev_token = @input.look(-1)
214
+ }
215
+ : element+ -> ^(ALT[first_token,"ALT"] element+ EOA["EOA"])
216
+ | -> ^(ALT[prev_token,"ALT"] EPSILON[prev_token,"EPSILON"] EOA["EOA"])
217
+ ;
218
+
219
+ exception_group
220
+ : ( exception_handler )+ ( finally_clause )?
221
+ | finally_clause
222
+ ;
223
+
224
+ exception_handler
225
+ : 'catch' ARG_ACTION ACTION -> ^('catch' ARG_ACTION ACTION)
226
+ ;
227
+
228
+ finally_clause
229
+ : 'finally' ACTION -> ^('finally' ACTION)
230
+ ;
231
+
232
+ element
233
+ : id (labelOp='='|labelOp='+=') atom
234
+ ( ebnf_suffix -> ^( ebnf_suffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] ^($labelOp id atom) EOA["EOA"]) EOB["EOB"]))
235
+ | -> ^($labelOp id atom)
236
+ )
237
+ | id (labelOp='='|labelOp='+=') block
238
+ ( ebnf_suffix -> ^( ebnf_suffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] ^($labelOp id block) EOA["EOA"]) EOB["EOB"]))
239
+ | -> ^($labelOp id block)
240
+ )
241
+ | atom
242
+ ( ebnf_suffix -> ^( ebnf_suffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] atom EOA["EOA"]) EOB["EOB"]) )
243
+ | -> atom
244
+ )
245
+ | ebnf
246
+ | ACTION
247
+ | SEMPRED ( g='=>' -> GATED_SEMPRED[$g] | -> SEMPRED )
248
+ | tree_spec
249
+ ( ebnf_suffix -> ^( ebnf_suffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] tree_spec EOA["EOA"]) EOB["EOB"]) )
250
+ | -> tree_spec
251
+ )
252
+ ;
253
+
254
+ atom: terminal
255
+ | range
256
+ ( (op='^'|op='!') -> ^($op range)
257
+ | -> range
258
+ )
259
+ | not_set
260
+ ( (op='^'|op='!') -> ^($op not_set)
261
+ | -> not_set
262
+ )
263
+ | RULE_REF ARG_ACTION?
264
+ ( (op='^'|op='!') -> ^($op RULE_REF ARG_ACTION?)
265
+ | -> ^(RULE_REF ARG_ACTION?)
266
+ )
267
+ ;
268
+
269
+ not_set
270
+ : '~'
271
+ ( not_terminal element_options? -> ^('~' not_terminal element_options?)
272
+ | block element_options? -> ^('~' block element_options?)
273
+ )
274
+ ;
275
+
276
+ not_terminal
277
+ : CHAR_LITERAL
278
+ | TOKEN_REF
279
+ | STRING_LITERAL
280
+ ;
281
+
282
+ element_options
283
+ : '<' qid '>' -> ^(OPTIONS qid)
284
+ | '<' option (';' option)* '>' -> ^(OPTIONS option+)
285
+ ;
286
+
287
+ element_option
288
+ : id '=' option_value -> ^('=' id option_value)
289
+ ;
290
+
291
+ tree_spec
292
+ : '^(' element ( element )+ ')' -> ^(TREE_BEGIN element+)
293
+ ;
294
+
295
+ range!
296
+ : c1=CHAR_LITERAL RANGE c2=CHAR_LITERAL element_options?
297
+ -> ^(CHAR_RANGE[$c1,".."] $c1 $c2 element_options?)
298
+ ;
299
+
300
+ terminal
301
+ : ( CHAR_LITERAL element_options? -> ^(CHAR_LITERAL element_options?)
302
+ // Args are only valid for lexer rules
303
+ | TOKEN_REF ARG_ACTION? element_options? -> ^(TOKEN_REF ARG_ACTION? element_options?)
304
+ | STRING_LITERAL element_options? -> ^(STRING_LITERAL element_options?)
305
+ | '.' element_options? -> ^('.' element_options?)
306
+ )
307
+ ( '^' -> ^('^' $terminal)
308
+ | '!' -> ^('!' $terminal)
309
+ )?
310
+ ;
311
+
312
+ /** Matches ENBF blocks (and token sets via block rule) */
313
+ ebnf
314
+ @init { first_token = @input.look(1) }
315
+ @after {
316
+ $ebnf.tree.token.line = first_token.line
317
+ $ebnf.tree.token.column = first_token.column
318
+ }
319
+ : block
320
+ ( op='?' -> ^(OPTIONAL[$op] block)
321
+ | op='*' -> ^(CLOSURE[$op] block)
322
+ | op='+' -> ^(POSITIVE_CLOSURE[$op] block)
323
+ | '=>' // syntactic predicate
324
+ -> {
325
+ @grammar_type == COMBINED_GRAMMAR && $rule::name[0].between?(?A, ?Z)
326
+ }?
327
+ // if lexer rule in combined, leave as pred for lexer
328
+ ^(SYNPRED["=>"] block)
329
+ // in real antlr tool, text for SYN_SEMPRED is predname
330
+ -> SYN_SEMPRED
331
+ | -> block
332
+ )
333
+ ;
334
+
335
+ ebnf_suffix
336
+ @init {
337
+ op = @input.look(1)
338
+ }
339
+ : '?' -> OPTIONAL[op]
340
+ | '*' -> CLOSURE[op]
341
+ | '+' -> POSITIVE_CLOSURE[op]
342
+ ;
343
+
344
+
345
+
346
+ // R E W R I T E S Y N T A X
347
+
348
+ rewrite
349
+ @init {
350
+ first_token = @input.look(1)
351
+ }
352
+ : (rew+='->' preds+=SEMPRED predicated+=rewrite_alternative)*
353
+ rew2='->' last=rewrite_alternative
354
+ -> ^($rew $preds $predicated)* ^($rew2 $last)
355
+ |
356
+ ;
357
+
358
+ rewrite_alternative
359
+ options {backtrack=true;}
360
+ : rewrite_template
361
+ | rewrite_tree_alternative
362
+ | /* empty rewrite */ -> ^(ALT["ALT"] EPSILON["EPSILON"] EOA["EOA"])
363
+ ;
364
+
365
+ rewrite_tree_block
366
+ : lp='(' rewrite_tree_alternative ')'
367
+ -> ^(BLOCK[$lp,"BLOCK"] rewrite_tree_alternative EOB[$lp,"EOB"])
368
+ ;
369
+
370
+ rewrite_tree_alternative
371
+ : rewrite_tree_element+ -> ^(ALT["ALT"] rewrite_tree_element+ EOA["EOA"])
372
+ ;
373
+
374
+ rewrite_tree_element
375
+ : rewrite_tree_atom
376
+ | rewrite_tree_atom ebnf_suffix
377
+ -> ^( ebnf_suffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] rewrite_tree_atom EOA["EOA"]) EOB["EOB"]))
378
+ | rewrite_tree
379
+ ( ebnf_suffix
380
+ -> ^(ebnf_suffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] rewrite_tree EOA["EOA"]) EOB["EOB"]))
381
+ | -> rewrite_tree
382
+ )
383
+ | rewrite_tree_ebnf
384
+ ;
385
+
386
+ rewrite_tree_atom
387
+ : CHAR_LITERAL
388
+ | TOKEN_REF ARG_ACTION? -> ^(TOKEN_REF ARG_ACTION?) // for imaginary nodes
389
+ | RULE_REF
390
+ | STRING_LITERAL
391
+ | d='$' id -> LABEL[$d,$id.text] // reference to a label in a rewrite rule
392
+ | ACTION
393
+ ;
394
+
395
+ rewrite_tree_ebnf
396
+ @init {
397
+ first_token = @input.look(1)
398
+ }
399
+ @after {
400
+ $rewrite_tree_ebnf.tree.token.line = first_token.line
401
+ $rewrite_tree_ebnf.tree.token.column = first_token.column
402
+ }
403
+ : rewrite_tree_block ebnf_suffix -> ^(ebnf_suffix rewrite_tree_block)
404
+ ;
405
+
406
+ rewrite_tree
407
+ : '^(' rewrite_tree_atom rewrite_tree_element* ')'
408
+ -> ^(TREE_BEGIN rewrite_tree_atom rewrite_tree_element* )
409
+ ;
410
+
411
+ /** Build a tree for a template rewrite:
412
+ ^(TEMPLATE (ID|ACTION) ^(ARGLIST ^(ARG ID ACTION) ...) )
413
+ where ARGLIST is always there even if no args exist.
414
+ ID can be "template" keyword. If first child is ACTION then it's
415
+ an indirect template ref
416
+
417
+ -> foo(a={...}, b={...})
418
+ -> ({string-e})(a={...}, b={...}) // e evaluates to template name
419
+ -> {%{$ID.text}} // create literal template from string (done in ActionTranslator)
420
+ -> {st-expr} // st-expr evaluates to ST
421
+ */
422
+ rewrite_template
423
+ : // -> template(a={...},...) "..." inline template
424
+ id lp='(' rewrite_template_args ')'
425
+ ( str=DOUBLE_QUOTE_STRING_LITERAL | str=DOUBLE_ANGLE_STRING_LITERAL )
426
+ -> ^(TEMPLATE[$lp,"TEMPLATE"] id rewrite_template_args $str)
427
+
428
+ | // -> foo(a={...}, ...)
429
+ rewrite_template_ref
430
+
431
+ | // -> ({expr})(a={...}, ...)
432
+ rewrite_indirect_template_head
433
+
434
+ | // -> {...}
435
+ ACTION
436
+ ;
437
+
438
+ /** -> foo(a={...}, ...) */
439
+ rewrite_template_ref
440
+ : id lp='(' rewrite_template_args ')'
441
+ -> ^(TEMPLATE[$lp,"TEMPLATE"] id rewrite_template_args)
442
+ ;
443
+
444
+ /** -> ({expr})(a={...}, ...) */
445
+ rewrite_indirect_template_head
446
+ : lp='(' ACTION ')' '(' rewrite_template_args ')'
447
+ -> ^(TEMPLATE[$lp,"TEMPLATE"] ACTION rewrite_template_args)
448
+ ;
449
+
450
+ rewrite_template_args
451
+ : rewrite_template_arg (',' rewrite_template_arg)*
452
+ -> ^(ARGLIST rewrite_template_arg+)
453
+ | -> ARGLIST
454
+ ;
455
+
456
+ rewrite_template_arg
457
+ : id '=' ACTION -> ^(ARG[$id.start] id ACTION)
458
+ ;
459
+
460
+ qid : id ('.' id)* ;
461
+
462
+ id :
463
+ TOKEN_REF -> ID[$TOKEN_REF]
464
+ | RULE_REF -> ID[$RULE_REF]
465
+ ;
466
+
467
+ // L E X I C A L R U L E S
468
+
469
+ SL_COMMENT
470
+ : '//'
471
+ ( ' $ANTLR ' SRC // src directive
472
+ | ~('\r'|'\n')*
473
+ )
474
+ '\r'? '\n' {$channel=HIDDEN;}
475
+ ;
476
+
477
+ ML_COMMENT
478
+ : '/*' {if @input.peek(1) == ?* then $type = DOC_COMMENT else $channel = HIDDEN end } .* '*/'
479
+ ;
480
+
481
+ CHAR_LITERAL
482
+ : '\'' LITERAL_CHAR '\''
483
+ ;
484
+
485
+ STRING_LITERAL
486
+ : '\'' LITERAL_CHAR LITERAL_CHAR* '\''
487
+ ;
488
+
489
+ fragment
490
+ LITERAL_CHAR
491
+ : ESC
492
+ | ~('\''|'\\')
493
+ ;
494
+
495
+ DOUBLE_QUOTE_STRING_LITERAL
496
+ : '"' (ESC | ~('\\'|'"'))* '"'
497
+ ;
498
+
499
+ DOUBLE_ANGLE_STRING_LITERAL
500
+ : '<<' .* '>>'
501
+ ;
502
+
503
+ fragment
504
+ ESC : '\\'
505
+ ( 'n'
506
+ | 'r'
507
+ | 't'
508
+ | 'b'
509
+ | 'f'
510
+ | '"'
511
+ | '\''
512
+ | '\\'
513
+ | '>'
514
+ | 'u' XDIGIT XDIGIT XDIGIT XDIGIT
515
+ | . // unknown, leave as it is
516
+ )
517
+ ;
518
+
519
+ fragment
520
+ XDIGIT :
521
+ '0' .. '9'
522
+ | 'a' .. 'f'
523
+ | 'A' .. 'F'
524
+ ;
525
+
526
+ INT : '0'..'9'+
527
+ ;
528
+
529
+ ARG_ACTION
530
+ : NESTED_ARG_ACTION
531
+ ;
532
+
533
+ fragment
534
+ NESTED_ARG_ACTION :
535
+ '['
536
+ ( options {greedy=false; k=1;}
537
+ : NESTED_ARG_ACTION
538
+ | ACTION_STRING_LITERAL
539
+ | ACTION_CHAR_LITERAL
540
+ | .
541
+ )*
542
+ ']'
543
+ //{setText(getText().substring(1, getText().length()-1));}
544
+ ;
545
+
546
+ ACTION
547
+ : NESTED_ACTION ( '?' { $type = SEMPRED } )?
548
+ ;
549
+
550
+ fragment
551
+ NESTED_ACTION :
552
+ '{'
553
+ ( options {greedy=false; k=2;}
554
+ : NESTED_ACTION
555
+ | SL_COMMENT
556
+ | ML_COMMENT
557
+ | ACTION_STRING_LITERAL
558
+ | ACTION_CHAR_LITERAL
559
+ | ~ '\\'
560
+ | '\\' .
561
+ )*
562
+ '}'
563
+ ;
564
+
565
+ fragment
566
+ ACTION_CHAR_LITERAL
567
+ : '\'' ( ~('\\'|'\'') | '\\' . )* '\''
568
+ ;
569
+
570
+ fragment
571
+ ACTION_STRING_LITERAL
572
+ : '"' ( ~('\\'|'"') | '\\' . )* '"'
573
+ ;
574
+
575
+ fragment
576
+ ACTION_ESC
577
+ : '\\' .
578
+ ;
579
+
580
+ TOKEN_REF
581
+ : 'A'..'Z' ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
582
+ ;
583
+
584
+ RULE_REF
585
+ : 'a'..'z' ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
586
+ ;
587
+
588
+ /** Match the start of an options section. Don't allow normal
589
+ * action processing on the {...} as it's not a action.
590
+ */
591
+ OPTIONS
592
+ : 'options' WS_LOOP '{'
593
+ ;
594
+
595
+ TOKENS
596
+ : 'tokens' WS_LOOP '{'
597
+ ;
598
+
599
+ /** Reset the file and line information; useful when the grammar
600
+ * has been generated so that errors are shown relative to the
601
+ * original file like the old C preprocessor used to do.
602
+ */
603
+ fragment
604
+ SRC : 'src' ' ' file=ACTION_STRING_LITERAL ' ' line=INT
605
+ ;
606
+
607
+ WS : ( ' '
608
+ | '\t'
609
+ | '\r'? '\n'
610
+ )+
611
+ {$channel=HIDDEN}
612
+ ;
613
+
614
+ fragment
615
+ WS_LOOP
616
+ : ( WS
617
+ | SL_COMMENT
618
+ | ML_COMMENT
619
+ )*
620
+ ;
621
+