1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/ext/ripper/tools/preproc.rb
nobu 7df1e45bb6 ripper: add states of scanner
* parse.y (ripper_state): add states of scanner to tokens from
  Ripper.lex and Ripper::Filter#on_*.  based on the patch by
  aycabta (Code Ahss) at [ruby-core:81789].  [Feature #13686]

* ext/ripper/tools/preproc.rb (prelude, usercode): generate EXPR_*
  constants from enums.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-09-14 10:53:47 +00:00

106 lines
2.1 KiB
Ruby
Executable file

# frozen_string_literal: true
# $Id$
require 'optparse'
def main
output = nil
parser = OptionParser.new
parser.banner = "Usage: #{File.basename($0)} [--output=PATH] <parse.y>"
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
$stderr.puts err.message
$stderr.puts parser.help
exit false
end
unless ARGV.size == 1
abort "wrong number of arguments (#{ARGV.size} for 1)"
end
out = "".dup
File.open(ARGV[0]) {|f|
prelude f, out
grammar f, out
usercode f, out
}
if output
File.open(output, 'w') {|f|
f.write out
}
else
print out
end
end
def prelude(f, out)
@exprs = {}
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
if (/^enum lex_state_(?:bits|e) \{/ =~ line)..(/^\}/ =~ line)
case line
when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\//
@exprs[$1.chomp("_bit")] = $2.strip
when /^\s*(EXPR_\w+)\s+=\s+(.+)$/
name = $1
val = $2.chomp(",")
@exprs[name] = "equals to " + (val.start_with?("(") ? "<tt>#{val}</tt>" : "+#{val}+")
end
end
out << line
end
end
end
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
def usercode(f, out)
require 'erb'
compiler = ERB::Compiler.new('%-')
compiler.put_cmd = compiler.insert_cmd = "out.<<"
lineno = f.lineno
src, = compiler.compile(f.read)
eval(src, binding, f.path, lineno)
end
main