redparse 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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