ruby_parser 3.13.1 → 3.21.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.autotest +18 -29
- data/History.rdoc +312 -0
- data/Manifest.txt +16 -15
- data/README.rdoc +13 -9
- data/Rakefile +237 -106
- data/bin/ruby_parse +3 -1
- data/bin/ruby_parse_extract_error +9 -4
- data/compare/normalize.rb +54 -6
- data/debugging.md +172 -0
- data/gauntlet.md +107 -0
- data/lib/rp_extensions.rb +15 -36
- data/lib/rp_stringscanner.rb +20 -51
- data/lib/ruby_lexer.rb +515 -812
- data/lib/ruby_lexer.rex +33 -27
- data/lib/ruby_lexer.rex.rb +64 -31
- data/lib/ruby_lexer_strings.rb +638 -0
- data/lib/ruby_parser.rb +46 -36
- data/lib/{ruby_parser.yy → ruby_parser2.yy} +1400 -488
- data/lib/ruby_parser20.rb +10953 -0
- data/lib/ruby_parser21.rb +10978 -0
- data/lib/ruby_parser22.rb +11119 -0
- data/lib/ruby_parser23.rb +11160 -0
- data/lib/ruby_parser24.rb +11209 -0
- data/lib/ruby_parser25.rb +11209 -0
- data/lib/ruby_parser26.rb +11231 -0
- data/lib/ruby_parser27.rb +12960 -0
- data/lib/{ruby26_parser.y → ruby_parser3.yy} +1652 -521
- data/lib/ruby_parser30.rb +13292 -0
- data/lib/ruby_parser31.rb +13625 -0
- data/lib/ruby_parser32.rb +13577 -0
- data/lib/ruby_parser33.rb +13577 -0
- data/lib/ruby_parser_extras.rb +988 -474
- data/test/test_ruby_lexer.rb +1339 -1155
- data/test/test_ruby_parser.rb +4255 -2103
- data/test/test_ruby_parser_extras.rb +39 -4
- data/tools/munge.rb +52 -13
- data/tools/ripper.rb +24 -6
- data.tar.gz.sig +0 -0
- metadata +73 -56
- metadata.gz.sig +0 -0
- data/lib/ruby20_parser.rb +0 -6869
- data/lib/ruby20_parser.y +0 -2431
- data/lib/ruby21_parser.rb +0 -6944
- data/lib/ruby21_parser.y +0 -2449
- data/lib/ruby22_parser.rb +0 -6968
- data/lib/ruby22_parser.y +0 -2458
- data/lib/ruby23_parser.rb +0 -6987
- data/lib/ruby23_parser.y +0 -2460
- data/lib/ruby24_parser.rb +0 -6994
- data/lib/ruby24_parser.y +0 -2466
- data/lib/ruby25_parser.rb +0 -6994
- data/lib/ruby25_parser.y +0 -2466
- data/lib/ruby26_parser.rb +0 -7012
data/Rakefile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
|
3
|
-
require "rubygems"
|
4
3
|
require "hoe"
|
5
4
|
|
6
5
|
Hoe.plugin :seattlerb
|
@@ -8,29 +7,41 @@ Hoe.plugin :racc
|
|
8
7
|
Hoe.plugin :isolate
|
9
8
|
Hoe.plugin :rdoc
|
10
9
|
|
10
|
+
Hoe.add_include_dirs "lib"
|
11
11
|
Hoe.add_include_dirs "../../sexp_processor/dev/lib"
|
12
12
|
Hoe.add_include_dirs "../../minitest/dev/lib"
|
13
13
|
Hoe.add_include_dirs "../../oedipus_lex/dev/lib"
|
14
|
+
Hoe.add_include_dirs "../../ruby2ruby/dev/lib"
|
14
15
|
|
15
|
-
V2 = %w[20 21 22 23 24 25 26]
|
16
|
-
|
16
|
+
V2 = %w[20 21 22 23 24 25 26 27]
|
17
|
+
V3 = %w[30 31 32 33]
|
18
|
+
|
19
|
+
VERS = V2 + V3
|
20
|
+
|
21
|
+
ENV["FAST"] = VERS.last if ENV["FAST"] && !VERS.include?(ENV["FAST"])
|
22
|
+
VERS.replace [ENV["FAST"]] if ENV["FAST"]
|
23
|
+
|
24
|
+
racc_flags = nil
|
17
25
|
|
18
26
|
Hoe.spec "ruby_parser" do
|
19
27
|
developer "Ryan Davis", "ryand-ruby@zenspider.com"
|
20
28
|
|
21
29
|
license "MIT"
|
22
30
|
|
23
|
-
dependency "sexp_processor", "~>
|
24
|
-
dependency "
|
25
|
-
dependency "
|
31
|
+
dependency "sexp_processor", "~> 4.16"
|
32
|
+
dependency "racc", "~> 1.5"
|
33
|
+
dependency "rake", [">= 10", "< 15"], :developer
|
34
|
+
dependency "oedipus_lex", "~> 2.6", :developer
|
35
|
+
|
36
|
+
require_ruby_version [">= 2.6", "< 4"]
|
26
37
|
|
27
38
|
if plugin? :perforce then # generated files
|
28
|
-
|
29
|
-
self.perforce_ignore << "lib/
|
39
|
+
VERS.each do |n|
|
40
|
+
self.perforce_ignore << "lib/ruby_parser#{n}.rb"
|
30
41
|
end
|
31
42
|
|
32
|
-
|
33
|
-
self.perforce_ignore << "lib/
|
43
|
+
VERS.each do |n|
|
44
|
+
self.perforce_ignore << "lib/ruby_parser#{n}.y"
|
34
45
|
end
|
35
46
|
|
36
47
|
self.perforce_ignore << "lib/ruby_lexer.rex.rb"
|
@@ -39,27 +50,68 @@ Hoe.spec "ruby_parser" do
|
|
39
50
|
if plugin?(:racc)
|
40
51
|
self.racc_flags << " -t" if ENV["DEBUG"]
|
41
52
|
self.racc_flags << " --superclass RubyParser::Parser"
|
42
|
-
|
53
|
+
racc_flags = self.racc_flags
|
43
54
|
end
|
44
55
|
end
|
45
56
|
|
46
|
-
|
47
|
-
file
|
48
|
-
|
49
|
-
|
57
|
+
def maybe_add_to_top path, string
|
58
|
+
file = File.read path
|
59
|
+
|
60
|
+
return if file.start_with? string
|
61
|
+
|
62
|
+
warn "Altering top of #{path}"
|
63
|
+
tmp_path = "#{path}.tmp"
|
64
|
+
File.open(tmp_path, "w") do |f|
|
65
|
+
f.puts string
|
66
|
+
f.puts
|
67
|
+
|
68
|
+
f.write file
|
69
|
+
# TODO: make this deal with encoding comments properly?
|
50
70
|
end
|
71
|
+
File.rename tmp_path, path
|
72
|
+
end
|
73
|
+
|
74
|
+
def unifdef?
|
75
|
+
@unifdef ||= system("which unifdef") or abort <<~EOM
|
76
|
+
unifdef not found!
|
77
|
+
|
78
|
+
Please install 'unifdef' package on your system or `rake generate` on a mac.
|
79
|
+
EOM
|
80
|
+
end
|
81
|
+
|
82
|
+
def racc?
|
83
|
+
@racc ||= system("which racc") or abort <<~EOM
|
84
|
+
racc not found! `gem install racc`
|
85
|
+
EOM
|
86
|
+
end
|
51
87
|
|
52
|
-
|
88
|
+
generate_parser = proc do |t|
|
89
|
+
unifdef?
|
90
|
+
racc?
|
91
|
+
n = t.name[/\d+/]
|
92
|
+
sh "unifdef -tk -DV=%s %s | racc %s /dev/stdin -o %s" % [n, t.source, racc_flags, t.name]
|
93
|
+
maybe_add_to_top t.name, "# frozen_string_literal: true"
|
94
|
+
end
|
95
|
+
|
96
|
+
V2.each do |n|
|
97
|
+
file "lib/ruby_parser#{n}.rb" => "lib/ruby_parser2.yy", &generate_parser
|
98
|
+
end
|
99
|
+
|
100
|
+
V3.each do |n|
|
101
|
+
file "lib/ruby_parser#{n}.rb" => "lib/ruby_parser3.yy", &generate_parser
|
53
102
|
end
|
54
103
|
|
55
104
|
file "lib/ruby_lexer.rex.rb" => "lib/ruby_lexer.rex"
|
56
105
|
|
106
|
+
task :generate => [:lexer, :parser]
|
107
|
+
|
57
108
|
task :clean do
|
58
109
|
rm_rf(Dir["**/*~"] +
|
59
110
|
Dir["diff.diff"] + # not all diffs. bit me too many times
|
60
111
|
Dir["coverage.info"] +
|
61
112
|
Dir["coverage"] +
|
62
|
-
Dir["lib/
|
113
|
+
Dir["lib/ruby_parser2*.y"] +
|
114
|
+
Dir["lib/ruby_parser3*.y"] +
|
63
115
|
Dir["lib/*.output"])
|
64
116
|
end
|
65
117
|
|
@@ -73,127 +125,187 @@ task :huh? do
|
|
73
125
|
puts "ruby #{Hoe::RUBY_FLAGS} bin/ruby_parse -q -g ..."
|
74
126
|
end
|
75
127
|
|
76
|
-
task :irb => [:isolate] do
|
77
|
-
sh "GEM_HOME=#{Gem.path.first} irb -rubygems -Ilib -rruby_parser;"
|
78
|
-
end
|
79
|
-
|
80
128
|
def (task(:phony)).timestamp
|
81
129
|
Time.at 0
|
82
130
|
end
|
83
131
|
|
84
132
|
task :isolate => :phony
|
85
133
|
|
86
|
-
def
|
87
|
-
Dir.chdir "compare" do
|
88
|
-
yield
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def dl v
|
134
|
+
def dl v, f
|
93
135
|
dir = v[/^\d+\.\d+/]
|
94
|
-
url = "https://cache.ruby-lang.org/pub/ruby/#{dir}/ruby-#{v}.tar.
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
136
|
+
url = "https://cache.ruby-lang.org/pub/ruby/#{dir}/ruby-#{v}.tar.xz"
|
137
|
+
|
138
|
+
warn "Downloading ruby #{v}"
|
139
|
+
system "curl -s -o #{f} #{url}"
|
99
140
|
end
|
100
141
|
|
142
|
+
task :parser => :isolate
|
143
|
+
|
144
|
+
multitask :compare_build
|
145
|
+
task :compare_build => :generate
|
146
|
+
task :compare => :compare_build
|
147
|
+
|
101
148
|
def ruby_parse version
|
102
149
|
v = version[/^\d+\.\d+/].delete "."
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
rp_out = "lib/
|
110
|
-
|
111
|
-
rp_y_rb = "lib/ruby#{v}_parser.rb"
|
112
|
-
|
113
|
-
c_diff = "compare/#{diff}"
|
114
|
-
c_rp_txt = "compare/#{rp_txt}"
|
115
|
-
c_mri_txt = "compare/#{mri_txt}"
|
116
|
-
c_parse_y = "compare/#{parse_y}"
|
117
|
-
c_tarball = "compare/#{tarball}"
|
150
|
+
diff = "compare/diff#{v}.diff"
|
151
|
+
rp_txt = "compare/rp#{v}.txt"
|
152
|
+
mri_txt = "compare/mri#{v}.txt"
|
153
|
+
parse_y = "compare/parse#{v}.y"
|
154
|
+
tarball = "compare/ruby-#{version}.tar.xz"
|
155
|
+
ruby_dir = "compare/ruby-#{version}"
|
156
|
+
rp_out = "lib/ruby_parser#{v}.output"
|
157
|
+
rp_y_rb = "lib/ruby_parser#{v}.rb"
|
118
158
|
normalize = "compare/normalize.rb"
|
119
159
|
|
120
|
-
file
|
121
|
-
|
122
|
-
dl version
|
123
|
-
end
|
160
|
+
file tarball do
|
161
|
+
dl version, tarball
|
124
162
|
end
|
125
163
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
164
|
+
desc "fetch all tarballs"
|
165
|
+
task :fetch => tarball
|
166
|
+
|
167
|
+
file parse_y => tarball do
|
168
|
+
extract_glob = case
|
169
|
+
when version > "3.3" then
|
170
|
+
"{id.h,parse.y,tool/{id2token.rb,lrama},defs/id.def}"
|
171
|
+
when version > "3.2" then
|
172
|
+
"{id.h,parse.y,tool/id2token.rb,defs/id.def}"
|
173
|
+
when version > "2.7" then
|
174
|
+
"{id.h,parse.y,tool/{id2token.rb,lib/vpath.rb}}"
|
175
|
+
else
|
176
|
+
"{id.h,parse.y,tool/{id2token.rb,vpath.rb}}"
|
177
|
+
end
|
178
|
+
system "tar xf #{tarball} -C compare #{File.basename ruby_dir}/#{extract_glob}"
|
179
|
+
|
180
|
+
# Debugging a new parse build system:
|
181
|
+
#
|
182
|
+
# Unpack the ruby tarball in question, configure, and run the following:
|
183
|
+
#
|
184
|
+
# % touch parse.y; make -n parse.c
|
185
|
+
# ...
|
186
|
+
# echo generating parse.c
|
187
|
+
# /Users/ryan/.rubies.current/bin/ruby --disable=gems ./tool/id2token.rb parse.y | \
|
188
|
+
# ruby ./tool/lrama/exe/lrama -oparse.c -Hparse.h - parse.y
|
189
|
+
#
|
190
|
+
# Then integrate these commands into the mess below:
|
191
|
+
|
192
|
+
d = ruby_dir
|
193
|
+
cmd = if version > "3.2" then
|
194
|
+
"ruby #{d}/tool/id2token.rb #{d}/parse.y | expand > #{parse_y}"
|
195
|
+
else
|
196
|
+
"ruby #{d}/tool/id2token.rb --path-separator=.:./ #{d}/id.h #{d}/parse.y | expand | ruby -pe 'gsub(/^%pure-parser/, \"%define api.pure\")' > #{parse_y}"
|
197
|
+
end
|
198
|
+
|
199
|
+
sh cmd
|
200
|
+
|
201
|
+
if File.exist? "#{d}/tool/lrama" then # UGH: this is dumb
|
202
|
+
rm_rf "compare/lrama"
|
203
|
+
sh "mv #{d}/tool/lrama compare"
|
137
204
|
end
|
205
|
+
sh "rm -rf #{d}"
|
138
206
|
end
|
139
207
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
208
|
+
bison = Dir["/opt/homebrew/opt/bison/bin/bison",
|
209
|
+
"/usr/local/opt/bison/bin/bison",
|
210
|
+
`which bison`.chomp,
|
211
|
+
].first
|
212
|
+
|
213
|
+
file mri_txt => [parse_y, normalize] do
|
214
|
+
if version > "3.3" then
|
215
|
+
sh "./compare/lrama/exe/lrama -r all -ocompare/parse#{v}.tab.c #{parse_y}"
|
216
|
+
else
|
217
|
+
sh "#{bison} -r all #{parse_y}"
|
218
|
+
mv Dir["parse#{v}.*"], "compare"
|
145
219
|
end
|
220
|
+
|
221
|
+
sh "#{normalize} compare/parse#{v}.output > #{mri_txt}"
|
222
|
+
rm ["compare/parse#{v}.output", "compare/parse#{v}.tab.c"]
|
146
223
|
end
|
147
224
|
|
148
225
|
file rp_out => rp_y_rb
|
149
226
|
|
150
|
-
file
|
151
|
-
|
152
|
-
sh "./normalize.rb ../#{rp_out} > #{rp_txt}"
|
153
|
-
end
|
227
|
+
file rp_txt => [rp_out, normalize] do
|
228
|
+
sh "#{normalize} #{rp_out} > #{rp_txt}"
|
154
229
|
end
|
155
230
|
|
156
231
|
compare = "compare#{v}"
|
232
|
+
compare_build = "compare_build#{v}"
|
157
233
|
|
158
234
|
desc "Compare all grammars to MRI"
|
159
235
|
task :compare => compare
|
236
|
+
task :compare_build => compare_build
|
160
237
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
238
|
+
task compare_build => diff
|
239
|
+
|
240
|
+
file diff => [mri_txt, rp_txt] do
|
241
|
+
sh "diff -du #{mri_txt} #{rp_txt} > #{diff}; true"
|
165
242
|
end
|
166
243
|
|
167
244
|
desc "Compare #{v} grammar to MRI #{version}"
|
168
|
-
task compare =>
|
169
|
-
|
170
|
-
system "wc -l #{diff}"
|
171
|
-
end
|
245
|
+
task compare => diff do
|
246
|
+
system "wc -l #{diff}"
|
172
247
|
end
|
173
248
|
|
174
249
|
task :clean do
|
175
|
-
rm_f Dir[
|
250
|
+
rm_f Dir[mri_txt, rp_txt]
|
176
251
|
end
|
177
252
|
|
178
253
|
task :realclean do
|
179
|
-
rm_f Dir[
|
254
|
+
rm_f Dir[parse_y, tarball]
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
task :versions do
|
259
|
+
require "open-uri"
|
260
|
+
require "net/http" # avoid require issues in threads
|
261
|
+
require "net/https"
|
262
|
+
|
263
|
+
versions = VERS.map { |s| s.split(//).join "." }
|
264
|
+
|
265
|
+
base_url = "https://cache.ruby-lang.org/pub/ruby"
|
266
|
+
|
267
|
+
class Array
|
268
|
+
def human_sort
|
269
|
+
sort_by { |item| item.to_s.split(/(\d+)/).map { |e| [e.to_i, e] } }
|
270
|
+
end
|
180
271
|
end
|
272
|
+
|
273
|
+
versions = versions.map { |ver|
|
274
|
+
Thread.new {
|
275
|
+
URI
|
276
|
+
.parse("#{base_url}/#{ver}/")
|
277
|
+
.read
|
278
|
+
.scan(/ruby-\d+\.\d+\.\d+[-\w.]*?.tar.gz/)
|
279
|
+
.reject { |s| s =~ /-(?:rc|preview)\d/ }
|
280
|
+
.human_sort
|
281
|
+
.last
|
282
|
+
.delete_prefix("ruby-")
|
283
|
+
.delete_suffix ".tar.gz"
|
284
|
+
}
|
285
|
+
}.map(&:value).sort
|
286
|
+
|
287
|
+
puts versions.map { |v| "ruby_parse %p" % [v] }
|
181
288
|
end
|
182
289
|
|
183
290
|
ruby_parse "2.0.0-p648"
|
184
|
-
ruby_parse "2.1.
|
185
|
-
ruby_parse "2.2.
|
291
|
+
ruby_parse "2.1.10"
|
292
|
+
ruby_parse "2.2.10"
|
186
293
|
ruby_parse "2.3.8"
|
187
|
-
ruby_parse "2.4.
|
188
|
-
ruby_parse "2.5.
|
189
|
-
ruby_parse "2.6.
|
294
|
+
ruby_parse "2.4.10"
|
295
|
+
ruby_parse "2.5.9"
|
296
|
+
ruby_parse "2.6.10"
|
297
|
+
ruby_parse "2.7.8"
|
298
|
+
ruby_parse "3.0.6"
|
299
|
+
ruby_parse "3.1.4"
|
300
|
+
ruby_parse "3.2.2"
|
301
|
+
ruby_parse "3.3.0"
|
190
302
|
|
191
303
|
task :debug => :isolate do
|
192
|
-
ENV["V"] ||=
|
304
|
+
ENV["V"] ||= VERS.last
|
193
305
|
Rake.application[:parser].invoke # this way we can have DEBUG set
|
194
306
|
Rake.application[:lexer].invoke # this way we can have DEBUG set
|
195
307
|
|
196
|
-
|
308
|
+
$:.unshift "lib"
|
197
309
|
require "ruby_parser"
|
198
310
|
require "pp"
|
199
311
|
|
@@ -204,19 +316,21 @@ task :debug => :isolate do
|
|
204
316
|
time = (ENV["RP_TIMEOUT"] || 10).to_i
|
205
317
|
|
206
318
|
n = ENV["BUG"]
|
207
|
-
file = (n && "bug#{n}.rb") || ENV["F"] || ENV["FILE"]
|
319
|
+
file = (n && "bug#{n}.rb") || ENV["F"] || ENV["FILE"] || "debug.rb"
|
320
|
+
ruby = ENV["R"] || ENV["RUBY"]
|
321
|
+
|
322
|
+
if ruby then
|
323
|
+
file = "env"
|
324
|
+
else
|
325
|
+
ruby = File.read file
|
326
|
+
end
|
208
327
|
|
209
|
-
ruby = if file then
|
210
|
-
File.read(file)
|
211
|
-
else
|
212
|
-
file = "env"
|
213
|
-
ENV["R"] || ENV["RUBY"]
|
214
|
-
end
|
215
328
|
|
216
329
|
begin
|
217
330
|
pp parser.process(ruby, file, time)
|
218
|
-
rescue Racc::ParseError => e
|
331
|
+
rescue ArgumentError, Racc::ParseError => e
|
219
332
|
p e
|
333
|
+
puts e.backtrace.join "\n "
|
220
334
|
ss = parser.lexer.ss
|
221
335
|
src = ss.string
|
222
336
|
lines = src[0..ss.pos].split(/\n/)
|
@@ -225,18 +339,26 @@ task :debug => :isolate do
|
|
225
339
|
end
|
226
340
|
|
227
341
|
task :debug3 do
|
228
|
-
file = ENV["F"]
|
229
|
-
|
342
|
+
file = ENV["F"] || "debug.rb"
|
343
|
+
version = ENV["V"] || ""
|
344
|
+
verbose = ENV["VERBOSE"] ? "-v" : ""
|
230
345
|
munge = "./tools/munge.rb #{verbose}"
|
231
346
|
|
232
347
|
abort "Need a file to parse, via: F=path.rb" unless file
|
233
348
|
|
234
349
|
ENV.delete "V"
|
235
350
|
|
236
|
-
|
237
|
-
|
238
|
-
sh "
|
239
|
-
sh "
|
351
|
+
ruby = "ruby#{version}"
|
352
|
+
|
353
|
+
sh "#{ruby} -v"
|
354
|
+
sh "#{ruby} -y #{file} 2>&1 | #{munge} > tmp/ruby"
|
355
|
+
sh "#{ruby} ./tools/ripper.rb -d #{file} | #{munge} > tmp/rip"
|
356
|
+
sh "rake debug F=#{file} DEBUG=1 2>&1 | #{munge} > tmp/rp"
|
357
|
+
sh "diff -U 999 -d tmp/{ruby,rp}"
|
358
|
+
end
|
359
|
+
|
360
|
+
task :cmp do
|
361
|
+
sh %(emacsclient --eval '(ediff-files "tmp/ruby" "tmp/rp")')
|
240
362
|
end
|
241
363
|
|
242
364
|
task :cmp3 do
|
@@ -244,16 +366,25 @@ task :cmp3 do
|
|
244
366
|
end
|
245
367
|
|
246
368
|
task :extract => :isolate do
|
247
|
-
ENV["V"] ||=
|
369
|
+
ENV["V"] ||= VERS.last
|
248
370
|
Rake.application[:parser].invoke # this way we can have DEBUG set
|
249
371
|
|
250
|
-
file = ENV["F"] || ENV["FILE"]
|
372
|
+
file = ENV["F"] || ENV["FILE"] || abort("Need to provide F=<path>")
|
251
373
|
|
252
374
|
ruby "-Ilib", "bin/ruby_parse_extract_error", file
|
253
375
|
end
|
254
376
|
|
377
|
+
task :parse => :isolate do
|
378
|
+
ENV["V"] ||= VERS.last
|
379
|
+
Rake.application[:parser].invoke # this way we can have DEBUG set
|
380
|
+
|
381
|
+
file = ENV["F"] || ENV["FILE"] || abort("Need to provide F=<path>")
|
382
|
+
|
383
|
+
ruby "-Ilib", "bin/ruby_parse", file
|
384
|
+
end
|
385
|
+
|
255
386
|
task :bugs do
|
256
|
-
sh "for f in bug*.rb ; do #{Gem.ruby} -S rake debug F=$f && rm $f ; done"
|
387
|
+
sh "for f in bug*.rb bad*.rb ; do #{Gem.ruby} -S rake debug F=$f && rm $f ; done"
|
257
388
|
end
|
258
389
|
|
259
390
|
# vim: syntax=Ruby
|
data/bin/ruby_parse
CHANGED
@@ -26,6 +26,8 @@ class File
|
|
26
26
|
end
|
27
27
|
|
28
28
|
begin
|
29
|
+
time = (ENV["RP_TIMEOUT"] || 10).to_i
|
30
|
+
|
29
31
|
ARGV.each do |file|
|
30
32
|
rp = RubyParser.new
|
31
33
|
loc = `wc -l #{file}`.strip.to_i
|
@@ -45,7 +47,7 @@ begin
|
|
45
47
|
begin
|
46
48
|
begin
|
47
49
|
rp.reset
|
48
|
-
r = rp.
|
50
|
+
r = rp.process(File.binread(file), file, time)
|
49
51
|
pp r unless $q
|
50
52
|
good += 1
|
51
53
|
rescue SyntaxError => e
|
@@ -21,7 +21,7 @@ class RubyParser
|
|
21
21
|
src = ss.string
|
22
22
|
pre_error = src[0...ss.pos]
|
23
23
|
|
24
|
-
defs = pre_error.grep(/^ *(?:def|it)/)
|
24
|
+
defs = pre_error.lines.grep(/^ *(?:def|it)/)
|
25
25
|
|
26
26
|
raise "can't figure out where the bad code starts" unless defs.last
|
27
27
|
|
@@ -104,9 +104,14 @@ rescue Timeout::Error
|
|
104
104
|
warn "TIMEOUT parsing #{file}. Skipping."
|
105
105
|
|
106
106
|
if $m then
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
base_dir, *rest = file.split("/")
|
108
|
+
base_dir.sub!(/\.slow\.?.*/, "")
|
109
|
+
base_dir += ".slow.#{time}"
|
110
|
+
|
111
|
+
new_file = File.join(base_dir, *rest)
|
112
|
+
|
113
|
+
FileUtils.mkdir_p File.dirname(new_file)
|
114
|
+
FileUtils.move file, new_file, verbose:true
|
110
115
|
elsif $t then
|
111
116
|
File.unlink file
|
112
117
|
end
|
data/compare/normalize.rb
CHANGED
@@ -8,6 +8,10 @@ order = []
|
|
8
8
|
|
9
9
|
def munge s
|
10
10
|
renames = [
|
11
|
+
# unquote... wtf?
|
12
|
+
/`(.+?)'/, proc { $1 },
|
13
|
+
/"'(.+?)'"/, proc { "\"#{$1}\"" },
|
14
|
+
|
11
15
|
"'='", "tEQL",
|
12
16
|
"'!'", "tBANG",
|
13
17
|
"'%'", "tPERCENT",
|
@@ -80,6 +84,8 @@ def munge s
|
|
80
84
|
|
81
85
|
"' '", "tSPACE", # needs to be later to avoid bad hits
|
82
86
|
|
87
|
+
"ε", "none", # bison 3+
|
88
|
+
"%empty", "none", # newer bison
|
83
89
|
"/* empty */", "none",
|
84
90
|
/^\s*$/, "none",
|
85
91
|
|
@@ -100,6 +106,44 @@ def munge s
|
|
100
106
|
|
101
107
|
"kVARIABLE", "keyword_variable", # ugh: this is a rule name
|
102
108
|
|
109
|
+
# 2.7 changes:
|
110
|
+
|
111
|
+
'"global variable"', "tGVAR",
|
112
|
+
'"operator-assignment"', "tOP_ASGN",
|
113
|
+
'"back reference"', "tBACK_REF",
|
114
|
+
'"numbered reference"', "tNTH_REF",
|
115
|
+
'"local variable or method"', "tIDENTIFIER",
|
116
|
+
'"constant"', "tCONSTANT",
|
117
|
+
|
118
|
+
'"(.."', "tBDOT2",
|
119
|
+
'"(..."', "tBDOT3",
|
120
|
+
'"char literal"', "tCHAR",
|
121
|
+
'"literal content"', "tSTRING_CONTENT",
|
122
|
+
'"string literal"', "tSTRING_BEG",
|
123
|
+
'"symbol literal"', "tSYMBEG",
|
124
|
+
'"backtick literal"', "tXSTRING_BEG",
|
125
|
+
'"regexp literal"', "tREGEXP_BEG",
|
126
|
+
'"word list"', "tWORDS_BEG",
|
127
|
+
'"verbatim word list"', "tQWORDS_BEG",
|
128
|
+
'"symbol list"', "tSYMBOLS_BEG",
|
129
|
+
'"verbatim symbol list"', "tQSYMBOLS_BEG",
|
130
|
+
|
131
|
+
'"float literal"', "tFLOAT",
|
132
|
+
'"imaginary literal"', "tIMAGINARY",
|
133
|
+
'"integer literal"', "tINTEGER",
|
134
|
+
'"rational literal"', "tRATIONAL",
|
135
|
+
|
136
|
+
'"instance variable"', "tIVAR",
|
137
|
+
'"class variable"', "tCVAR",
|
138
|
+
'"terminator"', "tSTRING_END", # TODO: switch this?
|
139
|
+
'"method"', "tFID",
|
140
|
+
'"}"', "tSTRING_DEND",
|
141
|
+
|
142
|
+
'"do for block"', "kDO_BLOCK",
|
143
|
+
'"do for condition"', "kDO_COND",
|
144
|
+
'"do for lambda"', "kDO_LAMBDA",
|
145
|
+
"tLABEL", "kLABEL",
|
146
|
+
|
103
147
|
# UGH
|
104
148
|
"k_LINE__", "k__LINE__",
|
105
149
|
"k_FILE__", "k__FILE__",
|
@@ -107,15 +151,17 @@ def munge s
|
|
107
151
|
|
108
152
|
'"defined?"', "kDEFINED",
|
109
153
|
|
110
|
-
|
111
154
|
'"do (for condition)"', "kDO_COND",
|
112
155
|
'"do (for lambda)"', "kDO_LAMBDA",
|
113
156
|
'"do (for block)"', "kDO_BLOCK",
|
114
157
|
|
115
|
-
/\"(\w+) \(modifier\)
|
116
|
-
/\"(\w+)\"/,
|
158
|
+
/\"(\w+) \(?modifier\)?\"/, proc { |x| "k#{$1.upcase}_MOD" },
|
159
|
+
/\"(\w+)\"/, proc { |x| "k#{$1.upcase}" },
|
117
160
|
|
118
|
-
|
161
|
+
/\$?@(\d+)(\s+|$)/, "", # newer bison
|
162
|
+
|
163
|
+
# TODO: remove for 3.0 work:
|
164
|
+
"lex_ctxt ", "" # 3.0 production that's mostly noise right now
|
119
165
|
]
|
120
166
|
|
121
167
|
renames.each_slice(2) do |(a, b)|
|
@@ -134,7 +180,7 @@ ARGF.each_line do |line|
|
|
134
180
|
|
135
181
|
case line.strip
|
136
182
|
when /^$/ then
|
137
|
-
when /^(\d+) (
|
183
|
+
when /^(\d+) (\$?[@\w]+): (.*)/ then # yacc
|
138
184
|
rule = $2
|
139
185
|
order << rule unless rules.has_key? rule
|
140
186
|
rules[rule] << munge($3)
|
@@ -156,10 +202,12 @@ ARGF.each_line do |line|
|
|
156
202
|
break
|
157
203
|
when /^Terminals/ then # yacc
|
158
204
|
break
|
205
|
+
when /^State \d/ then # lrama
|
206
|
+
break
|
159
207
|
when /^\cL/ then # byacc
|
160
208
|
break
|
161
209
|
else
|
162
|
-
warn "unparsed: #{$.}: #{line.
|
210
|
+
warn "unparsed: #{$.}: #{line.strip.inspect}"
|
163
211
|
end
|
164
212
|
end
|
165
213
|
|