1# 2# dummyparser.rb 3# 4 5require 'ripper' 6 7class Node 8 def initialize(name, *nodes) 9 @name = name 10 @children = nodes 11 end 12 13 attr_reader :name, :children 14 15 def to_s 16 "#{@name}(#{Node.trim_nil(@children).map {|n| n.to_s }.join(',')})" 17 end 18 19 def self.trim_nil(list) 20 if !list.empty? and list.last.nil? 21 list = list[0...-1] 22 list.pop while !list.empty? and list.last.nil? 23 end 24 list 25 end 26end 27 28class NodeList 29 def initialize 30 @list = [] 31 end 32 33 attr_reader :list 34 35 def push(item) 36 @list.push item 37 self 38 end 39 40 def prepend(items) 41 @list.unshift items 42 end 43 44 def to_s 45 "[#{@list.join(',')}]" 46 end 47end 48 49class DummyParser < Ripper 50 def hook(*names) 51 class << self; self; end.class_eval do 52 names.each do |name| 53 define_method(name) do |*a, &b| 54 result = super(*a, &b) 55 yield(name, *a) 56 result 57 end 58 end 59 end 60 self 61 end 62 63 def on_program(stmts) 64 stmts 65 end 66 67 def on_stmts_new 68 NodeList.new 69 end 70 71 def on_stmts_add(stmts, st) 72 stmts.push st 73 stmts 74 end 75 76 def on_void_stmt 77 Node.new('void') 78 end 79 80 def on_var_ref(name) 81 Node.new('ref', name) 82 end 83 84 def on_var_alias(a, b) 85 Node.new('valias', a, b) 86 end 87 88 def on_alias_error(a) 89 Node.new('aliaserr', a) 90 end 91 92 def on_arg_paren(args) 93 args 94 end 95 96 def on_args_new 97 NodeList.new 98 end 99 100 def on_args_add(list, arg) 101 list.push(arg) 102 end 103 104 def on_args_add_block(list, blk) 105 if blk 106 list.push('&' + blk.to_s) 107 else 108 list 109 end 110 end 111 112 def on_args_add_star(list, arg) 113 list.push('*' + arg.to_s) 114 end 115 116 def on_args_prepend(list, args) 117 list.prepend args 118 list 119 end 120 121 def on_method_add_arg(m, arg) 122 if arg == nil 123 arg = on_args_new 124 end 125 m.children.push arg 126 m 127 end 128 129 def on_method_add_block(m, b) 130 on_args_add_block(m.children, b) 131 m 132 end 133 134 def on_paren(params) 135 params 136 end 137 138 def on_brace_block(params, code) 139 Node.new('block', params, code) 140 end 141 142 def on_block_var(params, shadow) 143 params 144 end 145 146 def on_rest_param(var) 147 "*#{var}" 148 end 149 150 def on_blockarg(var) 151 "&#{var}" 152 end 153 154 def on_params(required, optional, rest, more, keyword, keyword_rest, block) 155 args = NodeList.new 156 157 required.each do |req| 158 args.push(req) 159 end if required 160 161 optional.each do |var, val| 162 args.push("#{var}=#{val}") 163 end if optional 164 165 args.push(rest) if rest 166 167 more.each do |m| 168 args.push(m) 169 end if more 170 171 args.push(block) if block 172 args 173 end 174 175 def on_assoc_new(a, b) 176 Node.new('assoc', a, b) 177 end 178 179 def on_bare_assoc_hash(assoc_list) 180 Node.new('assocs', *assoc_list) 181 end 182 183 def on_assoclist_from_args(a) 184 Node.new('assocs', *a) 185 end 186 187 def on_word_new 188 "" 189 end 190 191 def on_word_add(word, w) 192 word << w 193 end 194 195 def on_words_new 196 NodeList.new 197 end 198 199 def on_words_add(words, word) 200 words.push word 201 end 202 203 def on_qwords_new 204 NodeList.new 205 end 206 207 def on_qwords_add(words, word) 208 words.push word 209 end 210 211 (Ripper::PARSER_EVENTS.map(&:to_s) - instance_methods(false).map {|n|n.to_s.sub(/^on_/, '')}).each do |event| 212 define_method(:"on_#{event}") do |*args| 213 Node.new(event, *args) 214 end 215 end 216end 217