ruby_parser 3.0.0.a3 → 3.0.0.a4
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/History.txt +21 -0
- data/Rakefile +10 -1
- data/bin/ruby_parse_extract_error +6 -4
- data/lib/ruby19_parser.rb +16 -9
- data/lib/ruby19_parser.y +19 -9
- data/lib/ruby_lexer.rb +4 -2
- data/lib/ruby_parser_extras.rb +21 -44
- data/test/test_ruby_parser.rb +83 -5
- metadata +7 -7
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
=== 3.0.0.a4 / 2012-07-26
|
2
|
+
|
3
|
+
* 10 minor enhancements:
|
4
|
+
|
5
|
+
* 'rake debug' defaults to 1.9 parser since that's all I'm doing these days
|
6
|
+
* 1.9: Fixed f { |(a, b, ...), ...| ... } handling.
|
7
|
+
* Added 'rake extract F=path' task to quickly extract errors from large files
|
8
|
+
* Added on_error handler to provide more readable error message.
|
9
|
+
* Aliased #process to #parse.
|
10
|
+
* Renamed #parse to #process (legacy name), added default path of '(string)'
|
11
|
+
* cleaned ruby_parse_extract_error output and fixed to 1.9 parser
|
12
|
+
* ruby_parse_extract_error expands shell globs from ARGV
|
13
|
+
* ruby_parse_extract_error should also capture RuntimeError
|
14
|
+
* yyerror(msg) now warns with the message instead of ignoring it.
|
15
|
+
|
16
|
+
* 3 bug fixes:
|
17
|
+
|
18
|
+
* 1.9: Fixed bug lexing/parsing [ in rhs.
|
19
|
+
* 1.9: Fixed f { |((a, b), c)| ... } handling
|
20
|
+
* 1.9: fixed newline handling during expr_value
|
21
|
+
|
1
22
|
=== 3.0.0.a3 / 2012-07-03
|
2
23
|
|
3
24
|
* 1 major enhancement:
|
data/Rakefile
CHANGED
@@ -139,7 +139,7 @@ task :compare19 do
|
|
139
139
|
end
|
140
140
|
|
141
141
|
task :debug => :isolate do
|
142
|
-
ENV["V"] ||= "
|
142
|
+
ENV["V"] ||= "19"
|
143
143
|
Rake.application[:parser].invoke # this way we can have DEBUG set
|
144
144
|
|
145
145
|
$: << "lib"
|
@@ -171,4 +171,13 @@ task :debug => :isolate do
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
+
task :extract => :isolate do
|
175
|
+
ENV["V"] ||= "19"
|
176
|
+
Rake.application[:parser].invoke # this way we can have DEBUG set
|
177
|
+
|
178
|
+
file = ENV["F"] || ENV["FILE"]
|
179
|
+
|
180
|
+
ruby "-Ilib", "bin/ruby_parse_extract_error", file
|
181
|
+
end
|
182
|
+
|
174
183
|
# vim: syntax=Ruby
|
@@ -26,7 +26,7 @@ class Racc::Parser
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def retest_for_errors defs
|
29
|
-
|
29
|
+
warn "# retest: #{defs.size}"
|
30
30
|
|
31
31
|
parser = self.class.new
|
32
32
|
|
@@ -37,12 +37,14 @@ end
|
|
37
37
|
ARGV.replace ARGV.map { |path|
|
38
38
|
if File.directory? path then
|
39
39
|
Dir.glob File.join path, "**/*.rb"
|
40
|
+
elsif path =~ /\*\*/ then
|
41
|
+
Dir.glob path
|
40
42
|
else
|
41
43
|
path
|
42
44
|
end
|
43
45
|
}.flatten
|
44
46
|
|
45
|
-
parser =
|
47
|
+
parser = Ruby19Parser.new
|
46
48
|
|
47
49
|
ARGV.each do |file|
|
48
50
|
ruby = file == "-" ? $stdin.read : File.read(file)
|
@@ -51,8 +53,8 @@ ARGV.each do |file|
|
|
51
53
|
$stderr.print "Validating #{file}: "
|
52
54
|
parser.process(ruby, file)
|
53
55
|
$stderr.puts "good"
|
54
|
-
rescue Racc::ParseError => e
|
55
|
-
$stderr.puts "error: #{e.
|
56
|
+
rescue RuntimeError, Racc::ParseError => e
|
57
|
+
$stderr.puts "error: #{e.message.strip}"
|
56
58
|
$stderr.puts
|
57
59
|
|
58
60
|
defs = parser.extract_defs
|
data/lib/ruby19_parser.rb
CHANGED
@@ -4858,31 +4858,31 @@ def _reduce_353(val, _values, result)
|
|
4858
4858
|
end
|
4859
4859
|
|
4860
4860
|
def _reduce_354(val, _values, result)
|
4861
|
-
|
4861
|
+
result = assignable val[0]
|
4862
4862
|
|
4863
4863
|
result
|
4864
4864
|
end
|
4865
4865
|
|
4866
4866
|
def _reduce_355(val, _values, result)
|
4867
|
-
|
4867
|
+
result = val[1]
|
4868
4868
|
|
4869
4869
|
result
|
4870
4870
|
end
|
4871
4871
|
|
4872
4872
|
def _reduce_356(val, _values, result)
|
4873
|
-
|
4873
|
+
result = s(:array, val[0])
|
4874
4874
|
|
4875
4875
|
result
|
4876
4876
|
end
|
4877
4877
|
|
4878
4878
|
def _reduce_357(val, _values, result)
|
4879
|
-
|
4879
|
+
result = list_append val[0], val[2]
|
4880
4880
|
|
4881
4881
|
result
|
4882
4882
|
end
|
4883
4883
|
|
4884
4884
|
def _reduce_358(val, _values, result)
|
4885
|
-
|
4885
|
+
result = block_var val[0], nil, nil
|
4886
4886
|
|
4887
4887
|
result
|
4888
4888
|
end
|
@@ -5840,7 +5840,7 @@ def _reduce_523(val, _values, result)
|
|
5840
5840
|
identifier = val[0].to_sym
|
5841
5841
|
self.env[identifier] = :lvar
|
5842
5842
|
|
5843
|
-
result =
|
5843
|
+
result = identifier
|
5844
5844
|
|
5845
5845
|
result
|
5846
5846
|
end
|
@@ -5848,14 +5848,21 @@ end
|
|
5848
5848
|
# reduce 524 omitted
|
5849
5849
|
|
5850
5850
|
def _reduce_525(val, _values, result)
|
5851
|
-
|
5851
|
+
result = val[1]
|
5852
5852
|
|
5853
5853
|
result
|
5854
5854
|
end
|
5855
5855
|
|
5856
5856
|
def _reduce_526(val, _values, result)
|
5857
|
-
|
5858
|
-
|
5857
|
+
case val[0]
|
5858
|
+
when Symbol then
|
5859
|
+
result = s(:args)
|
5860
|
+
result << val[0].to_sym
|
5861
|
+
when Sexp then
|
5862
|
+
result = val[0]
|
5863
|
+
else
|
5864
|
+
raise "Unknown f_arg type: #{val.inspect}"
|
5865
|
+
end
|
5859
5866
|
|
5860
5867
|
result
|
5861
5868
|
end
|
data/lib/ruby19_parser.y
CHANGED
@@ -1191,25 +1191,25 @@ rule
|
|
1191
1191
|
|
1192
1192
|
f_marg: f_norm_arg
|
1193
1193
|
{
|
1194
|
-
|
1194
|
+
result = assignable val[0]
|
1195
1195
|
}
|
1196
1196
|
| tLPAREN f_margs rparen
|
1197
1197
|
{
|
1198
|
-
|
1198
|
+
result = val[1]
|
1199
1199
|
}
|
1200
1200
|
|
1201
1201
|
f_marg_list: f_marg
|
1202
1202
|
{
|
1203
|
-
|
1203
|
+
result = s(:array, val[0])
|
1204
1204
|
}
|
1205
1205
|
| f_marg_list tCOMMA f_marg
|
1206
1206
|
{
|
1207
|
-
|
1207
|
+
result = list_append val[0], val[2]
|
1208
1208
|
}
|
1209
1209
|
|
1210
1210
|
f_margs: f_marg_list
|
1211
1211
|
{
|
1212
|
-
|
1212
|
+
result = block_var val[0], nil, nil
|
1213
1213
|
}
|
1214
1214
|
| f_marg_list tCOMMA tSTAR f_norm_arg
|
1215
1215
|
{
|
@@ -1883,19 +1883,29 @@ keyword_variable: kNIL { result = s(:nil) }
|
|
1883
1883
|
identifier = val[0].to_sym
|
1884
1884
|
self.env[identifier] = :lvar
|
1885
1885
|
|
1886
|
-
result =
|
1886
|
+
result = identifier
|
1887
1887
|
}
|
1888
1888
|
|
1889
1889
|
f_arg_item: f_norm_arg
|
1890
|
+
# { # TODO
|
1891
|
+
# result = assignable val[0]
|
1892
|
+
# }
|
1890
1893
|
| tLPAREN f_margs rparen
|
1891
1894
|
{
|
1892
|
-
|
1895
|
+
result = val[1]
|
1893
1896
|
}
|
1894
1897
|
|
1895
1898
|
f_arg: f_arg_item
|
1896
1899
|
{
|
1897
|
-
|
1898
|
-
|
1900
|
+
case val[0]
|
1901
|
+
when Symbol then
|
1902
|
+
result = s(:args)
|
1903
|
+
result << val[0].to_sym
|
1904
|
+
when Sexp then
|
1905
|
+
result = val[0]
|
1906
|
+
else
|
1907
|
+
raise "Unknown f_arg type: #{val.inspect}"
|
1908
|
+
end
|
1899
1909
|
}
|
1900
1910
|
| f_arg tCOMMA f_arg_item
|
1901
1911
|
{
|
data/lib/ruby_lexer.rb
CHANGED
@@ -666,6 +666,8 @@ class RubyLexer
|
|
666
666
|
self.lineno = nil
|
667
667
|
c = src.matched
|
668
668
|
if c == '#' then
|
669
|
+
# TODO: add magic comment handling?
|
670
|
+
|
669
671
|
src.pos -= 1
|
670
672
|
|
671
673
|
while src.scan(/\s*#.*(\n+|\z)/) do
|
@@ -681,7 +683,7 @@ class RubyLexer
|
|
681
683
|
src.scan(/\n+/)
|
682
684
|
|
683
685
|
if [:expr_beg, :expr_fname,
|
684
|
-
:expr_dot, :expr_class].include? lex_state then
|
686
|
+
:expr_dot, :expr_class, :expr_value].include? lex_state then
|
685
687
|
next
|
686
688
|
end
|
687
689
|
|
@@ -807,7 +809,7 @@ class RubyLexer
|
|
807
809
|
else
|
808
810
|
rb_compile_error "unexpected '['"
|
809
811
|
end
|
810
|
-
elsif
|
812
|
+
elsif is_beg? then
|
811
813
|
self.tern.push false
|
812
814
|
result = :tLBRACK
|
813
815
|
elsif lex_state.is_argument && space_seen then
|
data/lib/ruby_parser_extras.rb
CHANGED
@@ -75,48 +75,10 @@ class RPStringScanner < StringScanner
|
|
75
75
|
s
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
79
|
-
# TODO:
|
80
|
-
# def last_line(src)
|
81
|
-
# if n = src.rindex("\n")
|
82
|
-
# src[(n+1) .. -1]
|
83
|
-
# else
|
84
|
-
# src
|
85
|
-
# end
|
86
|
-
# end
|
87
|
-
# private :last_line
|
88
|
-
|
89
|
-
# def next_words_on_error
|
90
|
-
# if n = @src.rest.index("\n")
|
91
|
-
# @src.rest[0 .. (n-1)]
|
92
|
-
# else
|
93
|
-
# @src.rest
|
94
|
-
# end
|
95
|
-
# end
|
96
|
-
|
97
|
-
# def prev_words_on_error(ev)
|
98
|
-
# pre = @pre
|
99
|
-
# if ev and /#{Regexp.quote(ev)}$/ =~ pre
|
100
|
-
# pre = $`
|
101
|
-
# end
|
102
|
-
# last_line(pre)
|
103
|
-
# end
|
104
|
-
|
105
|
-
# def on_error(et, ev, values)
|
106
|
-
# lines_of_rest = @src.rest.to_a.length
|
107
|
-
# prev_words = prev_words_on_error(ev)
|
108
|
-
# at = 4 + prev_words.length
|
109
|
-
# message = <<-MSG
|
110
|
-
# RD syntax error: line #{@blockp.line_index - lines_of_rest}:
|
111
|
-
# ...#{prev_words} #{(ev||'')} #{next_words_on_error()} ...
|
112
|
-
# MSG
|
113
|
-
# message << " " * at + "^" * (ev ? ev.length : 0) + "\n"
|
114
|
-
# raise ParseError, message
|
115
|
-
# end
|
116
78
|
end
|
117
79
|
|
118
80
|
module RubyParserStuff
|
119
|
-
VERSION = '3.0.0.
|
81
|
+
VERSION = '3.0.0.a4' unless constants.include? "VERSION" # SIGH
|
120
82
|
|
121
83
|
attr_accessor :lexer, :in_def, :in_single, :file
|
122
84
|
attr_reader :env, :comments
|
@@ -207,6 +169,8 @@ module RubyParserStuff
|
|
207
169
|
raise "wtf? #{val.inspect}" unless lasgn[0] == :lasgn
|
208
170
|
result << lasgn[1]
|
209
171
|
end
|
172
|
+
when :lasgn then
|
173
|
+
result << val
|
210
174
|
else
|
211
175
|
raise "unhandled sexp: #{val.inspect}"
|
212
176
|
end
|
@@ -240,6 +204,8 @@ module RubyParserStuff
|
|
240
204
|
r.concat v[1..-1].map { |s| s(:lasgn, s) }
|
241
205
|
when :block_arg then
|
242
206
|
r << s(:lasgn, :"&#{v.last}")
|
207
|
+
when :masgn then
|
208
|
+
r << v
|
243
209
|
else
|
244
210
|
raise "block_args19 #{id} unhandled sexp type:: #{v.inspect}"
|
245
211
|
end
|
@@ -263,7 +229,7 @@ module RubyParserStuff
|
|
263
229
|
case r.last.first
|
264
230
|
when :splat then
|
265
231
|
r = s(:masgn, r)
|
266
|
-
when :lasgn then
|
232
|
+
when :lasgn, :masgn then
|
267
233
|
r = r.last
|
268
234
|
else
|
269
235
|
raise "oh noes!: #{r.inspect}"
|
@@ -995,8 +961,17 @@ module RubyParserStuff
|
|
995
961
|
end
|
996
962
|
|
997
963
|
def yyerror msg
|
998
|
-
|
964
|
+
warn msg
|
965
|
+
super()
|
966
|
+
end
|
967
|
+
|
968
|
+
def on_error(et, ev, values)
|
999
969
|
super
|
970
|
+
rescue Racc::ParseError => e
|
971
|
+
# I don't like how the exception obscures the error message
|
972
|
+
msg = "# ERROR: %s:%p :: %s" % [self.file, lexer.lineno, e.message.strip]
|
973
|
+
warn msg
|
974
|
+
raise
|
1000
975
|
end
|
1001
976
|
|
1002
977
|
class Keyword
|
@@ -1215,11 +1190,13 @@ class RubyParser
|
|
1215
1190
|
@p19 = Ruby19Parser.new
|
1216
1191
|
end
|
1217
1192
|
|
1218
|
-
def
|
1219
|
-
|
1193
|
+
def process s, f = "(string)"
|
1194
|
+
Ruby19Parser.new.process s, f
|
1220
1195
|
rescue Racc::ParseError
|
1221
|
-
|
1196
|
+
Ruby18Parser.new.process s, f
|
1222
1197
|
end
|
1198
|
+
|
1199
|
+
alias :parse :process
|
1223
1200
|
end
|
1224
1201
|
|
1225
1202
|
############################################################
|
data/test/test_ruby_parser.rb
CHANGED
@@ -33,10 +33,16 @@ class RubyParserTestCase < ParseTreeTestCase
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def assert_parse_error rb, emsg
|
36
|
-
e =
|
37
|
-
|
36
|
+
e = nil
|
37
|
+
out, err = capture_io do
|
38
|
+
e = assert_raises Racc::ParseError do
|
39
|
+
processor.parse rb
|
40
|
+
end
|
38
41
|
end
|
39
42
|
|
43
|
+
assert_equal "", out
|
44
|
+
assert_match(/parse error on value/, err)
|
45
|
+
|
40
46
|
assert_equal emsg, e.message.strip # TODO: why strip?
|
41
47
|
end
|
42
48
|
|
@@ -47,6 +53,11 @@ class RubyParserTestCase < ParseTreeTestCase
|
|
47
53
|
end
|
48
54
|
|
49
55
|
module TestRubyParserShared
|
56
|
+
def setup
|
57
|
+
super
|
58
|
+
# p :test => [self.class, __name__]
|
59
|
+
end
|
60
|
+
|
50
61
|
def test_attrasgn_array_lhs
|
51
62
|
rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'
|
52
63
|
pt = s(:attrasgn,
|
@@ -613,6 +624,67 @@ module TestRubyParserShared
|
|
613
624
|
assert_equal 3, result.if.return.line
|
614
625
|
assert_equal 3, result.if.return.lit.line
|
615
626
|
end
|
627
|
+
|
628
|
+
def test_bug_and
|
629
|
+
rb = "true and []"
|
630
|
+
pt = s(:and, s(:true), s(:array))
|
631
|
+
|
632
|
+
assert_parse rb, pt
|
633
|
+
|
634
|
+
rb = "true and\ntrue"
|
635
|
+
pt = s(:and, s(:true), s(:true))
|
636
|
+
|
637
|
+
assert_parse rb, pt
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_bug_args
|
641
|
+
rb = "f { |(a, b)| d }"
|
642
|
+
pt = s(:iter, s(:call, nil, :f),
|
643
|
+
s(:masgn, s(:array, s(:lasgn, :a), s(:lasgn, :b))),
|
644
|
+
s(:call, nil, :d))
|
645
|
+
|
646
|
+
assert_parse rb, pt
|
647
|
+
end
|
648
|
+
|
649
|
+
def test_bug_args_masgn
|
650
|
+
rb = "f { |((a, b), c)| }"
|
651
|
+
pt = s(:iter,
|
652
|
+
s(:call, nil, :f),
|
653
|
+
s(:masgn,
|
654
|
+
s(:array,
|
655
|
+
s(:masgn, s(:array, s(:lasgn, :a), s(:lasgn, :b))),
|
656
|
+
s(:lasgn, :c))))
|
657
|
+
|
658
|
+
assert_parse rb, pt
|
659
|
+
end
|
660
|
+
|
661
|
+
# TODO:
|
662
|
+
# def test_bug_args_masgn2
|
663
|
+
# rb = "f { |((a, b), c), d| }"
|
664
|
+
# pt = s(:iter,
|
665
|
+
# s(:call, nil, :f),
|
666
|
+
# s(:masgn,
|
667
|
+
# s(:array,
|
668
|
+
# s(:masgn,
|
669
|
+
# s(:array,
|
670
|
+
# s(:masgn,
|
671
|
+
# s(:array, s(:lasgn, :a), s(:lasgn, :b))),
|
672
|
+
# s(:lasgn, :c))),
|
673
|
+
# s(:lasgn, :d))))
|
674
|
+
#
|
675
|
+
# assert_parse rb, pt
|
676
|
+
# end
|
677
|
+
|
678
|
+
# TODO:
|
679
|
+
# def test_bug_comma
|
680
|
+
# rb = "if test ?d, dir then end"
|
681
|
+
# pt = s(:if,
|
682
|
+
# s(:call, nil, :test, s(:lit, 100), s(:call, nil, :dir)),
|
683
|
+
# nil,
|
684
|
+
# nil)
|
685
|
+
#
|
686
|
+
# assert_parse rb, pt
|
687
|
+
# end
|
616
688
|
end
|
617
689
|
|
618
690
|
class TestRubyParser < MiniTest::Unit::TestCase
|
@@ -623,7 +695,12 @@ class TestRubyParser < MiniTest::Unit::TestCase
|
|
623
695
|
rb = "while false : 42 end"
|
624
696
|
pt = s(:while, s(:false), s(:lit, 42), true)
|
625
697
|
|
626
|
-
|
698
|
+
out, err = capture_io do
|
699
|
+
assert_equal pt, processor.parse(rb)
|
700
|
+
end
|
701
|
+
|
702
|
+
assert_empty out
|
703
|
+
assert_match(/parse error on value .:/, err)
|
627
704
|
|
628
705
|
# 1.9 only syntax
|
629
706
|
rb = "a.()"
|
@@ -633,7 +710,9 @@ class TestRubyParser < MiniTest::Unit::TestCase
|
|
633
710
|
|
634
711
|
# bad syntax
|
635
712
|
e = assert_raises Racc::ParseError do
|
636
|
-
|
713
|
+
capture_io do
|
714
|
+
processor.parse "a.("
|
715
|
+
end
|
637
716
|
end
|
638
717
|
|
639
718
|
msg = "parse error on value \"(\" (tLPAREN2)"
|
@@ -977,4 +1056,3 @@ class TestRuby19Parser < RubyParserTestCase
|
|
977
1056
|
# assert_parse rb, pt
|
978
1057
|
# end
|
979
1058
|
end
|
980
|
-
|
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: 1314497749
|
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
|
+
- 4
|
12
|
+
version: 3.0.0.a4
|
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-07-
|
41
|
+
date: 2012-07-26 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: 3
|
67
67
|
segments:
|
68
68
|
- 3
|
69
|
-
-
|
70
|
-
version: "3.
|
69
|
+
- 2
|
70
|
+
version: "3.2"
|
71
71
|
type: :development
|
72
72
|
version_requirements: *id002
|
73
73
|
- !ruby/object:Gem::Dependency
|
metadata.gz.sig
CHANGED
Binary file
|