ruby_parser 3.0.0.a6 → 3.0.0.a7
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.
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
|