In Files
- ripper/tools/generate.rb
- ripper/tools/preproc.rb
Parent
BasicObject
Class/Module Index
![show/hide quicksearch [+]](./images/find.png)
Object
Public Instance Methods
check_arity(h)
# File ripper/tools/generate.rb, line 126
def check_arity(h)
invalid = false
h.each do |event, list|
unless list.map {|line, arity| arity }.uniq.size == 1
invalid = true
locations = list.map {|line, a| "#{line}:#{a}" }.join(', ')
$stderr.puts "arity crash [event=#{event}]: #{locations}"
end
end
abort if invalid
end
generate_eventids1(ids)
# File ripper/tools/generate.rb, line 70
def generate_eventids1(ids)
buf = ""
buf << %Q[static struct {\n]
ids.each do |id, arity|
buf << %Q[ ID id_#{id};\n]
end
buf << %Q[} ripper_parser_ids;\n]
buf << %Q[\n]
ids.each do |id, arity|
buf << %Q[#define ripper_id_#{id} ripper_parser_ids.id_#{id}\n]
end
buf << %Q[\n]
buf << %Q[static void\n]
buf << %Q[ripper_init_eventids1(void)\n]
buf << %Q[{\n]
buf << %Q[#define set_id1(name) ripper_id_##name = rb_intern_const("on_"#name)\n]
ids.each do |id, arity|
buf << %Q[ set_id1(#{id});\n]
end
buf << %Q[}\n]
buf << %Q[\n]
buf << %Q[static void\n]
buf << %Q[ripper_init_eventids1_table(VALUE self)\n]
buf << %Q[{\n]
buf << %Q[ VALUE h = rb_hash_new();\n]
buf << %Q[ rb_define_const(self, "PARSER_EVENT_TABLE", h);\n]
ids.each do |id, arity|
buf << %Q[ rb_hash_aset(h, intern_sym("#{id}"), INT2FIX(#{arity}));\n]
end
buf << %Q[}\n]
buf
end
generate_eventids2_table(ids)
# File ripper/tools/generate.rb, line 103
def generate_eventids2_table(ids)
buf = ""
buf << %Q[static void\n]
buf << %Q[ripper_init_eventids2_table(VALUE self)\n]
buf << %Q[{\n]
buf << %Q[ VALUE h = rb_hash_new();\n]
buf << %Q[ rb_define_const(self, "SCANNER_EVENT_TABLE", h);\n]
ids.each do |id|
buf << %Q[ rb_hash_aset(h, intern_sym("#{id}"), INT2FIX(1));\n]
end
buf << %Q[}\n]
buf
end
grammar(f, out)
# File ripper/tools/preproc.rb, line 64
def grammar(f, out)
while line = f.gets
case line
when %r</\*%%%\*/>
out << '#if 0' << $/
when %r</\*%c%\*/>
out << '/*' << $/
when %r</\*%c>
out << '*/' << $/
when %r</\*%>
out << '#endif' << $/
when %r<%\*/>
out << $/
when /\A%%/
out << '%%' << $/
return
else
out << line
end
end
end
main()
# File ripper/tools/generate.rb, line 6
def main
mode = nil
ids1src = nil
ids2src = nil
output = nil
parser = @parser = OptionParser.new
parser.banner = "Usage: #{File.basename($0)} --mode=MODE [--ids1src=PATH] [--ids2src=PATH] [--output=PATH]"
parser.on('--mode=MODE', 'check, eventids1, or eventids2table.') {|m|
mode = m
}
parser.on('--ids1src=PATH', 'A source file of event-IDs 1 (parse.y).') {|path|
ids1src = path
}
parser.on('--ids2src=PATH', 'A source file of event-IDs 2 (eventids2.c).') {|path|
ids2src = path
}
parser.on('--output=PATH', 'An output file.') {|path|
output = path
}
parser.on('--help', 'Prints this message and quit.') {
puts parser.help
exit true
}
begin
parser.parse!
rescue OptionParser::ParseError => err
usage err.message
end
usage 'no mode given' unless mode
case mode
when 'check'
usage 'no --ids1src' unless ids1src
usage 'no --ids2src' unless ids2src
h = read_ids1_with_locations(ids1src)
check_arity h
ids2 = read_ids2(ids2src)
common = h.keys & ids2
unless common.empty?
abort "event crash: #{common.join(' ')}"
end
exit 0
when 'eventids1'
usage 'no --ids1src' unless ids1src
result = generate_eventids1(read_ids1(ids1src))
when 'eventids2table'
usage 'no --ids2src' unless ids2src
result = generate_eventids2_table(read_ids2(ids2src))
end
if output
File.open(output, 'w') {|f|
f.write result
}
else
puts result
end
end
prelude(f, out)
# File ripper/tools/preproc.rb, line 42
def prelude(f, out)
while line = f.gets
case line
when %r</\*%%%\*/>
out << '/*' << $/
when %r</\*%>
out << '*/' << $/
when %r<%\*/>
out << $/
when /\A%%/
out << '%%' << $/
return
when /\A%token/
out << line.sub(/<\w+>/, '<val>')
when /\A%type/
out << line.sub(/<\w+>/, '<val>')
else
out << line
end
end
end
read_ids1(path)
# File ripper/tools/generate.rb, line 117
def read_ids1(path)
strip_locations(read_ids1_with_locations(path))
end
read_ids1_with_locations(path)
# File ripper/tools/generate.rb, line 138
def read_ids1_with_locations(path)
h = {}
File.open(path) {|f|
f.each do |line|
next if /\A\#\s*define\s+dispatch/ =~ line
next if /ripper_dispatch/ =~ line
line.scan(/\bdispatch(\d)\((\w+)/) do |arity, event|
(h[event] ||= []).push [f.lineno, arity.to_i]
end
end
}
h
end
read_ids2(path)
# File ripper/tools/generate.rb, line 152
def read_ids2(path)
src = File.open(path) {|f| f.read}
ids2 = src.scan(/ID\s+ripper_id_(\w+)/).flatten.uniq.sort
diff = src.scan(/set_id2\((\w+)\);/).flatten - ids2
unless diff.empty?
abort "missing scanner IDs: #{diff}"
end
return ids2
end
strip_locations(h)
# File ripper/tools/generate.rb, line 121
def strip_locations(h)
h.map {|event, list| [event, list.first[1]] } .sort_by {|event, arity| event.to_s }
end