ruby_parser
Advanced tools
| #!/usr/bin/ruby -ws | ||
| $f ||= false | ||
| $:.unshift "../../ruby_parser/dev/lib" | ||
| $:.unshift "../../ruby2ruby/dev/lib" | ||
| require 'rubygems' | ||
| require 'ruby2ruby' | ||
| require 'ruby_parser' | ||
| require 'gauntlet' | ||
| class RubyParserGauntlet < Gauntlet | ||
| def initialize | ||
| super | ||
| self.data = Hash.new { |h,k| h[k] = {} } | ||
| old_data = load_yaml data_file | ||
| self.data.merge! old_data | ||
| end | ||
| def should_skip? name | ||
| if $f then | ||
| if Hash === data[name] then | ||
| ! data[name].empty? | ||
| else | ||
| data[name] | ||
| end | ||
| else | ||
| data[name] == true # yes, == true on purpose | ||
| end | ||
| end | ||
| def diff_pp o1, o2 | ||
| require 'pp' | ||
| File.open("/tmp/a.#{$$}", "w") do |f| | ||
| PP.pp o1, f | ||
| end | ||
| File.open("/tmp/b.#{$$}", "w") do |f| | ||
| PP.pp o2, f | ||
| end | ||
| `diff -u /tmp/a.#{$$} /tmp/b.#{$$}` | ||
| ensure | ||
| File.unlink "/tmp/a.#{$$}" rescue nil | ||
| File.unlink "/tmp/b.#{$$}" rescue nil | ||
| end | ||
| def broke name, file, msg | ||
| warn "bad" | ||
| self.data[name][file] = msg | ||
| self.dirty = true | ||
| end | ||
| def process path, name | ||
| begin | ||
| $stderr.print " #{path}: " | ||
| rp = RubyParser.new | ||
| r2r = Ruby2Ruby.new | ||
| old_ruby = File.read(path) | ||
| begin | ||
| old_sexp = rp.process old_ruby | ||
| rescue Racc::ParseError => e | ||
| self.data[name][path] = :unparsable | ||
| self.dirty = true | ||
| return | ||
| end | ||
| new_ruby = r2r.process old_sexp.deep_clone | ||
| begin | ||
| new_sexp = rp.process new_ruby | ||
| rescue Racc::ParseError => e | ||
| broke name, path, "couldn't parse new_ruby: #{e.message.strip}" | ||
| return | ||
| end | ||
| if old_sexp != new_sexp then | ||
| broke name, path, diff_pp(old_sexp, new_sexp) | ||
| return | ||
| end | ||
| self.data[name][path] = true | ||
| self.dirty = true | ||
| warn "good" | ||
| rescue Interrupt | ||
| puts "User cancelled" | ||
| exit 1 | ||
| rescue Exception => e | ||
| broke name, path, " UNKNOWN ERROR: #{e}: #{e.message.strip}" | ||
| end | ||
| end | ||
| def run name | ||
| warn name | ||
| Dir["**/*.rb"].sort.each do |path| | ||
| next if path =~ /gemspec.rb/ # HACK | ||
| next if data[name][path] == true | ||
| process path, name | ||
| end | ||
| if self.data[name].values.all? { |v| v == true } then | ||
| warn " ALL GOOD!" | ||
| self.data[name] = true | ||
| self.dirty = true | ||
| end | ||
| end | ||
| end | ||
| filter = ARGV.shift | ||
| filter = Regexp.new filter if filter | ||
| gauntlet = RubyParserGauntlet.new | ||
| gauntlet.run_the_gauntlet filter |
+14
-0
@@ -0,1 +1,15 @@ | ||
| === 2.0.2 / 2009-01-20 | ||
| * 2 minor enhancements: | ||
| * Added gauntlet_rubyparser plugin. YAY for easy massive bug-hunting. | ||
| * Promoted Sexp's file/line/comments to sexp_processor. | ||
| * 4 bug fixes: | ||
| * Fixed and improved the readme | ||
| * Fixed lexing heredoc newlines. | ||
| * Fixed line numbers on defns. | ||
| * Fixed rdoc generation bug pointed out by hugh sasse (who rocks) | ||
| === 2.0.1 / 2008-11-04 | ||
@@ -2,0 +16,0 @@ |
@@ -191,3 +191,4 @@ $: << File.expand_path("~/Work/p4/zss/src/ParseTree/dev/lib") # for me, not you. | ||
| line = src.string[src.pos, src.matched_size] | ||
| src.string[src.pos, src.matched_size] = '' | ||
| src.string[src.pos, src.matched_size] = "\n" | ||
| src.pos += 1 | ||
| else | ||
@@ -655,3 +656,2 @@ line = nil | ||
| end | ||
| else | ||
| end | ||
@@ -667,3 +667,2 @@ | ||
| self.command_start = true | ||
@@ -670,0 +669,0 @@ self.lex_state = :expr_beg |
@@ -116,3 +116,3 @@ require 'stringio' | ||
| class RubyParser < Racc::Parser | ||
| VERSION = '2.0.1' | ||
| VERSION = '2.0.2' | ||
@@ -506,3 +506,3 @@ attr_accessor :lexer, :in_def, :in_single, :file | ||
| def new_defn val | ||
| line, name, args, body = val[2], val[1], val[3], val[4] | ||
| (line, bol), name, args, body = val[2], val[1], val[3], val[4] | ||
| body ||= s(:nil) | ||
@@ -515,2 +515,3 @@ | ||
| result.line = line | ||
| result.line -= 1 if bol | ||
| result.comments = self.comments.pop | ||
@@ -833,2 +834,4 @@ result | ||
| ## | ||
| # :stopdoc: | ||
| # | ||
| # :expr_beg = ignore newline, +/- is a sign. | ||
@@ -887,2 +890,4 @@ # :expr_end = newline significant, +/- is a operator. | ||
| # :startdoc: | ||
| WORDLIST = Hash[*wordlist.map { |o| [o.name, o] }.flatten] | ||
@@ -1012,22 +1017,3 @@ | ||
| attr_writer :paren | ||
| attr_accessor :comments | ||
| attr_accessor :file | ||
| def line(n=nil) | ||
| if n then | ||
| @line = n | ||
| self | ||
| else | ||
| @line ||= nil | ||
| end | ||
| end | ||
| def line= n | ||
| @line = n | ||
| end | ||
| def node_type | ||
| first | ||
| end | ||
| def paren | ||
@@ -1046,15 +1032,4 @@ @paren ||= false | ||
| def values | ||
| self[1..-1] | ||
| end | ||
| alias :real_inspect :inspect | ||
| def inspect # :nodoc: | ||
| sexp_str = self.map {|x|x.inspect}.join(', ') | ||
| if line && ENV['VERBOSE'] then | ||
| "s(#{sexp_str}).line(#{line})" | ||
| else | ||
| "s(#{sexp_str})" | ||
| end | ||
| end | ||
| alias :node_type :sexp_type | ||
| alias :values :sexp_body # TODO: retire | ||
| end | ||
@@ -1061,0 +1036,0 @@ |
+1
-0
@@ -7,2 +7,3 @@ .autotest | ||
| bin/ruby_parse | ||
| lib/gauntlet_rubyparser.rb | ||
| lib/ruby_lexer.rb | ||
@@ -9,0 +10,0 @@ lib/ruby_parser.y |
+1
-1
@@ -18,3 +18,3 @@ # -*- ruby -*- | ||
| parser.extra_dev_deps << 'ParseTree' | ||
| parser.extra_deps << ['sexp_processor', '>= 3.0.0'] | ||
| parser.extra_deps << ['sexp_processor', '>= 3.0.1'] | ||
| end | ||
@@ -21,0 +21,0 @@ |
+32
-10
@@ -1,5 +0,5 @@ | ||
| ruby_parser | ||
| by Ryan Davis | ||
| http://parsetree.rubyforge.org/ | ||
| = ruby_parser | ||
| * http://parsetree.rubyforge.org/ | ||
| == DESCRIPTION: | ||
@@ -12,2 +12,23 @@ | ||
| 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))))) | ||
| == FEATURES/PROBLEMS: | ||
@@ -20,7 +41,8 @@ | ||
| * Can utilize PT's SexpProcessor and UnifiedRuby for language processing. | ||
| * Known Issue: Speed sucks currently. 5500 tests currently run in 21 min. | ||
| * Known Issue: Code is waaay ugly. Port of a port. Not my fault. Will fix RSN. | ||
| * Known Issue: I don't currently support newline nodes. | ||
| * Known Issue: Speed is now pretty good, but can always improve: | ||
| * RP parses a corpus of 3702 files in 125s (avg 108 Kb/s) | ||
| * MRI+PT parsed the same in 67.38s (avg 200.89 Kb/s) | ||
| * Known Issue: Code is much better, but still has a long way to go. | ||
| * Known Issue: Totally awesome. | ||
| * Known Issue: dasgn_curr decls can be out of order from ParseTree's. | ||
| * Known Issue: line number values can be slightly off. Parsing LR sucks. | ||
@@ -35,5 +57,5 @@ == SYNOPSIS: | ||
| * ruby. woot. | ||
| * ParseTree is needed for Sexp class... crap. I might break that out. | ||
| * sexp_processor for Sexp and SexpProcessor classes. | ||
| * ParseTree for testing. | ||
| * racc full package for parser development. | ||
| * racc full package for parser development (compiling .y to .rb). | ||
@@ -48,3 +70,3 @@ == INSTALL: | ||
| Copyright (c) 2007 Ryan Davis | ||
| Copyright (c) 2007-2008 Ryan Davis | ||
@@ -51,0 +73,0 @@ Permission is hereby granted, free of charge, to any person obtaining |
+22
-24
@@ -377,2 +377,9 @@ #!/usr/local/bin/ruby | ||
| # def test_str_pct_nested_nested | ||
| # rb = "%{ { #\{ \"#\{1}\" } } }" | ||
| # pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } ")) | ||
| # assert_equal pt, @processor.parse(rb) | ||
| # end | ||
| def test_str_str | ||
@@ -393,26 +400,17 @@ rb = "\"a #\{'b'}\"" | ||
| STARTING_LINE = { | ||
| "begin_def" => 2, | ||
| "block_stmt_after" => 2, | ||
| "block_stmt_after_mri_verbose_flag" => 2, | ||
| "block_stmt_before" => 2, | ||
| "block_stmt_before_mri_verbose_flag" => 2, | ||
| "block_stmt_both" => 2, | ||
| "block_stmt_both_mri_verbose_flag" => 2, | ||
| "case_nested_inner_no_expr" => 2, | ||
| "case_no_expr" => 2, | ||
| "case_splat" => 2, | ||
| "cvasgn" => 2, | ||
| "defn_args_none" => 2, | ||
| "defn_zarray" => 2, | ||
| "structure_unused_literal_wwtt" => 3, # yes, 3... odd test | ||
| "super_0" => 2, | ||
| "super_1" => 2, | ||
| "super_1_array" => 2, | ||
| "super_n" => 2, | ||
| "super_multi" => 2, | ||
| "undef_block_1" => 2, | ||
| "undef_block_2" => 2, | ||
| "undef_block_3" => 2, | ||
| "undef_block_wtf" => 2, | ||
| "zsuper" => 2, | ||
| "case_nested_inner_no_expr" => 2, | ||
| "case_no_expr" => 2, | ||
| "case_splat" => 2, | ||
| "dstr_heredoc_expand" => 2, | ||
| "dstr_heredoc_windoze_sucks" => 2, | ||
| "dstr_heredoc_yet_again" => 2, | ||
| "str_heredoc" => 2, | ||
| "str_heredoc_call" => 2, | ||
| "str_heredoc_empty" => 2, | ||
| "str_heredoc_indent" => 2, | ||
| "structure_unused_literal_wwtt" => 3, # yes, 3... odd test | ||
| "undef_block_1" => 2, | ||
| "undef_block_2" => 2, | ||
| "undef_block_3" => 2, | ||
| "undef_block_wtf" => 2, | ||
| } | ||
@@ -419,0 +417,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet