ruby_parser 3.0.0.a5 → 3.0.0.a6
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.tar.gz.sig +0 -0
- data/.autotest +1 -0
- data/History.txt +18 -0
- data/bin/ruby_parse_extract_error +39 -18
- data/lib/ruby18_parser.rb +1 -1
- data/lib/ruby19_parser.rb +4 -4
- data/lib/ruby19_parser.y +3 -3
- data/lib/ruby_lexer.rb +21 -7
- data/lib/ruby_parser_extras.rb +22 -4
- data/test/test_ruby_parser.rb +88 -4
- metadata +4 -4
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/.autotest
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== 3.0.0.a6 / 2012-08-20
|
2
|
+
|
3
|
+
* 2 minor enhancements:
|
4
|
+
|
5
|
+
* 1.8: Added basic encoding support to 1.8 parser. Assumes -Ku.
|
6
|
+
* 1.9: Added encoding magic comment support to 1.9 parser.
|
7
|
+
|
8
|
+
* 8 bug fixes:
|
9
|
+
|
10
|
+
* 1.9: Fixed lexing of -1 w/in conditionals. yeah... I dunno.
|
11
|
+
* 1.9: Fixed parsing of a do | | end.
|
12
|
+
* 1.9: Fixed parsing of not(x).
|
13
|
+
* 1.9: Fixed parsing of op_asgn + rescue: 'a ||= b rescue nil'
|
14
|
+
* 1.9: added \r to the EOL backslash handler. dos files blow
|
15
|
+
* 1.9: hacked in a workaround for 1.9 specific regexps running in 1.8.
|
16
|
+
* Added #reset to RubyParser proxy class
|
17
|
+
* Fixed lexing of conditional w/ %() tokens
|
18
|
+
|
1
19
|
=== 3.0.0.a5 / 2012-07-31
|
2
20
|
|
3
21
|
* 5 bug fixes:
|
@@ -1,5 +1,10 @@
|
|
1
1
|
#!/usr/bin/ruby -ws
|
2
2
|
|
3
|
+
$d ||= false
|
4
|
+
$d ||= ENV["DELETE"]
|
5
|
+
$q ||= false
|
6
|
+
$q ||= ENV["QUIET"]
|
7
|
+
|
3
8
|
require 'rubygems'
|
4
9
|
require 'ruby_parser'
|
5
10
|
|
@@ -13,6 +18,8 @@ class Racc::Parser
|
|
13
18
|
|
14
19
|
defs = pre_error.grep(/^ *def/)
|
15
20
|
|
21
|
+
raise "can't figure out where the bad code starts" unless defs.last
|
22
|
+
|
16
23
|
last_def_indent = defs.last[/^ */]
|
17
24
|
|
18
25
|
post_error = src[ss.pos..-1]
|
@@ -30,7 +37,9 @@ class Racc::Parser
|
|
30
37
|
|
31
38
|
parser = self.class.new
|
32
39
|
|
33
|
-
parser.process(defs.join("\n\n"))
|
40
|
+
parser.process(defs.join("\n\n"))
|
41
|
+
rescue SyntaxError, StandardError
|
42
|
+
nil
|
34
43
|
end
|
35
44
|
end
|
36
45
|
|
@@ -46,34 +55,46 @@ ARGV.replace ARGV.map { |path|
|
|
46
55
|
f =~ /bad_ruby_file/ # I have intentionally bad code in my test dirs
|
47
56
|
}
|
48
57
|
|
49
|
-
parser = Ruby19Parser.new
|
50
|
-
|
51
58
|
ARGV.each do |file|
|
52
59
|
ruby = file == "-" ? $stdin.read : File.read(file)
|
53
60
|
|
54
61
|
begin
|
55
|
-
$stderr.print "Validating #{file}: "
|
62
|
+
$stderr.print "# Validating #{file}: "
|
63
|
+
parser = Ruby19Parser.new
|
56
64
|
parser.process(ruby, file)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
$
|
65
|
+
warn "good"
|
66
|
+
File.unlink file if $d
|
67
|
+
rescue StandardError, SyntaxError, Racc::ParseError => e
|
68
|
+
warn "# error: #{e.message.strip}" unless $q
|
69
|
+
warn ""
|
70
|
+
next if $q
|
61
71
|
|
62
|
-
|
72
|
+
begin
|
73
|
+
defs = parser.extract_defs
|
63
74
|
|
64
|
-
|
65
|
-
parser.retest_for_errors defs
|
75
|
+
orig_size = defs.size
|
66
76
|
|
67
|
-
|
77
|
+
if parser.retest_for_errors defs then
|
78
|
+
warn "Can't reproduce error with just methods, punting..."
|
79
|
+
next
|
80
|
+
end
|
68
81
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
mandatory = defs.pop
|
83
|
+
|
84
|
+
catch :extract_done do
|
85
|
+
(1..defs.size).each do |perm_size|
|
86
|
+
defs.combination(perm_size).each do |trial|
|
87
|
+
trial << mandatory
|
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
|
75
94
|
end
|
76
95
|
end
|
96
|
+
rescue RuntimeError, Racc::ParseError => e
|
97
|
+
warn "# error: #{e.message.strip}"
|
77
98
|
end
|
78
99
|
end
|
79
100
|
end
|
data/lib/ruby18_parser.rb
CHANGED
data/lib/ruby19_parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by Racc 1.4.
|
3
|
+
# This file is automatically generated by Racc 1.4.9
|
4
4
|
# from Racc grammer file "".
|
5
5
|
#
|
6
6
|
|
@@ -3992,7 +3992,7 @@ end
|
|
3992
3992
|
|
3993
3993
|
def _reduce_198(val, _values, result)
|
3994
3994
|
result = new_op_asgn val
|
3995
|
-
result =
|
3995
|
+
result = s(:rescue, result, new_resbody(s(:array), val[4]))
|
3996
3996
|
|
3997
3997
|
result
|
3998
3998
|
end
|
@@ -4540,7 +4540,7 @@ def _reduce_292(val, _values, result)
|
|
4540
4540
|
end
|
4541
4541
|
|
4542
4542
|
def _reduce_293(val, _values, result)
|
4543
|
-
|
4543
|
+
result = s(:call, val[2], :"!")
|
4544
4544
|
|
4545
4545
|
result
|
4546
4546
|
end
|
@@ -5029,7 +5029,7 @@ end
|
|
5029
5029
|
# reduce 383 omitted
|
5030
5030
|
|
5031
5031
|
def _reduce_384(val, _values, result)
|
5032
|
-
|
5032
|
+
result = val[1] || 0
|
5033
5033
|
|
5034
5034
|
result
|
5035
5035
|
end
|
data/lib/ruby19_parser.y
CHANGED
@@ -582,7 +582,7 @@ rule
|
|
582
582
|
| var_lhs tOP_ASGN arg kRESCUE_MOD arg
|
583
583
|
{
|
584
584
|
result = new_op_asgn val
|
585
|
-
result =
|
585
|
+
result = s(:rescue, result, new_resbody(s(:array), val[4]))
|
586
586
|
}
|
587
587
|
| primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
|
588
588
|
{
|
@@ -966,7 +966,7 @@ rule
|
|
966
966
|
}
|
967
967
|
| kNOT tLPAREN2 expr rparen
|
968
968
|
{
|
969
|
-
|
969
|
+
result = s(:call, val[2], :"!")
|
970
970
|
}
|
971
971
|
| kNOT tLPAREN2 rparen
|
972
972
|
{
|
@@ -1309,7 +1309,7 @@ rule
|
|
1309
1309
|
|
1310
1310
|
block_param_def: tPIPE opt_bv_decl tPIPE
|
1311
1311
|
{
|
1312
|
-
|
1312
|
+
result = val[1] || 0
|
1313
1313
|
}
|
1314
1314
|
| tOROP
|
1315
1315
|
{
|
data/lib/ruby_lexer.rb
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
+
# encoding: US-ASCII
|
2
|
+
|
1
3
|
class RubyLexer
|
4
|
+
|
5
|
+
IDENT_CHAR_RE = case RUBY_VERSION
|
6
|
+
when /^1\.8/ then
|
7
|
+
/[\w\x80-\xFF]/
|
8
|
+
when /^(1\.9|2\.0)/ then # HACK - matching 2.0 for now
|
9
|
+
/[\w\u0080-\uFFFF]/u
|
10
|
+
else
|
11
|
+
raise "bork"
|
12
|
+
end
|
13
|
+
|
14
|
+
IDENT_RE = /^#{IDENT_CHAR_RE}+/
|
15
|
+
|
2
16
|
attr_accessor :command_start
|
3
17
|
attr_accessor :cmdarg
|
4
18
|
attr_accessor :cond
|
@@ -773,7 +787,7 @@ class RubyLexer
|
|
773
787
|
self.lex_state = :expr_dot
|
774
788
|
self.yacc_value = "::"
|
775
789
|
return :tCOLON2
|
776
|
-
elsif ! is_end? && src.scan(/:([a-zA-Z_]
|
790
|
+
elsif ! is_end? && src.scan(/:([a-zA-Z_]#{IDENT_CHAR_RE}*(?:[?!]|=(?!>))?)/) then
|
777
791
|
# scanning shortcut to symbols
|
778
792
|
self.yacc_value = src[1]
|
779
793
|
self.lex_state = :expr_end
|
@@ -898,7 +912,7 @@ class RubyLexer
|
|
898
912
|
return :tOP_ASGN
|
899
913
|
end
|
900
914
|
|
901
|
-
if (
|
915
|
+
if (is_beg? ||
|
902
916
|
(lex_state.is_argument && space_seen && !src.check(/\s/))) then
|
903
917
|
if lex_state.is_argument then
|
904
918
|
arg_ambiguous
|
@@ -1144,14 +1158,14 @@ class RubyLexer
|
|
1144
1158
|
|
1145
1159
|
return :tTILDE
|
1146
1160
|
elsif src.scan(/\\/) then
|
1147
|
-
if src.scan(/\n/) then
|
1161
|
+
if src.scan(/\r?\n/) then
|
1148
1162
|
self.lineno = nil
|
1149
1163
|
self.space_seen = true
|
1150
1164
|
next
|
1151
1165
|
end
|
1152
1166
|
rb_compile_error "bare backslash only allowed before newline"
|
1153
1167
|
elsif src.scan(/\%/) then
|
1154
|
-
if
|
1168
|
+
if is_beg? then
|
1155
1169
|
return parse_quote
|
1156
1170
|
end
|
1157
1171
|
|
@@ -1229,12 +1243,12 @@ class RubyLexer
|
|
1229
1243
|
if src.scan(/\004|\032|\000/) || src.eos? then # ^D, ^Z, EOF
|
1230
1244
|
return RubyLexer::EOF
|
1231
1245
|
else # alpha check
|
1232
|
-
|
1246
|
+
unless src.check IDENT_RE then
|
1233
1247
|
rb_compile_error "Invalid char #{src.matched.inspect} in expression"
|
1234
1248
|
end
|
1235
1249
|
end
|
1236
1250
|
|
1237
|
-
self.token = src.matched if self.src.scan
|
1251
|
+
self.token = src.matched if self.src.scan IDENT_RE
|
1238
1252
|
|
1239
1253
|
return process_token(command_state)
|
1240
1254
|
end
|
@@ -1311,7 +1325,7 @@ class RubyLexer
|
|
1311
1325
|
|
1312
1326
|
def process_token(command_state)
|
1313
1327
|
|
1314
|
-
token << src.matched if token =~
|
1328
|
+
token << src.matched if token =~ IDENT_RE && src.scan(/[\!\?](?!=)/)
|
1315
1329
|
|
1316
1330
|
result = nil
|
1317
1331
|
last_state = lex_state
|
data/lib/ruby_parser_extras.rb
CHANGED
@@ -78,7 +78,7 @@ class RPStringScanner < StringScanner
|
|
78
78
|
end
|
79
79
|
|
80
80
|
module RubyParserStuff
|
81
|
-
VERSION = '3.0.0.
|
81
|
+
VERSION = '3.0.0.a6' unless constants.include? "VERSION" # SIGH
|
82
82
|
|
83
83
|
attr_accessor :lexer, :in_def, :in_single, :file
|
84
84
|
attr_reader :env, :comments
|
@@ -749,7 +749,7 @@ module RubyParserStuff
|
|
749
749
|
Regexp.new(node[1], o, k)
|
750
750
|
else
|
751
751
|
Regexp.new(node[1], o)
|
752
|
-
end
|
752
|
+
end rescue node[1] # HACK - drops options
|
753
753
|
when :dstr then
|
754
754
|
if options =~ /o/ then
|
755
755
|
node[0] = :dregx_once
|
@@ -902,8 +902,21 @@ module RubyParserStuff
|
|
902
902
|
def process(str, file = "(string)")
|
903
903
|
raise "bad val: #{str.inspect}" unless String === str
|
904
904
|
|
905
|
+
str.lines.first(2).find { |s| s[/^# encoding: (.+)/, 1] }
|
906
|
+
encoding = $1
|
907
|
+
|
908
|
+
str = str.dup
|
909
|
+
|
910
|
+
if encoding then
|
911
|
+
if defined?(Encoding) then
|
912
|
+
str.force_encoding(encoding).encode! "utf-8"
|
913
|
+
else
|
914
|
+
warn "Skipping magic encoding comment"
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
905
918
|
self.file = file
|
906
|
-
self.lexer.src = str
|
919
|
+
self.lexer.src = str
|
907
920
|
|
908
921
|
@yydebug = ENV.has_key? 'DEBUG'
|
909
922
|
|
@@ -1199,13 +1212,18 @@ class RubyParser
|
|
1199
1212
|
@p19 = Ruby19Parser.new
|
1200
1213
|
end
|
1201
1214
|
|
1202
|
-
def process
|
1215
|
+
def process(s, f = "(string)") # parens for emacs *sigh*
|
1203
1216
|
Ruby19Parser.new.process s, f
|
1204
1217
|
rescue Racc::ParseError
|
1205
1218
|
Ruby18Parser.new.process s, f
|
1206
1219
|
end
|
1207
1220
|
|
1208
1221
|
alias :parse :process
|
1222
|
+
|
1223
|
+
def reset
|
1224
|
+
@p18.reset
|
1225
|
+
@p19.reset
|
1226
|
+
end
|
1209
1227
|
end
|
1210
1228
|
|
1211
1229
|
############################################################
|
data/test/test_ruby_parser.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/local/bin/ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# ENV['VERBOSE'] = "1"
|
4
5
|
|
@@ -646,6 +647,13 @@ module TestRubyParserShared
|
|
646
647
|
assert_parse rb, pt
|
647
648
|
end
|
648
649
|
|
650
|
+
def test_bug_cond_pct
|
651
|
+
rb = "case; when %r%blahblah%; end"
|
652
|
+
pt = s(:case, nil, s(:when, s(:array, s(:lit, /blahblah/)), nil), nil)
|
653
|
+
|
654
|
+
assert_parse rb, pt
|
655
|
+
end
|
656
|
+
|
649
657
|
# according to 2.3.1 parser:
|
650
658
|
# rp.process("f { |(a,b),c| }") == rp.process("f { |((a,b),c)| }")
|
651
659
|
|
@@ -657,7 +665,7 @@ module TestRubyParserShared
|
|
657
665
|
# s(:array,
|
658
666
|
# s(:masgn, s(:array, s(:lasgn, :a), s(:lasgn, :b))),
|
659
667
|
# s(:lasgn, :c))))
|
660
|
-
#
|
668
|
+
#
|
661
669
|
# assert_parse rb, pt.dup
|
662
670
|
# end
|
663
671
|
|
@@ -690,11 +698,18 @@ module TestRubyParserShared
|
|
690
698
|
# assert_parse rb, pt
|
691
699
|
# end
|
692
700
|
|
701
|
+
def ruby18
|
702
|
+
Ruby18Parser === self.processor
|
703
|
+
end
|
704
|
+
|
705
|
+
def ruby19
|
706
|
+
Ruby19Parser === self.processor
|
707
|
+
end
|
708
|
+
|
693
709
|
def test_bug_comma
|
694
|
-
val =
|
695
|
-
when Ruby18Parser then
|
710
|
+
val = if ruby18 then
|
696
711
|
s(:lit, 100)
|
697
|
-
|
712
|
+
elsif ruby19 then
|
698
713
|
s(:str, "d")
|
699
714
|
else
|
700
715
|
raise "wtf"
|
@@ -745,6 +760,68 @@ module TestRubyParserShared
|
|
745
760
|
|
746
761
|
assert_parse rb, pt
|
747
762
|
end
|
763
|
+
|
764
|
+
|
765
|
+
def test_bug_not_parens
|
766
|
+
rb = "not(a)"
|
767
|
+
pt = if ruby18 then
|
768
|
+
s(:not, s(:call, nil, :a))
|
769
|
+
elsif ruby19 then
|
770
|
+
s(:call, s(:call, nil, :a), :"!")
|
771
|
+
else
|
772
|
+
raise "wtf"
|
773
|
+
end
|
774
|
+
|
775
|
+
assert_parse rb, pt
|
776
|
+
end
|
777
|
+
|
778
|
+
def test_pipe_space
|
779
|
+
rb = "a.b do | | end"
|
780
|
+
pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
|
781
|
+
|
782
|
+
assert_parse rb, pt
|
783
|
+
end
|
784
|
+
|
785
|
+
def test_cond_unary_minus
|
786
|
+
rb = "if -1; end"
|
787
|
+
pt = s(:if, s(:lit, -1), nil, nil)
|
788
|
+
|
789
|
+
assert_parse rb, pt
|
790
|
+
end
|
791
|
+
|
792
|
+
def test_bug_op_asgn_rescue
|
793
|
+
rb = "a ||= b rescue nil"
|
794
|
+
pt = s(:rescue,
|
795
|
+
s(:op_asgn_or, s(:lvar, :a), s(:lasgn, :a, s(:call, nil, :b))),
|
796
|
+
s(:resbody, s(:array), s(:nil)))
|
797
|
+
|
798
|
+
assert_parse rb, pt
|
799
|
+
end
|
800
|
+
|
801
|
+
def test_magic_encoding_comment
|
802
|
+
rb = <<-EOM.gsub(/^ /, '')
|
803
|
+
# encoding: utf-8
|
804
|
+
class ExampleUTF8ClassNameVarietà
|
805
|
+
def self.è
|
806
|
+
così = :però
|
807
|
+
end
|
808
|
+
end
|
809
|
+
EOM
|
810
|
+
|
811
|
+
# TODO: class vars
|
812
|
+
# TODO: odd-ternary: a ?bb : c
|
813
|
+
# TODO: globals
|
814
|
+
|
815
|
+
pt = s(:class, :"ExampleUTF8ClassNameVariet\303\240", nil,
|
816
|
+
s(:defs, s(:self), :"\303\250", s(:args),
|
817
|
+
s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262"))))
|
818
|
+
|
819
|
+
err = RUBY_VERSION =~ /^1\.8/ ? "Skipping magic encoding comment\n" : ""
|
820
|
+
|
821
|
+
assert_output "", err do
|
822
|
+
assert_parse rb, pt
|
823
|
+
end
|
824
|
+
end
|
748
825
|
end
|
749
826
|
|
750
827
|
class TestRubyParser < MiniTest::Unit::TestCase
|
@@ -1112,6 +1189,13 @@ class TestRuby19Parser < RubyParserTestCase
|
|
1112
1189
|
assert_parse rb, pt
|
1113
1190
|
end
|
1114
1191
|
|
1192
|
+
# def test_pipe_semicolon # HACK
|
1193
|
+
# rb = "a.b do | ; c | end"
|
1194
|
+
# pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
|
1195
|
+
#
|
1196
|
+
# assert_parse rb, pt
|
1197
|
+
# end
|
1198
|
+
|
1115
1199
|
# HACK: need to figure out the desired structure and get this working
|
1116
1200
|
# def test_wtf
|
1117
1201
|
# # lambda -> f_larglist lambda_body
|
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: 4039646929
|
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
|
+
- 6
|
12
|
+
version: 3.0.0.a6
|
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-08-
|
41
|
+
date: 2012-08-20 00:00:00 Z
|
42
42
|
dependencies:
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: sexp_processor
|
metadata.gz.sig
CHANGED
Binary file
|