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,91 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+
6
+ =begin rdoc ANTLR3::Main::InteractiveStringStream
7
+
8
+ A special stream used in the <b>interactive mode</b> of the Main scripts. It
9
+ uses Readline (if available) or standard IO#gets to fetch data on demand.
10
+
11
+ =end
12
+
13
+ class InteractiveStringStream < StringStream
14
+ def initialize(options = {}, &block)
15
+ @data = ''
16
+ @size = @position = @column = @mark_depth = 0
17
+ @line = 1
18
+ @markers = []
19
+ @initialized = @eof = false
20
+ @last_marker = @name = nil
21
+ @readline = block or raise(ArgumentError, "no block was provided")
22
+ @name = options.fetch(:name, '(interactive)')
23
+ end
24
+
25
+ def <<(data)
26
+ tail = data.to_s
27
+ @size += tail.length
28
+ @data << tail
29
+ end
30
+
31
+ def consume
32
+ @position < @size and return(super)
33
+ unless @eof
34
+ readline
35
+ consume
36
+ end
37
+ end
38
+
39
+ def peek(i = 1)
40
+ i.zero? and return 0
41
+ i += 1 if i < 0
42
+ index = @position + i - 1
43
+ index < 0 and return 0
44
+
45
+ if index < @size
46
+ char = @data[index]
47
+ elsif readline
48
+ peek(i)
49
+ else EOF
50
+ end
51
+ end
52
+
53
+ def look(i = 1)
54
+ peek(i).chr rescue EOF
55
+ end
56
+
57
+ alias >> peek
58
+
59
+ def substring(start, stop)
60
+ fill_through(stop)
61
+ @data[start..stop]
62
+ end
63
+
64
+ private
65
+ def fill_through(position)
66
+ @eof and return
67
+ if position < 0 then fill_out
68
+ else readline until (@size > position or @eof)
69
+ end
70
+ end
71
+
72
+ def readline
73
+ @initialized = true
74
+ unless @eof
75
+ if line = @readline.call
76
+ self << line.to_s
77
+ return true
78
+ else
79
+ @eof = true
80
+ return false
81
+ end
82
+ end
83
+ end
84
+
85
+ def fill_out
86
+ @eof and return
87
+ readline until @eof
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1,412 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ =begin LICENSE
5
+
6
+ [The "BSD licence"]
7
+ Copyright (c) 2009 Kyle Yetter
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions
12
+ are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in the
18
+ documentation and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ =end
34
+
35
+ module ANTLR3
36
+
37
+ =begin rdoc ANTLR3::TokenRewriteStream
38
+
39
+ TokenRewriteStream is a specialized form of CommonTokenStream that provides simple stream editing functionality. By creating <i>rewrite programs</i>, new text output can be created based upon the tokens in the stream. The basic token stream itself is preserved, and text output is rendered on demand using the #to_s method.
40
+
41
+ =end
42
+
43
+ class TokenRewriteStream < CommonTokenStream
44
+
45
+ =begin rdoc ANTLR3::TokenRewriteStream::RewriteOperation
46
+
47
+ RewiteOperation objects represent some particular editing command that should
48
+ be executed by a token rewrite stream at some time in future when the stream is
49
+ rendering a rewritten stream.
50
+
51
+ To perform token stream rewrites safely and efficiently, the rewrites are
52
+ executed lazily (that is, only when the rewritten text is explicitly requested).
53
+ Rewrite streams implement lazy rewriting by storing the parameters of
54
+ edit-inducing methods like +delete+ and +insert+ as RewriteOperation objects in
55
+ a rewrite program list.
56
+
57
+ The three subclasses of RewriteOperation, InsertBefore, Delete, and Replace,
58
+ define specific implementations of stream edits.
59
+
60
+ =end
61
+
62
+ unless defined?(RewriteOperation)
63
+ RewriteOperation = Struct.new(:stream, :location, :text)
64
+ end
65
+
66
+ class RewriteOperation
67
+ extend ClassMacros
68
+ @operation_name = ''
69
+ class << self
70
+ # TODO: document
71
+ attr_reader :operation_name
72
+ end
73
+ abstract :execute
74
+
75
+ # TODO: document
76
+ def name
77
+ self.class.operation_name
78
+ end
79
+
80
+ # TODO: document
81
+ def inspect
82
+ return "(%s @ %p : %p)" % [name, location, text]
83
+ end
84
+ end
85
+
86
+ =begin rdoc ANTLR3::TokenRewriteStream::InsertBefore
87
+
88
+ Represents rewrite operation:
89
+
90
+ add string <tt>op.text</tt> to the rewrite output immediately before adding the
91
+ text content of the token at index <tt>op.index</tt>
92
+
93
+ =end
94
+
95
+ class InsertBefore < RewriteOperation
96
+ @operation_name = 'insert-before'.freeze
97
+
98
+ alias index location
99
+ alias index= location=
100
+
101
+ def execute(buffer)
102
+ buffer << text
103
+ token = stream[location]
104
+ buffer << token.text if token
105
+ return location + 1
106
+ end
107
+ end
108
+
109
+ =begin rdoc ANTLR3::TokenRewriteStream::Replace
110
+
111
+ Represents rewrite operation:
112
+
113
+ add text <tt>op.text</tt> to the rewrite buffer in lieu of the text of tokens
114
+ indexed within the range <tt>op.index .. op.last_index</tt>
115
+
116
+ =end
117
+
118
+ class Replace < RewriteOperation
119
+ @operation_name = 'replace'.freeze
120
+ def initialize(stream, location, text)
121
+ super(stream, nil, text)
122
+ self.location = location
123
+ end
124
+
125
+ def location=(val)
126
+ case val
127
+ when Range then super(val)
128
+ else
129
+ val = val.to_i
130
+ super(val..val)
131
+ end
132
+ end
133
+
134
+ def execute(buffer)
135
+ buffer << text unless text.nil?
136
+ return(location.end + 1)
137
+ end
138
+
139
+ def index
140
+ location.first
141
+ end
142
+
143
+ end
144
+
145
+ =begin rdoc ANTLR3::TokenRewriteStream::Delete
146
+
147
+ Represents rewrite operation:
148
+
149
+ skip over the tokens indexed within the range <tt>op.index .. op.last_index</tt>
150
+ and do not add any text to the rewrite buffer
151
+
152
+ =end
153
+
154
+ class Delete < Replace
155
+ @operation_name = 'delete'.freeze
156
+ def initialize(stream, location)
157
+ super(stream, location, nil)
158
+ end
159
+ end
160
+
161
+ class RewriteProgram
162
+ def initialize(stream, name = nil)
163
+ @stream = stream
164
+ @name = name
165
+ @operations = []
166
+ end
167
+
168
+ def replace(*range_arguments)
169
+ range, text = cast_range(range_arguments, 1)
170
+
171
+ op = Replace.new(@stream, range, text)
172
+ @operations << op
173
+ return op
174
+ end
175
+
176
+ def insert_before(index, text)
177
+ index = index.to_i
178
+ index < 0 and index += @stream.length
179
+ op = InsertBefore.new(@stream, index, text)
180
+ @operations << op
181
+ return op
182
+ end
183
+
184
+ def insert_after(index, text)
185
+ index = index.to_i
186
+ index < 0 and index += @stream.length
187
+ op = InsertBefore.new(@stream, index + 1, text)
188
+ @operations << op
189
+ return op
190
+ end
191
+
192
+ def delete(*range_arguments)
193
+ range, = cast_range(range_arguments)
194
+ op = Delete.new(@stream, range)
195
+ @operations << op
196
+ return op
197
+ end
198
+
199
+ def reduce
200
+ operations = @operations.reverse
201
+ reduced = []
202
+
203
+ until operations.empty?
204
+ operation = operations.shift
205
+ location = operation.location
206
+
207
+ case operation
208
+ when Replace
209
+ operations.delete_if do |prior_operation|
210
+ prior_location = prior_operation.location
211
+
212
+ case prior_operation
213
+ when InsertBefore
214
+ location.include?(prior_location)
215
+ when Replace
216
+ if location.covers?(prior_location)
217
+ true
218
+ elsif location.overlaps?(prior_location)
219
+ conflict!(operation, prior_operation)
220
+ end
221
+ end
222
+ end
223
+ when InsertBefore
224
+ operations.delete_if do |prior_operation|
225
+ prior_location = prior_operation.location
226
+
227
+ case prior_operation
228
+ when InsertBefore
229
+ if prior_location == location
230
+ operation.text += prior_operation.text
231
+ true
232
+ end
233
+ when Replace
234
+ if location == prior_location.first
235
+ prior_operation.text = operation.text << prior_operation.text.to_s
236
+ operation = nil
237
+ break(false)
238
+ elsif prior_location.include?(location)
239
+ conflict!(operation, prior_operation)
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ reduced.unshift(operation) if operation
246
+ end
247
+
248
+ @operations.replace(reduced)
249
+
250
+ @operations.inject({}) do |map, operation|
251
+ other_operaiton = map[operation.index] and
252
+ ANTLR3.bug!( Util.tidy(<<-END) % [self.class, operation, other_operaiton] )
253
+ | %s#reduce! should have left only one operation per index,
254
+ | but %p conflicts with %p
255
+ END
256
+ map[operation.index] = operation
257
+ map
258
+ end
259
+ end
260
+
261
+ def execute(*range_arguments)
262
+ if range_arguments.empty?
263
+ range = 0 ... @stream.length
264
+ else
265
+ range, = cast_range(range_arguments)
266
+ end
267
+
268
+ output = ''
269
+
270
+ tokens = @stream.tokens
271
+
272
+ operations = reduce
273
+
274
+ cursor = range.first
275
+ while range.include?(cursor)
276
+ if operation = operations.delete(cursor)
277
+ cursor = operation.execute(output)
278
+ else
279
+ token = tokens[cursor]
280
+ output << token.text if token
281
+ cursor += 1
282
+ end
283
+ end
284
+ if operation = operations.delete(cursor) and
285
+ operation.is_a?(InsertBefore)
286
+ # catch edge 'insert-after' operations
287
+ operation.execute(output)
288
+ end
289
+
290
+ return output
291
+ end
292
+
293
+ def clear
294
+ @operations.clear
295
+ end
296
+
297
+ def undo(number_of_operations = 1)
298
+ @operations.pop(number_of_operations)
299
+ end
300
+
301
+ def conflict!(current, previous)
302
+ message = 'operation %p overlaps with previous operation %p' % [current, previous]
303
+ raise(RangeError, message, caller)
304
+ end
305
+
306
+ def cast_range(args, extra = 0)
307
+ single, pair = extra + 1, extra + 2
308
+ case check_arguments(args, single, pair)
309
+ when single
310
+ loc = args.shift
311
+
312
+ if loc.is_a?(Range)
313
+ first, last = loc.first.to_i, loc.last.to_i
314
+ loc.exlude_end? and last -= 1
315
+ return cast_range(args.unshift(first, last), extra)
316
+ else
317
+ loc = loc.to_i
318
+ return cast_range(args.unshift(loc, loc), extra)
319
+ end
320
+ when pair
321
+ first, last = args.shift(2).map! { |arg| arg.to_i }
322
+ if first < 0 and last < 0
323
+ first += @stream.length
324
+ last += @stream.length
325
+ else
326
+ last < 0 and last += @stream.length
327
+ first = first.at_least(0)
328
+ end
329
+ return(args.unshift(first .. last))
330
+ end
331
+ end
332
+
333
+ def check_arguments(args, min, max)
334
+ n = args.length
335
+ if n < min
336
+ raise ArgumentError,
337
+ "wrong number of arguments (#{args.length} for #{min})",
338
+ caller
339
+ elsif n > max
340
+ raise ArgumentError,
341
+ "wrong number of arguments (#{args.length} for #{max})",
342
+ caller
343
+ else return n
344
+ end
345
+ end
346
+
347
+ private :conflict!, :cast_range, :check_arguments
348
+ end
349
+
350
+ attr_reader :programs
351
+
352
+ def initialize(token_source, options = {})
353
+ super(token_source, options)
354
+
355
+ @programs = Hash.new do |programs, name|
356
+ if name.is_a?(String)
357
+ programs[name] = RewriteProgram.new(self, name)
358
+ else programs[name.to_s]
359
+ end
360
+ end
361
+
362
+ @last_rewrite_token_indexes = {}
363
+ end
364
+
365
+ def rewrite(program_name = 'default', range = nil)
366
+ program = @programs[program_name]
367
+ if block_given?
368
+ yield(program)
369
+ program.execute(range)
370
+ else program
371
+ end
372
+ end
373
+
374
+ def program(name = 'default')
375
+ return @programs[name]
376
+ end
377
+
378
+ def delete_program(name = 'default')
379
+ @programs.delete(name)
380
+ end
381
+
382
+ def original_string(start = 0, finish = size - 1)
383
+ @position == -1 and fill_buffer
384
+
385
+ return(self[start..finish].map { |t| t.text }.join(''))
386
+ end
387
+
388
+ def insert_before(*args)
389
+ @programs['default'].insert_before(*args)
390
+ end
391
+
392
+ def insert_after(*args)
393
+ @programs['default'].insert_after(*args)
394
+ end
395
+
396
+ def replace(*args)
397
+ @programs['default'].replace(*args)
398
+ end
399
+
400
+ def delete(*args)
401
+ @programs['default'].delete(*args)
402
+ end
403
+
404
+ def render(*arguments)
405
+ case arguments.first
406
+ when String, Symbol then name = arguments.shift.to_s
407
+ else name = 'default'
408
+ end
409
+ @programs[name].execute(*arguments)
410
+ end
411
+ end
412
+ end