From 554314c40ae31d7ce2c3a85ab4acbb079f5f2e82 Mon Sep 17 00:00:00 2001 From: Benjamin Attal Date: Mon, 9 Jun 2014 23:24:47 -0400 Subject: [PATCH] Move ruby parser to Ripper. --- parsers/ruby/lib/parser.rb | 186 ++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 112 deletions(-) diff --git a/parsers/ruby/lib/parser.rb b/parsers/ruby/lib/parser.rb index 0062a0c..5d5d699 100644 --- a/parsers/ruby/lib/parser.rb +++ b/parsers/ruby/lib/parser.rb @@ -1,6 +1,5 @@ -require 'socket' -require 'ruby_parser' -require 'sexp_processor' +require 'ripper' +require 'pp' module Bitshift class Parser @@ -9,156 +8,119 @@ module Bitshift end def parse - parser = RubyParser.new - tree = parser.parse(@source) - return '{}' if tree.nil? - - processor = CachedWalker.new tree - processor.process(tree) - return processor.to_s + # new stuff + walker = TreeWalker.new(@source) + walker.parse + return walker.to_s end end - class CachedWalker < SexpProcessor + class TreeWalker < Ripper::SexpBuilder attr_accessor :symbols - def initialize(tree) - super() - + def initialize(source) ns_hash = Hash.new { |hash, key| - hash[key] = { assignments: [], uses: [] } + hash[key] = { + :assignments => [], :uses => [] + } } class_hash = ns_hash.clone function_hash = ns_hash.clone var_hash = ns_hash.clone - @require_empty = false @symbols = { - namespaces: ns_hash, - classes: class_hash, - functions: function_hash, - vars: var_hash + :namespaces => ns_hash, + :classes => class_hash, + :functions => function_hash, + :vars => var_hash } - end - - def block_position(exp) - end_ln = (start_ln = exp.line) - cur_exp = exp - while cur_exp.is_a? Sexp - end_ln = cur_exp.line - cur_exp = cur_exp.last - break if cur_exp == nil - end - - pos = [start_ln, -1, end_ln, -1] - return pos + super(source) end - def statement_position(exp) - pos = Hash.new - end_ln = start_ln = exp.line - - pos = [start_ln, -1, end_ln, -1] - return pos - end + def block_position(node) + last_node = node[0] + while last_node.is_a? Array + sp = last_node + while not (last_el = last_node[last_node.count - 1]) or + (last_el.is_a? Array and last_el[last_el.count - 1].nil?) + last_node = last_node[0..last_node.count - 2] + end + last_node = last_el + end - def process_module(exp) - pos = block_position(exp) - exp.shift + last_node = node[0] + while last_node.is_a? Array + ep = last_node + while not (last_el = last_node[last_node.count - 1]) or + (last_el.is_a? Array and last_el[last_el.count - 1].nil?) + last_node = last_node[0..last_node.count - 2] + end + last_node = last_el + end - while (name = exp.shift).is_a? Sexp + if sp == ep + return sp + [sp[0], -1] end + return sp + ep + end + def on_module(*node) + pos = block_position(node) + name = node[0][1][1] symbols[:namespaces][name][:assignments] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + return node end - def process_class(exp) - pos = block_position(exp) - exp.shift - - while (name = exp.shift).is_a? Sexp - end - + def on_class(*node) + pos = block_position(node) + name = node[0][1][1] symbols[:classes][name][:assignments] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + return node end - def process_defn(exp) - pos = block_position(exp) - exp.shift - - while (name = exp.shift).is_a? Sexp - end - + def on_def(*node) + pos = block_position(node) + name = node[0][1] symbols[:functions][name][:assignments] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + return node end - def process_call(exp) - pos = statement_position(exp) - exp.shift - exp.shift - - while (name = exp.shift).is_a? Sexp - end - + def on_call(*node) + pos = block_position(node) + name = node[node.count - 1][1] symbols[:functions][name][:uses] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + return node end - def process_iasgn(exp) - pos = statement_position(exp) - exp.shift - - while (name = exp.shift).is_a? Sexp - end - - symbols[:vars][name][:assignments] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + def on_vcall(*node) + pos = block_position(node) + name = node[0][1] + symbols[:functions][name][:uses] << pos + return node end - def process_lasgn(exp) - pos = statement_position(exp) - exp.shift - - while (name = exp.shift).is_a? Sexp - end - + def on_assign(*node) + pos = block_position(node) + return node if not node[0][0].is_a? Array + name = node[0][0][1] symbols[:vars][name][:assignments] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + return node end - def process_attrasgn(exp) - pos = statement_position(exp) - exp.shift - - while (name = exp.shift).is_a? Sexp - end - - symbols[:vars][((name.to_s)[0..-2]).to_sym][:assignments] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + def on_var_field(*node) + pos = block_position(node) + name = node[0][1] + symbols[:vars][name][:uses] << pos + return node end - def process_lvar(exp) - pos = statement_position(exp) - exp.shift - - while (name = exp.shift).is_a? Sexp - end - + def on_var_ref(*node) + pos = block_position(node) + name = node[0][1] symbols[:vars][name][:uses] << pos - exp.each_sexp {|s| process(s)} - return exp.clear + return node end def to_s