redparse 0.8.3 → 0.8.4

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.
@@ -0,0 +1,129 @@
1
+ require 'tempfile'
2
+ #require 'yaml'
3
+ #require 'marshal'
4
+
5
+ module ParseTreeComm
6
+ SERIALIZE=Marshal
7
+ def put o
8
+ o=SERIALIZE.dump o
9
+ msg= o.size.to_s+"\n"+o+"\n"
10
+ begin
11
+ @out.write msg
12
+ @out.flush
13
+ rescue Exception
14
+ @out=@in=nil
15
+ raise
16
+ end
17
+ end
18
+ def get
19
+ begin
20
+ len=@in.gets.to_i
21
+ msg=@in.read(len)
22
+ @in.getc #read trailing \n
23
+ rescue Exception
24
+ @in=@out=nil
25
+ raise
26
+ end
27
+ result=SERIALIZE.load msg
28
+ return result
29
+ end
30
+ end
31
+
32
+ class ParseTreeServer
33
+ include ParseTreeComm
34
+
35
+ def self.path_to_server_command
36
+ File.expand_path __FILE__
37
+ end
38
+
39
+ def ensure_parse_tree_and_1_8
40
+ if ::RUBY_VERSION[/^\d+\.\d+/].to_f>1.8
41
+ ruby18=ENV['RUBY1_8']||fail("you must use ruby <= 1.8 (with parse_tree) or set RUBY1_8 env to a 1.8 interpreter")
42
+ exec ruby18, $0
43
+ else
44
+ begin require 'rubygems'; rescue LoadError; end
45
+
46
+ if File.exist? find_home+"/.redparse/parse_tree_server.rc"
47
+ $:.concat File.readlines(find_home+"/.redparse/parse_tree_server.rc").map{|l| l.chop }
48
+ end
49
+
50
+ require 'parse_tree'
51
+ end
52
+ rescue Exception=>e
53
+ put e
54
+ put nil
55
+ put nil
56
+ raise
57
+ end
58
+
59
+ def main
60
+ si=STDIN
61
+ so=STDOUT
62
+ @out=so; @in=si
63
+ ensure_parse_tree_and_1_8
64
+ begin
65
+ warnstash=Tempfile.new "warnstash"
66
+ STDERR.reopen warnstash
67
+ instance=ParseTree.new
68
+ while true
69
+ str=get
70
+ exit! if str==:exit!
71
+ if str==:version
72
+ put ::RUBY_VERSION
73
+ next
74
+ end
75
+
76
+ pos=STDERR.pos
77
+
78
+ tree=
79
+ begin
80
+ instance.parse_tree_for_string(str) #tree
81
+ rescue Exception=>e;
82
+ tree=e
83
+ end
84
+ put tree
85
+
86
+ open(STDERR.path){|f|
87
+ f.pos=pos
88
+ put warnings=f.read.split #warnings
89
+ }
90
+ end
91
+ rescue Exception=>e; put e; raise
92
+ ensure exit!
93
+ end
94
+ end
95
+
96
+ ##
97
+ # Finds the user's home directory.
98
+ #--
99
+ # Some comments from the ruby-talk list regarding finding the home
100
+ # directory:
101
+ #
102
+ # I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
103
+ # to be depending on HOME in those code samples. I propose that
104
+ # it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
105
+ # least on Win32).
106
+ #(originally stolen from rubygems)
107
+ def find_home
108
+ ['HOME', 'USERPROFILE'].each do |homekey|
109
+ return ENV[homekey] if ENV[homekey]
110
+ end
111
+
112
+ if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
113
+ return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
114
+ end
115
+
116
+ begin
117
+ File.expand_path("~")
118
+ rescue
119
+ if File::ALT_SEPARATOR then
120
+ "C:/"
121
+ else
122
+ "/"
123
+ end
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ ParseTreeServer.new.main if $0==__FILE__
@@ -0,0 +1,43 @@
1
+ class RedParse
2
+ def self.remove_silly_begins(pt)
3
+ pt.each_with_index{|x,i|
4
+ if Array===x
5
+ remove_silly_begins(x)
6
+ if x.size==2 and x.first==:begin
7
+ pt[i]=x=x.last
8
+ end
9
+ end
10
+ }
11
+ end
12
+ end
13
+
14
+ __END__
15
+ begin require 'rubygems'
16
+ rescue LoadError; #do nothing
17
+ end
18
+
19
+ have_graphwalk=true
20
+ begin require 'ron/graphedge'
21
+ rescue LoadError;
22
+ warn 'Ron::GraphWalk not found; some tests will be too strict'
23
+ have_graphwalk=false
24
+ end
25
+
26
+ unless have_graphwalk
27
+ class RedParse
28
+ def self.remove_silly_begins(pt) pt end
29
+ end
30
+ else
31
+ class RedParse
32
+ def self.remove_silly_begins(pt)
33
+ munger=proc{|cntr,o,i,ty,useit|
34
+ if Array===o and o.size==2 and o.first==:begin
35
+ useit[0]=true
36
+ Ron::GraphWalk.graphcopy(o.last,&munger)
37
+ end
38
+ }
39
+ Ron::GraphWalk.graphcopy(pt,&munger)
40
+ end
41
+ end
42
+ end
43
+
@@ -20,7 +20,7 @@
20
20
  unless Array===(Class*5).subregs
