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