1# frozen_string_literal: true 2# 3# dummyparser.rb 4# 5 6require 'ripper' 7 8class Node 9 def initialize(name, *nodes) 10 @name = name 11 @children = nodes 12 end 13 14 attr_reader :name, :children 15 16 def to_s 17 "#{@name}(#{Node.trim_nil(@children).map {|n| n.to_s }.join(',')})" 18 end 19 20 def self.trim_nil(list) 21 if !list.empty? and list.last.nil? 22 list = list[0...-1] 23 list.pop while !list.empty? and list.last.nil? 24 end 25 list 26 end 27 28 class Sym < self 29 def initialize(name) 30 @name = name 31 end 32 33 def to_s 34 ":#{@name}" 35 end 36 end 37end 38 39class NodeList 40 def initialize(list = []) 41 @list = list 42 end 43 44 attr_reader :list 45 46 def push(item) 47 @list.push item 48 self 49 end 50 51 def concat(item) 52 @list.concat item 53 self 54 end 55 56 def prepend(items) 57 @list.unshift items 58 end 59 60 def to_s 61 "[#{@list.join(',')}]" 62 end 63end 64 65class DummyParser < Ripper 66 def hook(*names) 67 class << self; self; end.class_eval do 68 names.each do |name| 69 define_method(name) do |*a, &b| 70 result = super(*a, &b) 71 yield(name, *a) 72 result 73 end 74 end 75 end 76 self 77 end 78 79 def on_program(stmts) 80 stmts 81 end 82 83 def on_stmts_new 84 NodeList.new 85 end 86 87 def on_stmts_add(stmts, st) 88 stmts.push st 89 stmts 90 end 91 92 def on_void_stmt 93 Node.new('void') 94 end 95 96 def on_var_ref(name) 97 Node.new('ref', name) 98 end 99 100 def on_var_alias(a, b) 101 Node.new('valias', a, b) 102 end 103 104 def on_alias_error(a) 105 Node.new('aliaserr', a) 106 end 107 108 def on_arg_paren(args) 109 args 110 end 111 112 def on_args_new 113 NodeList.new 114 end 115 116 def on_args_add(list, arg) 117 list.push(arg) 118 end 119 120 def on_args_add_block(list, blk) 121 if blk 122 list.push('&' + blk.to_s) 123 else 124 list 125 end 126 end 127 128 def on_args_add_star(list, arg) 129 list.push('*' + arg.to_s) 130 end 131 132 def on_args_prepend(list, args) 133 list.prepend args 134 list 135 end 136 137 def on_method_add_arg(m, arg) 138 if arg == nil 139 arg = on_args_new 140 end 141 m.children.push arg 142 m 143 end 144 145 def on_method_add_block(m, b) 146 on_args_add_block(m.children, b) 147 m 148 end 149 150 def on_paren(params) 151 params 152 end 153 154 def on_brace_block(params, code) 155 Node.new('block', params, code) 156 end 157 158 def on_block_var(params, shadow) 159 params 160 end 161 162 def on_rest_param(var) 163 "*#{var}" 164 end 165 166 def on_kwrest_param(var) 167 "**#{var}" 168 end 169 170 def on_blockarg(var) 171 "&#{var}" 172 end 173 174 def on_params(required, optional, rest, more, keyword, keyword_rest, block) 175 args = NodeList.new 176 177 required.each do |req| 178 args.push(req) 179 end if required 180 181 optional.each do |var, val| 182 args.push("#{var}=#{val}") 183 end if optional 184 185 args.push(rest) if rest 186 187 more.each do |m| 188 args.push(m) 189 end if more 190 191 args.push(block) if block 192 args 193 end 194 195 def on_assoc_new(a, b) 196 Node.new('assoc', a, b) 197 end 198 199 def on_bare_assoc_hash(assoc_list) 200 Node.new('assocs', *assoc_list) 201 end 202 203 def on_assoclist_from_args(a) 204 Node.new('assocs', *a) 205 end 206 207 def on_word_new 208 "".dup 209 end 210 211 def on_word_add(word, w) 212 word << w 213 end 214 215 def on_words_new 216 NodeList.new 217 end 218 219 def on_words_add(words, word) 220 words.push word 221 end 222 223 def on_qwords_new 224 NodeList.new 225 end 226 227 def on_qwords_add(words, word) 228 words.push word 229 end 230 231 def on_symbols_new 232 NodeList.new 233 end 234 235 def on_symbols_add(symbols, symbol) 236 symbols.push Node::Sym.new(symbol) 237 end 238 239 def on_qsymbols_new 240 NodeList.new 241 end 242 243 def on_qsymbols_add(symbols, symbol) 244 symbols.push Node::Sym.new(symbol) 245 end 246 247 def on_mlhs_new 248 NodeList.new 249 end 250 251 def on_mlhs_paren(list) 252 Node.new(:mlhs, list) 253 end 254 255 def on_mlhs_add(list, node) 256 list.push node 257 end 258 259 def on_mlhs_add_block(list, blk) 260 if blk 261 list.push('&' + blk.to_s) 262 else 263 list 264 end 265 end 266 267 def on_mlhs_add_star(list, arg) 268 list.push('*' + arg.to_s) 269 end 270 271 def on_mlhs_add_post(list, post) 272 list.concat(post.list) 273 end 274 275 def on_rescue(exc, *rest) 276 Node.new('rescue', (exc && NodeList.new(exc)), *rest) 277 end 278 279 (Ripper::PARSER_EVENTS.map(&:to_s) - instance_methods(false).map {|n|n.to_s.sub(/^on_/, '')}).each do |event| 280 define_method(:"on_#{event}") do |*args| 281 Node.new(event, *args) 282 end 283 end 284end 285