21
21
  module ::Reg
22
22
  class Repeat
23
- undef subregs if instance_methods.include? "subregs"
23
+ undef subregs if allocate.respond_to? :subregs
24
24
  def subregs
25
25
  [@reg]
26
26
  end
@@ -29,7 +29,7 @@
29
29
  end
30
30
 
31
31
 
32
- unless defined? ::Reg::Transform and ::Reg::Transform.ancestors.include? ::Reg::HasCmatch
32
+ unless defined? ::Reg::Transform #and ::Reg::Transform.ancestors.include? ::Reg::HasBmatch
33
33
  #hack, until support for this syntax makes it into the release of reg
34
34
  module ::Reg
35
35
  class Transform;
@@ -46,7 +46,7 @@
46
46
  end
47
47
  end
48
48
 
49
- unless ::Reg::Reg.instance_methods.include? "lb"
49
+ unless Object.allocate.extend(::Reg::Reg).respond_to? :lb
50
50
  module ::Reg
51
51
  module Reg
52
52
  def lb
@@ -73,7 +73,7 @@
73
73
  end
74
74
  end
75
75
 
76
- unless ::Reg::Reg.instance_methods.include? "la"
76
+ unless Object.allocate.extend(::Reg::Reg).respond_to? :la
77
77
  module ::Reg
78
78
  module Reg
79
79
  def la
@@ -100,7 +100,7 @@
100
100
  end
101
101
  end
102
102
 
103
- unless ::Reg::Reg.instance_methods.include? "watch"
103
+ unless Object.allocate.extend(::Reg::Reg).respond_to? :watch
104
104
  module ::Reg
105
105
  module Reg
106
106
  def watch
@@ -1,3 +1,3 @@
1
1
  class RedParse
2
- VERSION='0.8.3'
2
+ VERSION='0.8.4'
3
3
  end
