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.

parser.rb 4.0 KiB

10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. require 'ripper'
  2. require 'pp'
  3. module Bitshift
  4. class Parser
  5. def initialize(source)
  6. @source = source
  7. end
  8. def parse
  9. # new stuff
  10. walker = TreeWalker.new(@source)
  11. walker.parse
  12. return walker.to_s
  13. end
  14. end
  15. class TreeWalker < Ripper::SexpBuilder
  16. attr_accessor :symbols
  17. def initialize(source)
  18. ns_hash = Hash.new {
  19. |hash, key|
  20. hash[key] = {
  21. :assignments => [], :uses => []
  22. }
  23. }
  24. class_hash = ns_hash.clone
  25. function_hash = ns_hash.clone
  26. var_hash = ns_hash.clone
  27. @symbols = {
  28. :namespaces => ns_hash,
  29. :classes => class_hash,
  30. :functions => function_hash,
  31. :vars => var_hash
  32. }
  33. super(source)
  34. end
  35. def block_position(node)
  36. last_node = node[0]
  37. while last_node.is_a? Array
  38. sp = last_node
  39. while not (last_el = last_node[last_node.count - 1]) or
  40. (last_el.is_a? Array and last_el[last_el.count - 1].nil?)
  41. last_node = last_node[0..last_node.count - 2]
  42. end
  43. last_node = last_el
  44. end
  45. last_node = node[0]
  46. while last_node.is_a? Array
  47. ep = last_node
  48. while not (last_el = last_node[last_node.count - 1]) or
  49. (last_el.is_a? Array and last_el[last_el.count - 1].nil?)
  50. last_node = last_node[0..last_node.count - 2]
  51. end
  52. last_node = last_el
  53. end
  54. if sp == ep
  55. return sp + [sp[0], -1]
  56. end
  57. return sp + ep
  58. end
  59. def on_module(*node)
  60. pos = block_position(node)
  61. name = node[0][1][1]
  62. symbols[:namespaces][name][:assignments] << pos
  63. return node
  64. end
  65. def on_class(*node)
  66. pos = block_position(node)
  67. name = node[0][1][1]
  68. symbols[:classes][name][:assignments] << pos
  69. return node
  70. end
  71. def on_def(*node)
  72. pos = block_position(node)
  73. name = node[0][1]
  74. symbols[:functions][name][:assignments] << pos
  75. return node
  76. end
  77. def on_call(*node)
  78. pos = block_position(node)
  79. name = node[node.count - 1][1]
  80. symbols[:functions][name][:uses] << pos
  81. return node
  82. end
  83. def on_vcall(*node)
  84. pos = block_position(node)
  85. name = node[0][1]
  86. symbols[:functions][name][:uses] << pos
  87. return node
  88. end
  89. def on_assign(*node)
  90. pos = block_position(node)
  91. return node if not node[0][0].is_a? Array
  92. name = node[0][0][1]
  93. symbols[:vars][name][:assignments] << pos
  94. return node
  95. end
  96. def on_var_field(*node)
  97. pos = block_position(node)
  98. name = node[0][1]
  99. symbols[:vars][name][:uses] << pos
  100. return node
  101. end
  102. def on_var_ref(*node)
  103. pos = block_position(node)
  104. name = node[0][1]
  105. symbols[:vars][name][:uses] << pos
  106. return node
  107. end
  108. def on_command(*node)
  109. # catch require statements
  110. end
  111. def to_s
  112. new_symbols = Hash.new {|hash, key| hash[key] = Hash.new}
  113. symbols.each do |type, sym_list|
  114. sym_list.each do |name, sym|
  115. new_symbols[type.to_s][name.to_s] = {
  116. "assignments" => sym[:assignments],
  117. "uses" => sym[:uses]}
  118. end
  119. end
  120. str = new_symbols.to_s
  121. str = str.gsub(/=>/, ":")
  122. return str
  123. end
  124. end
  125. end