antlr3 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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