data/redparse.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "#{File.dirname(__FILE__)}/lib/redparse/version"
4
+ RedParse::Description=open("README.txt"){|f| f.read[/^==+ ?description[^\n]*?\n *\n?(.*?\n *\n.*?)\n *\n/im,1] }
5
+ RedParse::Latest_changes="###"+open("History.txt"){|f| f.read[/\A===(.*?)(?====)/m,1] }
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "redparse"
9
+ s.version = RedParse::VERSION
10
+ s.date = Time.now.strftime("%Y-%m-%d")
11
+ s.authors = ["Caleb Clausen"]
12
+ s.email = %q{caleb (at) inforadical (dot) net}
13
+ s.summary = "RedParse is a ruby parser written in pure ruby."
14
+ s.description = RedParse::Description
15
+ s.homepage = %{http://github.com/coatl/redparse}
16
+ s.rubyforge_project = %q{redparse}
17
+
18
+ s.files = `git ls-files`.split
19
+ s.test_files = %w[test/test_all.rb]
20
+ s.require_paths = ["lib"]
21
+ s.extra_rdoc_files = ["README.txt", "COPYING.LGPL"]
22
+ s.has_rdoc = true
23
+ s.rdoc_options = %w[--main README.txt]
24
+
25
+ s.rubygems_version = %q{1.3.0}
26
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
27
+
28
+ if s.respond_to? :specification_version then
29
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
30
+ s.specification_version = 2
31
+
32
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
33
+ s.add_runtime_dependency("rubylexer", '0.7.7')
34
+ s.add_runtime_dependency("reg", ['>= 0.4.8'])
35
+ else
36
+ s.add_dependency("rubylexer", '0.7.7')
37
+ s.add_dependency("reg", ['>= 0.4.8'])
38
+ end
39
+ else
40
+ s.add_dependency("rubylexer", '0.7.7')
41
+ s.add_dependency("reg", ['>= 0.4.8'])
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/ruby -Ke
2
+ okuri = "p" if can_postfix =~ /^��[��-��]/
3
+ okuri = "k" if can_postfix =~ /^��[��-��]/
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'parse_tree'
4
+
5
+ ##
6
+ # Finds the user's home directory.
7
+ #--
8
+ # Some comments from the ruby-talk list regarding finding the home
9
+ # directory:
10
+ #
11
+ # I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
12
+ # to be depending on HOME in those code samples. I propose that
13
+ # it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
14
+ # least on Win32).
15
+ #(originally stolen from rubygems)
16
+ def find_home
17
+ ['HOME', 'USERPROFILE'].each do |homekey|
18
+ return ENV[homekey] if ENV[homekey]
19
+ end
20
+
21
+ if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
22
+ return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
23
+ end
24
+
25
+ begin
26
+ File.expand_path("~")
27
+ rescue
28
+ if File::ALT_SEPARATOR then
29
+ "C:/"
30
+ else
31
+ "/"
32
+ end
33
+ end
34
+ end
35
+
36
+ PARSETREE_AND_DEPENDANCIES=
37
+ %r{/(?:ZenTest|RubyInline|sexp_processor|ParseTree)-}
38
+
39
+ pt_needs_dirs=$:.grep PARSETREE_AND_DEPENDANCIES
40
+
41
+ open find_home+"/.redparse/parse_tree_server.rc","w" do |rcfile|
42
+ rcfile.write pt_needs_dirs.join("\n")+"\n"
43
+ end
@@ -17,6 +17,43 @@
17
17
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
  =end
19
19
 
20
+
21
+ =begin
22
+ rp-locatetest passes all the ruby files it can find on the system (using
23
+ the unix command locate) to bin/redparse --vsparsetree. In other words,
24
+ it's comparing the output of RedParse (when cvt'd to a ParseTree-style
25
+ tree) to the actual output of ParseTree.
26
+
27
+ I usually run it like this:
28
+
29
+ nice ruby test/rp-locatetest.rb >test.log 2>&1 &
30
+
31
+ That runs rp-locatetest at low priority, in the background, saving
32
+ stdout and stderr to test.log.
33
+
34
+ You can then trawl through test.log, looking for lines that don't start
35
+ with 'no differences in '. (Other than the page of warnings in the
36
+ beginning, which is repeated every so often.) Or, you can look for
37
+ non-commented lines in the file 'problemfiles'. (Which is just a list of
38
+ files that caused failures in rp-locatetest.)
39
+
40
+ Ok, this is more complicated than it ought to be. Sorry.
41
+
42
+ rp-locatetest takes a LONG time to run, and hogs the cpu at 100%. That's
43
+ why I was using nice. So, make sure it's ok to do that on whatever
44
+ server you run it on. I always get impatient and kill it after some
45
+ hours or days. On a subsequent run it'll pick up again where it left
46
+ off.
47
+
48
+ Right now, about 0.5% of my ruby files cause problems for rp-locatetest.
49
+ Most of those failures correspond to known problems (the file is listed
50
+ at the end of the README and/or there's a case in test_redparse.rb for
51
+ that failure).
52
+ =end
53
+
54
+ $VERBOSE=1
55
+ $Debug=1
56
+
20
57
  #require 'test/code/rubylexervsruby'
21
58
  #require 'test/code/strgen'
22
59
  require "redparse/problemfiles"
@@ -152,7 +189,8 @@ until testdata.empty?
152
189
 
153
190
  # puts "testing: "+chunk.join(" ")
154
191
  chunk.empty? and next
155
- system $RUBY, "-Ilib", "bin/redparse", "--update-problemfiles", "-q", "--vsparsetree", *chunk
192
+ system $RUBY, "-Ilib", "bin/redparse", "--update-problemfiles", "--ignore-silly-begins", "--unparse",
193
+ "-q", "--vsparsetree", *chunk
156
194
  exit 2 if $?>>8 == 2 #exit if child got ^c
157
195
  end
158
196
  end
@@ -343,3 +381,5 @@ __END__
343
381
  /usr/lib/ruby/1.8/hpricot/traverse.rb
344
382
  /home/caleb/sandbox/rubylexer/jewels/net-netrc-0.2.1/lib/net/netrc.rb
345
383
  /home/caleb/sandbox/rubylexer/jewels/etc-0.2.0/lib/etc.rb
