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 CHANGED
Binary file
@@ -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"] ||= "18"
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
- d :retest => defs.size
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 = RubyParser.new
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.description}"
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
@@ -4858,31 +4858,31 @@ def _reduce_353(val, _values, result)
4858
4858
  end
4859
4859
 
4860
4860
  def _reduce_354(val, _values, result)
4861
- raise "no4: #{val.inspect}"
4861
+ result = assignable val[0]
4862
4862
 
4863
4863
  result
4864
4864
  end
4865
4865
 
4866
4866
  def _reduce_355(val, _values, result)
4867
- raise "no5: #{val.inspect}"
4867
+ result = val[1]
4868
4868
 
4869
4869
  result
4870
4870
  end
4871
4871
 
4872
4872
  def _reduce_356(val, _values, result)
4873
- raise "no6: #{val.inspect}"
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
- raise "no7: #{val.inspect}"
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
- raise "no8: #{val.inspect}"
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 = val[0]
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
- raise "no19: #{val.inspect}"
5851
+ result = val[1]
5852
5852
 
5853
5853
  result
5854
5854
  end
5855
5855
 
5856
5856
  def _reduce_526(val, _values, result)
5857
- result = s(:args)
5858
- result << val[0].to_sym
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
@@ -1191,25 +1191,25 @@ rule
1191
1191
 
1192
1192
  f_marg: f_norm_arg
1193
1193
  {
1194
- raise "no4: #{val.inspect}"
1194
+ result = assignable val[0]
1195
1195
  }
1196
1196
  | tLPAREN f_margs rparen
1197
1197
  {
1198
- raise "no5: #{val.inspect}"
1198
+ result = val[1]
1199
1199
  }
1200
1200
 
1201
1201
  f_marg_list: f_marg
1202
1202
  {
1203
- raise "no6: #{val.inspect}"
1203
+ result = s(:array, val[0])
1204
1204
  }
1205
1205
  | f_marg_list tCOMMA f_marg
1206
1206
  {
1207
- raise "no7: #{val.inspect}"
1207
+ result = list_append val[0], val[2]
1208
1208
  }
1209
1209
 
1210
1210
  f_margs: f_marg_list
1211
1211
  {
1212
- raise "no8: #{val.inspect}"
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 = val[0]
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
- raise "no19: #{val.inspect}"
1895
+ result = val[1]
1893
1896
  }
1894
1897
 
1895
1898
  f_arg: f_arg_item
1896
1899
  {
1897
- result = s(:args)
1898
- result << val[0].to_sym
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
  {
@@ -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 lex_state == :expr_beg || lex_state == :expr_mid then
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
@@ -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.a3' unless constants.include? "VERSION" # SIGH
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
- # for now do nothing with the msg
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 parse s
1219
- @p19.parse s
1193
+ def process s, f = "(string)"
1194
+ Ruby19Parser.new.process s, f
1220
1195
  rescue Racc::ParseError
1221
- @p18.parse s
1196
+ Ruby18Parser.new.process s, f
1222
1197
  end
1198
+
1199
+ alias :parse :process
1223
1200
  end
1224
1201
 
1225
1202
  ############################################################
@@ -33,10 +33,16 @@ class RubyParserTestCase < ParseTreeTestCase
33
33
  end
34
34
 
35
35
  def assert_parse_error rb, emsg
36
- e = assert_raises Racc::ParseError do
37
- processor.parse rb
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
- assert_equal pt, processor.parse(rb)
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
- processor.parse "a.("
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: 2882648795
4
+ hash: 1314497749
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
9
  - 0
10
10
  - a
11
- - 3
12
- version: 3.0.0.a3
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-04 00:00:00 Z
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: 7
66
+ hash: 3
67
67
  segments:
68
68
  - 3
69
- - 0
70
- version: "3.0"
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