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,57 @@
1
+ #!/usr/bin/ruby
2
+
3
+ unless defined? Call
4
+
5
+ Call = Struct.new(:file, :line, :method)
6
+ class Call
7
+
8
+ def self.parse(call_string)
9
+ parts = call_string.split(':', 3)
10
+ file = parts.shift
11
+ line = parts.shift.to_i
12
+ if parts.empty?
13
+ return Call.new(file, line)
14
+ else
15
+ mstring = parts.shift
16
+ match = mstring.match(/`(.+)'/)
17
+ method = match ? match[1] : nil
18
+ return Call.new(file, line, method)
19
+ end
20
+ end
21
+
22
+ def self.convert_backtrace( trace )
23
+ trace.map { |c| parse c }
24
+ end
25
+
26
+ def irb?
27
+ self.file == '(irb)'
28
+ end
29
+
30
+ def e_switch?
31
+ self.file == '-e'
32
+ end
33
+
34
+ def to_s
35
+ string = '%s:%i' % [file, line]
36
+ method and string << ":in `%s'" % method
37
+ return(string)
38
+ end
39
+
40
+ def inspect
41
+ to_s.inspect
42
+ end
43
+ end
44
+
45
+ module Kernel
46
+ def call_stack(depth = 1)
47
+ Call.convert_backtrace(caller(depth + 1))
48
+ end
49
+ end
50
+
51
+ class Exception
52
+ def backtrace!
53
+ Call.convert_backtrace(backtrace)
54
+ end
55
+ end
56
+
57
+ end # unless defined? Call
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ =begin ::about::
5
+ author: Kyle Yetter <kcy5b@yahoo.com>
6
+ created on: October 11, 2009
7
+ =end
8
+
9
+ module ANTLR3
10
+ module Test
11
+
12
+ require 'rbconfig'
13
+ path_sep = RbConfig::CONFIG['PATH_SEPARATOR']
14
+
15
+
16
+
17
+ exec_path = ENV['PATH'].split(path_sep)
18
+
19
+
20
+
21
+
22
+ end
23
+ end
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ class String
5
+ def /(subpath)
6
+ File.join(self, subpath.to_s)
7
+ end
8
+
9
+ def here_indent(chr = '| ')
10
+ dup.here_indent!(chr)
11
+ end
12
+
13
+ def here_indent!(chr = '| ')
14
+ chr = Regexp.escape(chr)
15
+ exp = Regexp.new("^ *#{chr}")
16
+ self.gsub!(exp,'')
17
+ return self
18
+ end
19
+
20
+ def here_flow(chr = '| ')
21
+ dup.here_flow!(chr)
22
+ end
23
+
24
+ def here_flow!(chr = '| ')
25
+ here_indent!(chr).gsub!(/\n\s+/,' ')
26
+ return(self)
27
+ end
28
+
29
+ # Indent left or right by n spaces.
30
+ # (This used to be called #tab and aliased as #indent.)
31
+ #
32
+ # CREDIT: Gavin Sinclair
33
+ # CREDIT: Trans
34
+
35
+ def indent(n)
36
+ if n >= 0
37
+ gsub(/^/, ' ' * n)
38
+ else
39
+ gsub(/^ {0,#{-n}}/, "")
40
+ end
41
+ end
42
+
43
+ # Outdent just indents a negative number of spaces.
44
+ #
45
+ # CREDIT: Noah Gibbs
46
+
47
+ def outdent(n)
48
+ indent(-n)
49
+ end
50
+
51
+ # Returns the shortest length of leading whitespace for all non-blank lines
52
+ #
53
+ # n = %Q(
54
+ # a = 3
55
+ # b = 4
56
+ # ).level_of_indent #=> 2
57
+ #
58
+ # CREDIT: Kyle Yetter
59
+ def level_of_indent
60
+ self.scan(/^ *(?=\S)/).map { |space| space.length }.min || 0
61
+ end
62
+
63
+ def fixed_indent(n)
64
+ self.outdent(self.level_of_indent).indent(n)
65
+ end
66
+
67
+ # Provides a margin controlled string.
68
+ #
69
+ # x = %Q{
70
+ # | This
71
+ # | is
72
+ # | margin controlled!
73
+ # }.margin
74
+ #
75
+ #
76
+ # NOTE: This may still need a bit of tweaking.
77
+ #
78
+ # CREDIT: Trans
79
+
80
+ def margin(n=0)
81
+ #d = /\A.*\n\s*(.)/.match( self )[1]
82
+ #d = /\A\s*(.)/.match( self)[1] unless d
83
+ d = ((/\A.*\n\s*(.)/.match(self)) ||
84
+ (/\A\s*(.)/.match(self)))[1]
85
+ return '' unless d
86
+ if n == 0
87
+ gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, '')
88
+ else
89
+ gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, ' ' * n)
90
+ end
91
+ end
92
+
93
+ # Expands tabs to +n+ spaces. Non-destructive. If +n+ is 0, then tabs are
94
+ # simply removed. Raises an exception if +n+ is negative.
95
+ #
96
+ # Thanks to GGaramuno for a more efficient algorithm. Very nice.
97
+ #
98
+ # CREDIT: Gavin Sinclair
99
+ # CREDIT: Noah Gibbs
100
+ # CREDIT: GGaramuno
101
+
102
+ def expand_tabs(n=8)
103
+ n = n.to_int
104
+ raise ArgumentError, "n must be >= 0" if n < 0
105
+ return gsub(/\t/, "") if n == 0
106
+ return gsub(/\t/, " ") if n == 1
107
+ str = self.dup
108
+ while
109
+ str.gsub!(/^([^\t\n]*)(\t+)/) { |f|
110
+ val = ( n * $2.size - ($1.size % n) )
111
+ $1 << (' ' * val)
112
+ }
113
+ end
114
+ str
115
+ end
116
+
117
+
118
+ # The reverse of +camelcase+. Makes an underscored of a camelcase string.
119
+ #
120
+ # Changes '::' to '/' to convert namespaces to paths.
121
+ #
122
+ # Examples
123
+ # "SnakeCase".snakecase #=> "snake_case"
124
+ # "Snake-Case".snakecase #=> "snake_case"
125
+ # "SnakeCase::Errors".underscore #=> "snake_case/errors"
126
+
127
+ def snakecase
128
+ gsub(/::/, '/'). # NOT SO SURE ABOUT THIS -T
129
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
130
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
131
+ tr("-", "_").
132
+ downcase
133
+ end
134
+
135
+ end
136
+
137
+
138
+ class Module
139
+ # Returns the module's container module.
140
+ #
141
+ # module Example
142
+ # class Demo
143
+ # end
144
+ # end
145
+ #
146
+ # Example::Demo.modspace #=> Example
147
+ #
148
+ # See also Module#basename.
149
+ #
150
+ # CREDIT: Trans
151
+
152
+ def modspace
153
+ space = name[ 0...(name.rindex( '::' ) || 0)]
154
+ space.empty? ? Object : eval(space)
155
+ end
156
+ end
157
+
158
+ module Kernel
159
+ autoload :Tempfile, 'tempfile'
160
+
161
+ def screen_width(out=STDERR)
162
+ default_width = ENV['COLUMNS'] || 80
163
+ tiocgwinsz = 0x5413
164
+ data = [0, 0, 0, 0].pack("SSSS")
165
+ if out.ioctl(tiocgwinsz, data) >= 0 then
166
+ rows, cols, xpixels, ypixels = data.unpack("SSSS")
167
+ if cols >= 0 then cols else default_width end
168
+ else
169
+ default_width
170
+ end
171
+ rescue Exception => e
172
+ default_width rescue (raise e)
173
+ end
174
+ end
175
+
176
+
177
+ class File
178
+
179
+ # Given some target path string, and an optional reference path
180
+ # (Dir.pwd by default), this method returns a string containing
181
+ # the relative path of the target path from the reference path
182
+ #
183
+ # Examples:
184
+ # File.relative_path('rel/path') # => './rel/path'
185
+ # File.relative_path('/some/abs/path', '/some') # => './abs/path'
186
+ # File.relative_path('/some/file.txt', '/some/abs/path') # => '../../file.txt'
187
+ def self.relative_path(target, reference = Dir.pwd)
188
+ pair = [target, reference].map! do |path|
189
+ File.expand_path(path.to_s).split(File::Separator).tap do |list|
190
+ if list.empty? then list << String.new(File::Separator)
191
+ elsif list.first.empty? then list.first.replace(File::Separator)
192
+ end
193
+ end
194
+ end
195
+
196
+ target_list, reference_list = pair
197
+ while target_list.first == reference_list.first
198
+ target_list.shift
199
+ reference_list.shift or break
200
+ end
201
+
202
+ relative_list = Array.new(reference_list.length, '..')
203
+ relative_list.empty? and relative_list << '.'
204
+ relative_list.concat(target_list).compact!
205
+ return relative_list.join(File::Separator)
206
+ end
207
+
208
+ end
209
+
210
+ class Dir
211
+ defined?(DOTS) or DOTS = %w(. ..).freeze
212
+ def self.children(directory)
213
+ entries = Dir.entries(directory) - DOTS
214
+ entries.map! do |entry|
215
+ File.join(directory, entry)
216
+ end
217
+ end
218
+
219
+ def self.mkpath(path)
220
+ $VERBOSE and $stderr.puts("INFO: Dir.mkpath(%p)" % path)
221
+ test(?d, path) and return(path)
222
+ parent = File.dirname(path)
223
+ test(?d, parent) or mkpath(parent)
224
+ Dir.mkdir(path)
225
+ return(path)
226
+ end
227
+
228
+ end
229
+
230
+ class Array
231
+
232
+ # Pad an array with a given <tt>value</tt> upto a given <tt>length</tt>.
233
+ #
234
+ # [0,1,2].pad(6,"a") #=> [0,1,2,"a","a","a"]
235
+ #
236
+ # If <tt>length</tt> is a negative number padding will be added
237
+ # to the beginning of the array.
238
+ #
239
+ # [0,1,2].pad(-6,"a") #=> ["a","a","a",0,1,2]
240
+ #
241
+ # CREDIT: Richard Laugesen
242
+
243
+ def pad(len, val=nil)
244
+ return dup if self.size >= len.abs
245
+ if len < 0
246
+ Array.new((len+size).abs,val) + self
247
+ else
248
+ self + Array.new(len-size,val)
249
+ end
250
+ end
251
+
252
+ # Like #pad but changes the array in place.
253
+ #
254
+ # a = [0,1,2]
255
+ # a.pad!(6,"x")
256
+ # a #=> [0,1,2,"x","x","x"]
257
+ #
258
+ # CREDIT: Richard Laugesen
259
+
260
+ def pad!(len, val=nil)
261
+ return self if self.size >= len.abs
262
+ if len < 0
263
+ replace Array.new((len+size).abs,val) + self
264
+ else
265
+ concat Array.new(len-size,val)
266
+ end
267
+ end
268
+
269
+ end
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+ module Test
6
+ module Diff
7
+ module_function
8
+
9
+ # trim common head and tail elements of the two lists
10
+ def width
11
+ screen_width - 20
12
+ end
13
+
14
+ def column_width
15
+ width / 2 - 1
16
+ end
17
+
18
+ def segment(list_a, list_b)
19
+ # trim leading common elements
20
+ common_head = 0
21
+ list_a.zip(list_b) do |a, b|
22
+ a == b ? (common_head += 1) : break
23
+ end
24
+ head = list_a[0...common_head]
25
+ list_a = list_a[common_head..-1].reverse!
26
+ list_b = list_b[common_head..-1].reverse!
27
+
28
+
29
+ common_tail = 0
30
+ list_a.zip(list_b) { |a,b| a == b ? (common_tail += 1) : break }
31
+ tail = list_a[0...common_tail].reverse!
32
+ list_a = list_a[common_tail..-1].reverse!
33
+ list_b = list_b[common_tail..-1].reverse!
34
+
35
+ return [head, tail, list_a, list_b]
36
+ end
37
+
38
+ def max(a,b)
39
+ case a <=> b
40
+ when -1 then b
41
+ else a
42
+ end
43
+ end
44
+
45
+ def colorize(text, color)
46
+ lines = text.split("\n")
47
+ escape =
48
+ case color
49
+ when :white then "\e[37m"
50
+ when :magenta then "\e[35m"
51
+ when :yellow then "\e[33m"
52
+ when :green then "\e[32m"
53
+ when :black then "\e[30m"
54
+ when :red then "\e[31m"
55
+ when :cyan then "\e[36m"
56
+ when :blue then "\e[34m"
57
+ end
58
+ lines.map! { |ln| escape + ln << "\e[\0m" }.join("\n")
59
+ end
60
+
61
+ def display_shared(item)
62
+ colorize(pair(item, item), :green)
63
+ end
64
+ def display_addition(item)
65
+ colorize(pair(nil, item), :magenta)
66
+ end
67
+ def display_subtraction(item)
68
+ colorize(pair(item, nil), :red)
69
+ end
70
+ def wrapped_inspect(list)
71
+ width = column_width
72
+ list = list.map { |i| i.inspect }
73
+ list[-1] << ' ]'
74
+
75
+ lines, line, joint = [], '[ ', ''
76
+
77
+ add_line = proc do |l|
78
+ lines << l.ljust(width)
79
+ ' '
80
+ end
81
+
82
+ for item in list
83
+ line << joint
84
+ leftover = width - line.length
85
+ if item.length > leftover
86
+ i = item.rindex(/\s+/, leftover - 1) || leftover
87
+ if
88
+ line = add_line[line << item[0, i]]
89
+ item = item[i..-1]
90
+ else
91
+
92
+ end
93
+ end
94
+ line << item
95
+
96
+ d = item.length + 2
97
+ if line.length + d > width
98
+ line << ','
99
+ lines << line
100
+ line, joint = ' ', ''
101
+ else
102
+ joint = ", "
103
+ end
104
+ end
105
+ lines << line
106
+
107
+ lines.join("\n")
108
+ end
109
+
110
+ def pair(x, y)
111
+ x = x ? wrapped_inspect(x).split("\n") : []
112
+ y = y ? wrapped_inspect(y).split("\n") : []
113
+ line_count = max(x.length, y.length)
114
+ x.pad!(line_count, '')
115
+ y.pad!(line_count, '')
116
+
117
+ x.zip(y).map! { |pair| pair.map! { |i| i.ljust(column_width) }.join(' ') }.join("\n")
118
+ end
119
+
120
+ def compute_lcs(list_a, list_b)
121
+ m, n = list_a.length, list_b.length
122
+ lcs_matrix = Array.new(m + 1) do |row|
123
+ Array.new(n + 1, 0)
124
+ end
125
+ m.times do |i| n.times do |j|
126
+ if list_a[i] == list_b[j] then lcs_matrix[i+1][j+1] = lcs_matrix[i][j] + 1
127
+ else lcs_matrix[i+1][j+1] = max(lcs_matrix[i+1][j], lcs_matrix[i][j+1])
128
+ end
129
+ end end
130
+ return lcs_matrix
131
+ end
132
+
133
+ def partial_diff(out, a, b, lcs, i = a.length, j = b.length)
134
+ if i > 0 and j > 0 and a[i-1] == b[j-1]
135
+ partial_diff(out, a, b, lcs, i-1, j-1)
136
+ out << display_shared(a[i-1])
137
+ else
138
+ if j > 0 and i.zero? || lcs[i][j-1] >= lcs[i-1][j]
139
+ partial_diff(out,a,b,lcs,i,j-1)
140
+ out << display_addition(b[j-1])
141
+ elsif i > 0 and j.zero? || lcs[i][j-1] < lcs[i-1][j]
142
+ partial_diff(out, a,b,lcs,i-1,j)
143
+ out << display_subtraction(a[i-1])
144
+ end
145
+ end
146
+ return out
147
+ end
148
+
149
+ def diff(a, b, options = {})
150
+ head, tail, a, b = segment(a, b)
151
+ lcs = compute_lcs(a,b)
152
+ out = []
153
+ out << %w(Expected Got).map! { |w| w.ljust(column_width) }.join(' ')
154
+ head.each do |item|
155
+ out << display_shared(item)
156
+ end
157
+ partial_diff(out, a, b, lcs)
158
+ tail.each do |item|
159
+ out << display_shared(item)
160
+ end
161
+ out.join("\n")
162
+ end
163
+ end
164
+ end
165
+ end