ruby_parser 2.0.1 → 2.0.2
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/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
|