ruby_parser 3.0.0.a6 → 3.0.0.a7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby_parser might be problematic. Click here for more details.
- data/History.txt +14 -0
- data/bin/ruby_parse_extract_error +48 -46
- data/lib/ruby19_parser.rb +3 -7
- data/lib/ruby19_parser.y +1 -4
- data/lib/ruby_lexer.rb +11 -8
- data/lib/ruby_parser_extras.rb +28 -18
- data/test/test_ruby_parser.rb +31 -1
- data.tar.gz.sig +0 -0
- metadata +7 -7
- metadata.gz.sig +0 -0
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 3.0.0.a7 / 2012-09-21
|
2
|
+
|
3
|
+
* 3 minor enhancements:
|
4
|
+
|
5
|
+
* Reorganized ruby_parse_extract_error so it will start much faster with a bunch of glob directories
|
6
|
+
* RubyParserStuff#process takes optional time arg and raises Timeout::Error if it goes too long. You should rescue that, ya know...
|
7
|
+
* ruby_parse_extract_error now checks *.rake and Rakefile on dir scan.
|
8
|
+
|
9
|
+
* 3 bug fixes:
|
10
|
+
|
11
|
+
* 1.9: Fixed ternary state tracking so {a:f{f()},b:nil} won't trip up the lexer.
|
12
|
+
* Fixed optional values in block args (no20/no21)
|
13
|
+
* ruby_parse_extract_error skips non-files. Some asshats put .rb on their dirs. :(
|
14
|
+
|
1
15
|
=== 3.0.0.a6 / 2012-08-20
|
2
16
|
|
3
17
|
* 2 minor enhancements:
|
@@ -33,8 +33,6 @@ class Racc::Parser
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def retest_for_errors defs
|
36
|
-
warn "# retest: #{defs.size}"
|
37
|
-
|
38
36
|
parser = self.class.new
|
39
37
|
|
40
38
|
parser.process(defs.join("\n\n"))
|
@@ -43,58 +41,62 @@ class Racc::Parser
|
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
|
-
|
44
|
+
def expand path
|
47
45
|
if File.directory? path then
|
48
|
-
Dir.glob File.join path, "
|
49
|
-
elsif path =~ /\*\*/ then
|
50
|
-
Dir.glob path
|
46
|
+
Dir.glob File.join path, "**/{*.rb,*.rake,Rakefile}"
|
51
47
|
else
|
52
|
-
path
|
48
|
+
Dir.glob path
|
53
49
|
end
|
54
|
-
|
55
|
-
f =~ /bad_ruby_file/ # I have intentionally bad code in my test dirs
|
56
|
-
}
|
50
|
+
end
|
57
51
|
|
58
|
-
|
59
|
-
|
52
|
+
def process_error parser
|
53
|
+
defs = parser.extract_defs
|
60
54
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
rescue StandardError, SyntaxError, Racc::ParseError => e
|
68
|
-
warn "# error: #{e.message.strip}" unless $q
|
69
|
-
warn ""
|
70
|
-
next if $q
|
71
|
-
|
72
|
-
begin
|
73
|
-
defs = parser.extract_defs
|
74
|
-
|
75
|
-
orig_size = defs.size
|
76
|
-
|
77
|
-
if parser.retest_for_errors defs then
|
78
|
-
warn "Can't reproduce error with just methods, punting..."
|
79
|
-
next
|
80
|
-
end
|
55
|
+
orig_size = defs.size
|
56
|
+
|
57
|
+
if parser.retest_for_errors defs then
|
58
|
+
warn "Can't reproduce error with just methods, punting..."
|
59
|
+
return
|
60
|
+
end
|
81
61
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
unless parser.retest_for_errors trial then
|
89
|
-
puts trial.join "\n"
|
90
|
-
warn "# reduced repro found!"
|
91
|
-
throw :extract_done
|
92
|
-
end
|
93
|
-
end
|
62
|
+
catch :extract_done do
|
63
|
+
(1..defs.size).each do |perm_size|
|
64
|
+
defs.combination(perm_size).each do |trial|
|
65
|
+
unless parser.retest_for_errors trial then
|
66
|
+
puts trial.join "\n"
|
67
|
+
throw :extract_done
|
94
68
|
end
|
95
69
|
end
|
96
|
-
rescue RuntimeError, Racc::ParseError => e
|
97
|
-
warn "# error: #{e.message.strip}"
|
98
70
|
end
|
99
71
|
end
|
72
|
+
rescue RuntimeError, Racc::ParseError => e
|
73
|
+
warn "# error: #{e.message.strip}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def process file
|
77
|
+
ruby = file == "-" ? $stdin.read : File.read(file)
|
78
|
+
|
79
|
+
$stderr.print "# Validating #{file}: "
|
80
|
+
parser = Ruby19Parser.new
|
81
|
+
parser.process(ruby, file)
|
82
|
+
warn "good"
|
83
|
+
File.unlink file if $d
|
84
|
+
rescue StandardError, SyntaxError, Racc::ParseError => e
|
85
|
+
warn ""
|
86
|
+
warn "# error: #{e.message.strip}" unless $q
|
87
|
+
warn ""
|
88
|
+
return if $q
|
89
|
+
|
90
|
+
process_error parser
|
91
|
+
rescue Timeout::Error
|
92
|
+
warn "TIMEOUT parsing #{file}. Skipping."
|
93
|
+
end
|
94
|
+
|
95
|
+
$stdout.sync = true
|
96
|
+
|
97
|
+
ARGV.each do |path|
|
98
|
+
expand(path).each do |file|
|
99
|
+
next unless File.file? file # omg... why would you name a dir support.rb?
|
100
|
+
process file
|
101
|
+
end
|
100
102
|
end
|
data/lib/ruby19_parser.rb
CHANGED
@@ -2593,7 +2593,7 @@ racc_reduce_table = [
|
|
2593
2593
|
3, 266, :_reduce_527,
|
2594
2594
|
3, 309, :_reduce_528,
|
2595
2595
|
3, 310, :_reduce_529,
|
2596
|
-
1, 267, :
|
2596
|
+
1, 267, :_reduce_none,
|
2597
2597
|
3, 267, :_reduce_531,
|
2598
2598
|
1, 307, :_reduce_532,
|
2599
2599
|
3, 307, :_reduce_533,
|
@@ -5881,16 +5881,12 @@ def _reduce_528(val, _values, result)
|
|
5881
5881
|
end
|
5882
5882
|
|
5883
5883
|
def _reduce_529(val, _values, result)
|
5884
|
-
|
5884
|
+
result = self.assignable val[0], val[2]
|
5885
5885
|
|
5886
5886
|
result
|
5887
5887
|
end
|
5888
5888
|
|
5889
|
-
|
5890
|
-
raise "no21: #{val.inspect}"
|
5891
|
-
|
5892
|
-
result
|
5893
|
-
end
|
5889
|
+
# reduce 530 omitted
|
5894
5890
|
|
5895
5891
|
def _reduce_531(val, _values, result)
|
5896
5892
|
raise "no22: #{val.inspect}"
|
data/lib/ruby19_parser.y
CHANGED
@@ -1920,13 +1920,10 @@ keyword_variable: kNIL { result = s(:nil) }
|
|
1920
1920
|
|
1921
1921
|
f_block_opt: tIDENTIFIER tEQL primary_value
|
1922
1922
|
{
|
1923
|
-
|
1923
|
+
result = self.assignable val[0], val[2]
|
1924
1924
|
}
|
1925
1925
|
|
1926
1926
|
f_block_optarg: f_block_opt
|
1927
|
-
{
|
1928
|
-
raise "no21: #{val.inspect}"
|
1929
|
-
}
|
1930
1927
|
| f_block_optarg tCOMMA f_block_opt
|
1931
1928
|
{
|
1932
1929
|
raise "no22: #{val.inspect}"
|
data/lib/ruby_lexer.rb
CHANGED
@@ -16,7 +16,7 @@ class RubyLexer
|
|
16
16
|
attr_accessor :command_start
|
17
17
|
attr_accessor :cmdarg
|
18
18
|
attr_accessor :cond
|
19
|
-
attr_accessor :tern
|
19
|
+
attr_accessor :tern # TODO: rename ternary damnit... wtf
|
20
20
|
attr_accessor :nest
|
21
21
|
|
22
22
|
ESC_RE = /\\([0-7]{1,3}|x[0-9a-fA-F]{1,2}|M-[^\\]|(C-|c)[^\\]|[^0-7xMCc])/
|
@@ -711,6 +711,7 @@ class RubyLexer
|
|
711
711
|
elsif src.scan(/[\]\)\}]/) then
|
712
712
|
cond.lexpop
|
713
713
|
cmdarg.lexpop
|
714
|
+
tern.lexpop
|
714
715
|
self.lex_state = :expr_end
|
715
716
|
self.yacc_value = src.matched
|
716
717
|
result = {
|
@@ -718,7 +719,6 @@ class RubyLexer
|
|
718
719
|
"]" => :tRBRACK,
|
719
720
|
"}" => :tRCURLY
|
720
721
|
}[src.matched]
|
721
|
-
self.tern.lexpop if [:tRBRACK, :tRCURLY].include?(result)
|
722
722
|
return result
|
723
723
|
elsif src.scan(/\.\.\.?|,|![=~]?/) then
|
724
724
|
self.lex_state = :expr_beg
|
@@ -1295,6 +1295,10 @@ class RubyLexer
|
|
1295
1295
|
is_arg? and space_seen and c !~ /\s/
|
1296
1296
|
end
|
1297
1297
|
|
1298
|
+
def is_label_possible? command_state
|
1299
|
+
(lex_state == :expr_beg && !command_state) || is_arg?
|
1300
|
+
end
|
1301
|
+
|
1298
1302
|
def yylex_paren19
|
1299
1303
|
if is_beg? then
|
1300
1304
|
result = :tLPAREN
|
@@ -1358,15 +1362,11 @@ class RubyLexer
|
|
1358
1362
|
end
|
1359
1363
|
|
1360
1364
|
unless self.tern.is_in_state
|
1361
|
-
if
|
1362
|
-
lex_state == :expr_arg ||
|
1363
|
-
lex_state == :expr_cmdarg then
|
1365
|
+
if is_label_possible? command_state then
|
1364
1366
|
colon = src.scan(/:/)
|
1365
1367
|
|
1366
|
-
if colon && src.peek(1) != ":"
|
1367
|
-
src.unscan
|
1368
|
+
if colon && src.peek(1) != ":" then
|
1368
1369
|
self.lex_state = :expr_beg
|
1369
|
-
src.scan(/:/)
|
1370
1370
|
self.yacc_value = [token, src.lineno]
|
1371
1371
|
return :tLABEL
|
1372
1372
|
end
|
@@ -1413,6 +1413,9 @@ class RubyLexer
|
|
1413
1413
|
end
|
1414
1414
|
end
|
1415
1415
|
|
1416
|
+
# TODO:
|
1417
|
+
# if (mb == ENC_CODERANGE_7BIT && lex_state != EXPR_DOT) {
|
1418
|
+
|
1416
1419
|
self.lex_state =
|
1417
1420
|
if is_beg? || lex_state == :expr_dot || is_arg? then
|
1418
1421
|
if command_state then
|
data/lib/ruby_parser_extras.rb
CHANGED
@@ -3,6 +3,7 @@ require 'racc/parser'
|
|
3
3
|
require 'sexp'
|
4
4
|
require 'strscan'
|
5
5
|
require 'ruby_lexer'
|
6
|
+
require "timeout"
|
6
7
|
|
7
8
|
def d o
|
8
9
|
$stderr.puts o.inspect
|
@@ -78,7 +79,7 @@ class RPStringScanner < StringScanner
|
|
78
79
|
end
|
79
80
|
|
80
81
|
module RubyParserStuff
|
81
|
-
VERSION = '3.0.0.
|
82
|
+
VERSION = '3.0.0.a7' unless constants.include? "VERSION" # SIGH
|
82
83
|
|
83
84
|
attr_accessor :lexer, :in_def, :in_single, :file
|
84
85
|
attr_reader :env, :comments
|
@@ -190,8 +191,8 @@ module RubyParserStuff
|
|
190
191
|
|
191
192
|
def block_args19 val, id
|
192
193
|
# HACK OMG THIS CODE IS SOOO UGLY! CLEAN ME
|
193
|
-
untested = %w[1 2 3 4 7 9 10
|
194
|
-
raise "no block_args19 #{id}" if untested.include? id
|
194
|
+
untested = %w[1 2 3 4 7 9 10 12 14]
|
195
|
+
raise "no block_args19 #{id} #{val.inspect}" if untested.include? id
|
195
196
|
|
196
197
|
r = s(:array)
|
197
198
|
|
@@ -213,6 +214,8 @@ module RubyParserStuff
|
|
213
214
|
}
|
214
215
|
when :block_arg then
|
215
216
|
r << s(:lasgn, :"&#{v.last}")
|
217
|
+
when :lasgn then
|
218
|
+
r << s(:masgn, s(:array, v))
|
216
219
|
when :masgn then
|
217
220
|
r << v
|
218
221
|
else
|
@@ -899,29 +902,36 @@ module RubyParserStuff
|
|
899
902
|
lhs
|
900
903
|
end
|
901
904
|
|
902
|
-
|
903
|
-
|
905
|
+
##
|
906
|
+
# Parse +str+ at path +file+ and return a sexp. Raises
|
907
|
+
# Timeout::Error if it runs for more than +time+ seconds.
|
904
908
|
|
905
|
-
|
906
|
-
|
909
|
+
def process(str, file = "(string)", time = 10)
|
910
|
+
Timeout.timeout time do
|
911
|
+
raise "bad val: #{str.inspect}" unless String === str
|
907
912
|
|
908
|
-
|
913
|
+
str.lines.first(2).find { |s| s[/^# encoding: (.+)/, 1] }
|
914
|
+
encoding = $1
|
909
915
|
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
916
|
+
str = str.dup
|
917
|
+
|
918
|
+
if encoding then
|
919
|
+
if defined?(Encoding) then
|
920
|
+
str.force_encoding(encoding).encode! "utf-8"
|
921
|
+
else
|
922
|
+
warn "Skipping magic encoding comment"
|
923
|
+
end
|
915
924
|
end
|
916
|
-
end
|
917
925
|
|
918
|
-
|
919
|
-
|
926
|
+
self.file = file
|
927
|
+
self.lexer.src = str
|
920
928
|
|
921
|
-
|
929
|
+
@yydebug = ENV.has_key? 'DEBUG'
|
922
930
|
|
923
|
-
|
931
|
+
do_parse
|
932
|
+
end
|
924
933
|
end
|
934
|
+
|
925
935
|
alias :parse :process
|
926
936
|
|
927
937
|
def remove_begin node
|
data/test/test_ruby_parser.rb
CHANGED
@@ -1189,10 +1189,40 @@ class TestRuby19Parser < RubyParserTestCase
|
|
1189
1189
|
assert_parse rb, pt
|
1190
1190
|
end
|
1191
1191
|
|
1192
|
+
def test_block_arg_optional
|
1193
|
+
rb = "a { |b = 1| }"
|
1194
|
+
pt = s(:iter,
|
1195
|
+
s(:call, nil, :a),
|
1196
|
+
s(:masgn, s(:array, s(:lasgn, :b, s(:lit, 1)))))
|
1197
|
+
|
1198
|
+
assert_parse rb, pt
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
def test_zomg_sometimes_i_hate_this_project
|
1202
|
+
rb = <<-RUBY
|
1203
|
+
{
|
1204
|
+
a: lambda { b ? c() : d },
|
1205
|
+
e: nil,
|
1206
|
+
}
|
1207
|
+
RUBY
|
1208
|
+
|
1209
|
+
pt = s(:hash,
|
1210
|
+
s(:lit, :a),
|
1211
|
+
s(:iter,
|
1212
|
+
s(:call, nil, :lambda),
|
1213
|
+
nil,
|
1214
|
+
s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
|
1215
|
+
|
1216
|
+
s(:lit, :e),
|
1217
|
+
s(:nil))
|
1218
|
+
|
1219
|
+
assert_parse rb, pt
|
1220
|
+
end
|
1221
|
+
|
1192
1222
|
# def test_pipe_semicolon # HACK
|
1193
1223
|
# rb = "a.b do | ; c | end"
|
1194
1224
|
# pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
|
1195
|
-
#
|
1225
|
+
#
|
1196
1226
|
# assert_parse rb, pt
|
1197
1227
|
# end
|
1198
1228
|
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1069898451
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 0
|
9
9
|
- 0
|
10
10
|
- a
|
11
|
-
-
|
12
|
-
version: 3.0.0.
|
11
|
+
- 7
|
12
|
+
version: 3.0.0.a7
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Ryan Davis
|
@@ -38,7 +38,7 @@ cert_chain:
|
|
38
38
|
FBHgymkyj/AOSqKRIpXPhjC6
|
39
39
|
-----END CERTIFICATE-----
|
40
40
|
|
41
|
-
date: 2012-
|
41
|
+
date: 2012-09-21 00:00:00 Z
|
42
42
|
dependencies:
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: sexp_processor
|
@@ -63,11 +63,11 @@ dependencies:
|
|
63
63
|
requirements:
|
64
64
|
- - ~>
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
hash:
|
66
|
+
hash: 1
|
67
67
|
segments:
|
68
68
|
- 3
|
69
|
-
-
|
70
|
-
version: "3.
|
69
|
+
- 3
|
70
|
+
version: "3.3"
|
71
71
|
type: :development
|
72
72
|
version_requirements: *id002
|
73
73
|
- !ruby/object:Gem::Dependency
|
metadata.gz.sig
CHANGED
Binary file
|