ruby_parser 2.0.1 → 2.0.2
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/Manifest.txt +1 -0
- data/README.txt +32 -10
- data/Rakefile +1 -1
- data/lib/gauntlet_rubyparser.rb +120 -0
- data/lib/ruby_lexer.rb +2 -3
- data/lib/ruby_parser.rb +2 -2
- data/lib/ruby_parser.y +1 -1
- data/lib/ruby_parser_extras.rb +9 -34
- data/test/test_ruby_parser.rb +22 -24
- metadata +7 -6
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 2.0.2 / 2009-01-20
|
2
|
+
|
3
|
+
* 2 minor enhancements:
|
4
|
+
|
5
|
+
* Added gauntlet_rubyparser plugin. YAY for easy massive bug-hunting.
|
6
|
+
* Promoted Sexp's file/line/comments to sexp_processor.
|
7
|
+
|
8
|
+
* 4 bug fixes:
|
9
|
+
|
10
|
+
* Fixed and improved the readme
|
11
|
+
* Fixed lexing heredoc newlines.
|
12
|
+
* Fixed line numbers on defns.
|
13
|
+
* Fixed rdoc generation bug pointed out by hugh sasse (who rocks)
|
14
|
+
|
1
15
|
=== 2.0.1 / 2008-11-04
|
2
16
|
|
3
17
|
* 2 minor enhancements:
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
ruby_parser
|
2
|
-
|
3
|
-
|
1
|
+
= ruby_parser
|
2
|
+
|
3
|
+
* http://parsetree.rubyforge.org/
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
@@ -9,6 +9,27 @@ racc--which does by default use a C extension). RP's output is
|
|
9
9
|
the same as ParseTree's output: s-expressions using ruby's arrays and
|
10
10
|
base types.
|
11
11
|
|
12
|
+
As an example:
|
13
|
+
|
14
|
+
def conditional1(arg1)
|
15
|
+
if arg1 == 0 then
|
16
|
+
return 1
|
17
|
+
end
|
18
|
+
return 0
|
19
|
+
end
|
20
|
+
|
21
|
+
becomes:
|
22
|
+
|
23
|
+
s(:defn, :conditional1,
|
24
|
+
s(:args, :arg1),
|
25
|
+
s(:scope,
|
26
|
+
s(:block,
|
27
|
+
s(:if,
|
28
|
+
s(:call, s(:lvar, :arg1), :==, s(:arglist, s(:lit, 0))),
|
29
|
+
s(:return, s(:lit, 1)),
|
30
|
+
nil),
|
31
|
+
s(:return, s(:lit, 0)))))
|
32
|
+
|
12
33
|
== FEATURES/PROBLEMS:
|
13
34
|
|
14
35
|
* Pure ruby, no compiles.
|
@@ -16,11 +37,12 @@ base types.
|
|
16
37
|
* Incredibly simple interface.
|
17
38
|
* Output is 100% equivalent to ParseTree.
|
18
39
|
* Can utilize PT's SexpProcessor and UnifiedRuby for language processing.
|
19
|
-
* Known Issue: Speed
|
20
|
-
*
|
21
|
-
*
|
40
|
+
* Known Issue: Speed is now pretty good, but can always improve:
|
41
|
+
* RP parses a corpus of 3702 files in 125s (avg 108 Kb/s)
|
42
|
+
* MRI+PT parsed the same in 67.38s (avg 200.89 Kb/s)
|
43
|
+
* Known Issue: Code is much better, but still has a long way to go.
|
22
44
|
* Known Issue: Totally awesome.
|
23
|
-
* Known Issue:
|
45
|
+
* Known Issue: line number values can be slightly off. Parsing LR sucks.
|
24
46
|
|
25
47
|
== SYNOPSIS:
|
26
48
|
|
@@ -30,9 +52,9 @@ base types.
|
|
30
52
|
== REQUIREMENTS:
|
31
53
|
|
32
54
|
* ruby. woot.
|
33
|
-
*
|
55
|
+
* sexp_processor for Sexp and SexpProcessor classes.
|
34
56
|
* ParseTree for testing.
|
35
|
-
* racc full package for parser development.
|
57
|
+
* racc full package for parser development (compiling .y to .rb).
|
36
58
|
|
37
59
|
== INSTALL:
|
38
60
|
|
@@ -42,7 +64,7 @@ base types.
|
|
42
64
|
|
43
65
|
(The MIT License)
|
44
66
|
|
45
|
-
Copyright (c) 2007 Ryan Davis
|
67
|
+
Copyright (c) 2007-2008 Ryan Davis
|
46
68
|
|
47
69
|
Permission is hereby granted, free of charge, to any person obtaining
|
48
70
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ hoe = Hoe.new('ruby_parser', RubyParser::VERSION) do |parser|
|
|
15
15
|
parser.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
|
16
16
|
|
17
17
|
parser.extra_dev_deps << 'ParseTree'
|
18
|
-
parser.extra_deps << ['sexp_processor', '>= 3.0.
|
18
|
+
parser.extra_deps << ['sexp_processor', '>= 3.0.1']
|
19
19
|
end
|
20
20
|
|
21
21
|
hoe.spec.files += ['lib/ruby_parser.rb'] # jim.... cmon man
|
@@ -0,0 +1,120 @@
|
|
1
|
+
#!/usr/bin/ruby -ws
|
2
|
+
|
3
|
+
$f ||= false
|
4
|
+
|
5
|
+
$:.unshift "../../ruby_parser/dev/lib"
|
6
|
+
$:.unshift "../../ruby2ruby/dev/lib"
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'ruby2ruby'
|
10
|
+
require 'ruby_parser'
|
11
|
+
|
12
|
+
require 'gauntlet'
|
13
|
+
|
14
|
+
class RubyParserGauntlet < Gauntlet
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
|
18
|
+
self.data = Hash.new { |h,k| h[k] = {} }
|
19
|
+
old_data = load_yaml data_file
|
20
|
+
self.data.merge! old_data
|
21
|
+
end
|
22
|
+
|
23
|
+
def should_skip? name
|
24
|
+
if $f then
|
25
|
+
if Hash === data[name] then
|
26
|
+
! data[name].empty?
|
27
|
+
else
|
28
|
+
data[name]
|
29
|
+
end
|
30
|
+
else
|
31
|
+
data[name] == true # yes, == true on purpose
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def diff_pp o1, o2
|
36
|
+
require 'pp'
|
37
|
+
|
38
|
+
File.open("/tmp/a.#{$$}", "w") do |f|
|
39
|
+
PP.pp o1, f
|
40
|
+
end
|
41
|
+
|
42
|
+
File.open("/tmp/b.#{$$}", "w") do |f|
|
43
|
+
PP.pp o2, f
|
44
|
+
end
|
45
|
+
|
46
|
+
`diff -u /tmp/a.#{$$} /tmp/b.#{$$}`
|
47
|
+
ensure
|
48
|
+
File.unlink "/tmp/a.#{$$}" rescue nil
|
49
|
+
File.unlink "/tmp/b.#{$$}" rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def broke name, file, msg
|
53
|
+
warn "bad"
|
54
|
+
self.data[name][file] = msg
|
55
|
+
self.dirty = true
|
56
|
+
end
|
57
|
+
|
58
|
+
def process path, name
|
59
|
+
begin
|
60
|
+
$stderr.print " #{path}: "
|
61
|
+
rp = RubyParser.new
|
62
|
+
r2r = Ruby2Ruby.new
|
63
|
+
|
64
|
+
old_ruby = File.read(path)
|
65
|
+
|
66
|
+
begin
|
67
|
+
old_sexp = rp.process old_ruby
|
68
|
+
rescue Racc::ParseError => e
|
69
|
+
self.data[name][path] = :unparsable
|
70
|
+
self.dirty = true
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
74
|
+
new_ruby = r2r.process old_sexp.deep_clone
|
75
|
+
|
76
|
+
begin
|
77
|
+
new_sexp = rp.process new_ruby
|
78
|
+
rescue Racc::ParseError => e
|
79
|
+
broke name, path, "couldn't parse new_ruby: #{e.message.strip}"
|
80
|
+
return
|
81
|
+
end
|
82
|
+
|
83
|
+
if old_sexp != new_sexp then
|
84
|
+
broke name, path, diff_pp(old_sexp, new_sexp)
|
85
|
+
return
|
86
|
+
end
|
87
|
+
|
88
|
+
self.data[name][path] = true
|
89
|
+
self.dirty = true
|
90
|
+
|
91
|
+
warn "good"
|
92
|
+
rescue Interrupt
|
93
|
+
puts "User cancelled"
|
94
|
+
exit 1
|
95
|
+
rescue Exception => e
|
96
|
+
broke name, path, " UNKNOWN ERROR: #{e}: #{e.message.strip}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def run name
|
101
|
+
warn name
|
102
|
+
Dir["**/*.rb"].sort.each do |path|
|
103
|
+
next if path =~ /gemspec.rb/ # HACK
|
104
|
+
next if data[name][path] == true
|
105
|
+
process path, name
|
106
|
+
end
|
107
|
+
|
108
|
+
if self.data[name].values.all? { |v| v == true } then
|
109
|
+
warn " ALL GOOD!"
|
110
|
+
self.data[name] = true
|
111
|
+
self.dirty = true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
filter = ARGV.shift
|
117
|
+
filter = Regexp.new filter if filter
|
118
|
+
|
119
|
+
gauntlet = RubyParserGauntlet.new
|
120
|
+
gauntlet.run_the_gauntlet filter
|
data/lib/ruby_lexer.rb
CHANGED
@@ -188,7 +188,8 @@ class RubyLexer
|
|
188
188
|
if src.check(/.*\n/) then
|
189
189
|
# TODO: think about storing off the char range instead
|
190
190
|
line = src.string[src.pos, src.matched_size]
|
191
|
-
src.string[src.pos, src.matched_size] =
|
191
|
+
src.string[src.pos, src.matched_size] = "\n"
|
192
|
+
src.pos += 1
|
192
193
|
else
|
193
194
|
line = nil
|
194
195
|
end
|
@@ -651,7 +652,6 @@ class RubyLexer
|
|
651
652
|
if src.eos? then
|
652
653
|
return RubyLexer::EOF
|
653
654
|
end
|
654
|
-
else
|
655
655
|
end
|
656
656
|
|
657
657
|
# Replace a string of newlines with a single one
|
@@ -662,7 +662,6 @@ class RubyLexer
|
|
662
662
|
next
|
663
663
|
end
|
664
664
|
|
665
|
-
|
666
665
|
self.command_start = true
|
667
666
|
self.lex_state = :expr_beg
|
668
667
|
return :tNL
|
data/lib/ruby_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.6
|
4
4
|
# from Racc grammer file "".
|
5
5
|
#
|
6
6
|
|
@@ -4564,7 +4564,7 @@ def _reduce_317(val, _values, result)
|
|
4564
4564
|
self.comments.push self.lexer.comments
|
4565
4565
|
self.in_def = true
|
4566
4566
|
self.env.extend
|
4567
|
-
result =
|
4567
|
+
result = lexer.lineno, lexer.src.beginning_of_line?
|
4568
4568
|
|
4569
4569
|
result
|
4570
4570
|
end
|
data/lib/ruby_parser.y
CHANGED
data/lib/ruby_parser_extras.rb
CHANGED
@@ -113,7 +113,7 @@ class RPStringScanner < StringScanner
|
|
113
113
|
end
|
114
114
|
|
115
115
|
class RubyParser < Racc::Parser
|
116
|
-
VERSION = '2.0.
|
116
|
+
VERSION = '2.0.2'
|
117
117
|
|
118
118
|
attr_accessor :lexer, :in_def, :in_single, :file
|
119
119
|
attr_reader :env, :comments
|
@@ -502,7 +502,7 @@ class RubyParser < Racc::Parser
|
|
502
502
|
end
|
503
503
|
|
504
504
|
def new_defn val
|
505
|
-
line, name, args, body = val[2], val[1], val[3], val[4]
|
505
|
+
(line, bol), name, args, body = val[2], val[1], val[3], val[4]
|
506
506
|
body ||= s(:nil)
|
507
507
|
|
508
508
|
body ||= s(:block)
|
@@ -510,6 +510,7 @@ class RubyParser < Racc::Parser
|
|
510
510
|
|
511
511
|
result = s(:defn, name.to_sym, args, s(:scope, body))
|
512
512
|
result.line = line
|
513
|
+
result.line -= 1 if bol
|
513
514
|
result.comments = self.comments.pop
|
514
515
|
result
|
515
516
|
end
|
@@ -827,6 +828,8 @@ class Keyword
|
|
827
828
|
end
|
828
829
|
|
829
830
|
##
|
831
|
+
# :stopdoc:
|
832
|
+
#
|
830
833
|
# :expr_beg = ignore newline, +/- is a sign.
|
831
834
|
# :expr_end = newline significant, +/- is a operator.
|
832
835
|
# :expr_arg = newline significant, +/- is a operator.
|
@@ -880,6 +883,8 @@ class Keyword
|
|
880
883
|
["alias", [:kALIAS, :kALIAS ], :expr_fname ],
|
881
884
|
].map { |args| KWtable.new(*args) }
|
882
885
|
|
886
|
+
# :startdoc:
|
887
|
+
|
883
888
|
WORDLIST = Hash[*wordlist.map { |o| [o.name, o] }.flatten]
|
884
889
|
|
885
890
|
def self.keyword str
|
@@ -1004,25 +1009,6 @@ end
|
|
1004
1009
|
|
1005
1010
|
class Sexp
|
1006
1011
|
attr_writer :paren
|
1007
|
-
attr_accessor :comments
|
1008
|
-
attr_accessor :file
|
1009
|
-
|
1010
|
-
def line(n=nil)
|
1011
|
-
if n then
|
1012
|
-
@line = n
|
1013
|
-
self
|
1014
|
-
else
|
1015
|
-
@line ||= nil
|
1016
|
-
end
|
1017
|
-
end
|
1018
|
-
|
1019
|
-
def line= n
|
1020
|
-
@line = n
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
def node_type
|
1024
|
-
first
|
1025
|
-
end
|
1026
1012
|
|
1027
1013
|
def paren
|
1028
1014
|
@paren ||= false
|
@@ -1037,19 +1023,8 @@ class Sexp
|
|
1037
1023
|
self.value.to_sym
|
1038
1024
|
end
|
1039
1025
|
|
1040
|
-
|
1041
|
-
|
1042
|
-
end
|
1043
|
-
|
1044
|
-
alias :real_inspect :inspect
|
1045
|
-
def inspect # :nodoc:
|
1046
|
-
sexp_str = self.map {|x|x.inspect}.join(', ')
|
1047
|
-
if line && ENV['VERBOSE'] then
|
1048
|
-
"s(#{sexp_str}).line(#{line})"
|
1049
|
-
else
|
1050
|
-
"s(#{sexp_str})"
|
1051
|
-
end
|
1052
|
-
end
|
1026
|
+
alias :node_type :sexp_type
|
1027
|
+
alias :values :sexp_body # TODO: retire
|
1053
1028
|
end
|
1054
1029
|
|
1055
1030
|
# END HACK
|
data/test/test_ruby_parser.rb
CHANGED
@@ -374,6 +374,13 @@ class TestRubyParser < RubyParserTestCase
|
|
374
374
|
assert_equal pt, @processor.parse(rb)
|
375
375
|
end
|
376
376
|
|
377
|
+
# def test_str_pct_nested_nested
|
378
|
+
# rb = "%{ { #\{ \"#\{1}\" } } }"
|
379
|
+
# pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
|
380
|
+
|
381
|
+
# assert_equal pt, @processor.parse(rb)
|
382
|
+
# end
|
383
|
+
|
377
384
|
def test_str_str
|
378
385
|
rb = "\"a #\{'b'}\""
|
379
386
|
pt = s(:str, "a b")
|
@@ -389,30 +396,21 @@ class TestRubyParser < RubyParserTestCase
|
|
389
396
|
end
|
390
397
|
|
391
398
|
STARTING_LINE = {
|
392
|
-
"
|
393
|
-
"
|
394
|
-
"
|
395
|
-
"
|
396
|
-
"
|
397
|
-
"
|
398
|
-
"
|
399
|
-
"
|
400
|
-
"
|
401
|
-
"
|
402
|
-
"
|
403
|
-
"
|
404
|
-
"
|
405
|
-
"
|
406
|
-
"
|
407
|
-
"super_1" => 2,
|
408
|
-
"super_1_array" => 2,
|
409
|
-
"super_n" => 2,
|
410
|
-
"super_multi" => 2,
|
411
|
-
"undef_block_1" => 2,
|
412
|
-
"undef_block_2" => 2,
|
413
|
-
"undef_block_3" => 2,
|
414
|
-
"undef_block_wtf" => 2,
|
415
|
-
"zsuper" => 2,
|
399
|
+
"case_nested_inner_no_expr" => 2,
|
400
|
+
"case_no_expr" => 2,
|
401
|
+
"case_splat" => 2,
|
402
|
+
"dstr_heredoc_expand" => 2,
|
403
|
+
"dstr_heredoc_windoze_sucks" => 2,
|
404
|
+
"dstr_heredoc_yet_again" => 2,
|
405
|
+
"str_heredoc" => 2,
|
406
|
+
"str_heredoc_call" => 2,
|
407
|
+
"str_heredoc_empty" => 2,
|
408
|
+
"str_heredoc_indent" => 2,
|
409
|
+
"structure_unused_literal_wwtt" => 3, # yes, 3... odd test
|
410
|
+
"undef_block_1" => 2,
|
411
|
+
"undef_block_2" => 2,
|
412
|
+
"undef_block_3" => 2,
|
413
|
+
"undef_block_wtf" => 2,
|
416
414
|
}
|
417
415
|
|
418
416
|
def after_process_hook klass, node, data, input_name, output_name
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-01-20 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 3.0.
|
23
|
+
version: 3.0.1
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: ParseTree
|
@@ -40,9 +40,9 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.8.
|
43
|
+
version: 1.8.2
|
44
44
|
version:
|
45
|
-
description: "ruby_parser (RP) is a ruby parser written in pure ruby (utilizing racc--which does by default use a C extension). RP's output is the same as ParseTree's output: s-expressions using ruby's arrays and base types."
|
45
|
+
description: "ruby_parser (RP) is a ruby parser written in pure ruby (utilizing racc--which does by default use a C extension). RP's output is the same as ParseTree's output: s-expressions using ruby's arrays and base types. As an example: def conditional1(arg1) if arg1 == 0 then return 1 end return 0 end becomes: s(:defn, :conditional1, s(:args, :arg1), s(:scope, s(:block, s(:if, s(:call, s(:lvar, :arg1), :==, s(:arglist, s(:lit, 0))), s(:return, s(:lit, 1)), nil), s(:return, s(:lit, 0)))))"
|
46
46
|
email:
|
47
47
|
- ryand-ruby@zenspider.com
|
48
48
|
executables:
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- README.txt
|
61
61
|
- Rakefile
|
62
62
|
- bin/ruby_parse
|
63
|
+
- lib/gauntlet_rubyparser.rb
|
63
64
|
- lib/ruby_lexer.rb
|
64
65
|
- lib/ruby_parser.y
|
65
66
|
- lib/ruby_parser_extras.rb
|
@@ -68,7 +69,7 @@ files:
|
|
68
69
|
- test/test_ruby_parser_extras.rb
|
69
70
|
- lib/ruby_parser.rb
|
70
71
|
has_rdoc: true
|
71
|
-
homepage:
|
72
|
+
homepage: http://parsetree.rubyforge.org/
|
72
73
|
post_install_message:
|
73
74
|
rdoc_options:
|
74
75
|
- --main
|