384
+
385
+
data/test/test_1.9.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'test/unit'
2
+ require 'rubylexer/test/oneliners_1.9'
3
+ require "redparse"
4
+
5
+ class TestsFor1_9 < Test::Unit::TestCase
6
+ RUBY_1_9_TO_1_8_EQUIVALENCES=[
7
+ '{a: b}'...'{:a=>b}',
8
+ '{a: b, c: d}'...'{:a=>b, :c=>d}',
9
+ "a ? b\n : c"..."a ? b : \n c",
10
+
11
+ 'not(true)'...'not true',
12
+ 'not(+1)'...'not +1',
13
+ 'not (true).to_s'...'not (true).to_s', #equivalent, but parser gets there different ways
14
+ ]
15
+
16
+ RUBY_1_9_TO_1_8_EQUIVALENCES_BUT_FOR_STRESC=[
17
+ '"foo"'...'"foo"',
18
+ '"foo#{bar}"'...'"foo#{bar}"',
19
+
20
+ '%W[foo]'...'%W[foo]',
21
+ '%W[foo#{bar}]'...'%W[foo#{bar}]',
22
+
23
+ '`foo`'...'`foo`',
24
+ '`foo#{bar}`'...'`foo#{bar}`',
25
+
26
+ '//'...'//',
27
+ '/aa/i'...'/aa/i',
28
+ '/a#{a}/u'...'/a#{a}/u',
29
+ '/a#{"a"}/e'...'/a#{"a"}/e',
30
+ '/b#{__FILE__}/s'...'/b#{__FILE__}/s',
31
+ '/bb/m'...'/bb/m',
32
+ '/b b/x'...'/b b/x',
33
+ '/b#{b}/o'...'/b#{b}/o',
34
+ ]
35
+
36
+
37
+ RUBY_1_9_VALID=[
38
+ 'not (true).to_s',
39
+ ]
40
+
41
+ include RedParse::Nodes
42
+ RUBY_1_9_PATTERNS={
43
+ 'not(true).to_s'=>+CallNode[+UnOpNode["not", +VarLikeNode["true"]], "to_s"],
44
+ }
45
+
46
+ def test_ruby19_equivs
47
+ RUBY_1_9_TO_1_8_EQUIVALENCES.each{|pair|
48
+ new,old=pair.first,pair.last
49
+ pt19=RedParse.new(new,'(eval)',1,[],:rubyversion=>1.9,:cache_mode=>:none).parse
50
+ pt18=RedParse.new(old,'(eval)',1,[],:cache_mode=>:none).parse
51
+ assert_equal pt18,pt19
52
+ }
53
+ end
54
+
55
+ def test_ruby19_equivs_but_for_stresc
56
+ RUBY_1_9_TO_1_8_EQUIVALENCES_BUT_FOR_STRESC.each{|pair|
57
+ new,old=pair.first,pair.last
58
+ pt19=RedParse.new(new,'(eval)',1,[],:rubyversion=>1.9,:cache_mode=>:none).parse
59
+ pt18=RedParse.new(old,'(eval)',1,[],:cache_mode=>:none).parse
60
+ if pt18.instance_variable_get(:@bs_handler)==:dquote_esc_seq
61
+ pt18.instance_variable_set :@bs_handler,:dquote19_esc_seq
62
+ else
63
+ pt18.instance_variable_set :@bs_handler,:Wquote19_esc_seq
64
+ pt18.instance_variable_get(:@parses_like).each{|x|
65
+ x.instance_variable_set :@bs_handler,:Wquote19_esc_seq if x.instance_variable_get :@bs_handler
66
+ }
67
+ end
68
+ assert_equal pt18,pt19
69
+ }
70
+ end
71
+
72
+ def test_ruby19_valid
73
+ RUBY_1_9_VALID.each{|xmpl|
74
+ pt19=RedParse.new(xmpl,'(eval)',1,[],:rubyversion=>1.9,:cache_mode=>:none).parse
75
+ assert_nil pt19.errors
76
+ }
77
+ end
78
+
79
+ def test_ruby19_patterns
80
+ RUBY_1_9_PATTERNS.each_pair{|code,pattern|
81
+ pt=RedParse.new(code,'(eval)',1,[],:rubyversion=>1.9,:cache_mode=>:none).parse
82
+ assert_match pattern, pt
83
+ }
84
+ end
85
+
86
+
87
+
88
+
89
+ include Ruby1_9OneLiners
90
+
91
+ def count_methods(tree)
92
+ count=0
93
+ tree.walk{|node|
94
+ case node
95
+ when CallSiteNode, MethodNode; count+=1
96
+ end
97
+ }
98
+ return count
99
+ end
100
+
101
+ def test_1_9
102
+ EXPECT_NO_METHODS.each{|snippet|
103
+ tree=RedParse.new(snippet,"-e").parse
104
+ count=count_methods(tree)
105
+ assert_equal count,0
106
+ }
107
+
108
+ EXPECT_1_METHOD.each{|snippet|
109
+ tree=RedParse.new(snippet,"-e").parse
110
+ count=count_methods(tree)
111
+ assert_equal count,1
112
+ }
113
+ end
114
+ end