A semantic search engine for source code https://bitshift.benkurtovic.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

127 lines
3.3 KiB

  1. require 'socket'
  2. require 'ruby_parser'
  3. require 'sexp_processor'
  4. module Bitshift
  5. class Parser
  6. def initialize(source)
  7. @source = source
  8. end
  9. def parse
  10. parser = RubyParser.new
  11. tree = parser.parse(@source)
  12. puts tree.inspect
  13. offset = tree.line - 1
  14. processor = NodeVisitor.new offset
  15. processor.process tree
  16. return processor.symbols
  17. end
  18. end
  19. class NodeVisitor < SexpProcessor
  20. attr_accessor :symbols
  21. attr_accessor :offset
  22. def initialize(offset)
  23. super()
  24. @require_empty = false
  25. @offset = offset
  26. module_hash = Hash.new {|hash, key| hash[key] = Hash.new}
  27. class_hash = module_hash.clone
  28. function_hash = Hash.new {|hash, key| hash[key] = { calls: [] } }
  29. var_hash = Hash.new {|hash, key| hash[key] = [] }
  30. @symbols = {
  31. modules: module_hash,
  32. classes: class_hash,
  33. functions: function_hash,
  34. vars: var_hash
  35. }
  36. end
  37. def block_position(exp)
  38. pos = Hash.new
  39. end_ln = (start_ln = exp.line - offset)
  40. cur_exp = exp
  41. while cur_exp.is_a? Sexp
  42. end_ln = cur_exp.line - offset
  43. cur_exp = cur_exp.last
  44. break if cur_exp == nil
  45. end
  46. pos[:coord] = {
  47. start_ln: start_ln,
  48. end_ln: end_ln }
  49. return pos
  50. end
  51. def statement_position(exp)
  52. pos = Hash.new
  53. end_ln = start_ln = exp.line - offset
  54. pos[:coord] = {
  55. start_ln: start_ln,
  56. end_ln: end_ln }
  57. return pos
  58. end
  59. def process_module(exp)
  60. pos = block_position exp
  61. exp.shift
  62. name = exp.shift
  63. symbols[:modules][name] = pos
  64. exp.each_sexp {|s| process(s)}
  65. return exp.clear
  66. end
  67. def process_class(exp)
  68. pos = block_position exp
  69. exp.shift
  70. name = exp.shift
  71. symbols[:classes][name] = pos
  72. exp.each_sexp {|s| process(s)}
  73. return exp.clear
  74. end
  75. def process_defn(exp)
  76. pos = block_position exp
  77. exp.shift
  78. name = exp.shift
  79. symbols[:functions][name][:declaration] = pos
  80. exp.each_sexp {|s| process(s)}
  81. return exp.clear
  82. end
  83. def process_call(exp)
  84. pos = statement_position exp
  85. exp.shift
  86. exp.shift
  87. name = exp.shift
  88. symbols[:functions][name][:calls] << pos
  89. exp.each_sexp {|s| process(s)}
  90. return exp.clear
  91. end
  92. def process_iasgn(exp)
  93. pos = statement_position exp
  94. exp.shift
  95. name = exp.shift
  96. symbols[:vars][name] << pos
  97. exp.each_sexp {|s| process(s)}
  98. return exp.clear
  99. end
  100. def process_lasgn(exp)
  101. pos = statement_position exp
  102. exp.shift
  103. name = exp.shift
  104. symbols[:vars][name] << pos
  105. exp.each_sexp {|s| process(s)}
  106. return exp.clear
  107. end
  108. end
  109. end