diff options
Diffstat (limited to 'ext/ripper/tools/preproc.rb')
-rw-r--r-- | ext/ripper/tools/preproc.rb | 115 |
1 files changed, 66 insertions, 49 deletions
diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb index b838a78db7..5e8a6e0cb5 100644 --- a/ext/ripper/tools/preproc.rb +++ b/ext/ripper/tools/preproc.rb @@ -5,11 +5,15 @@ require 'optparse' def main output = nil + template = nil parser = OptionParser.new - parser.banner = "Usage: #{File.basename($0)} [--output=PATH] <parse.y>" + parser.banner = "Usage: #{File.basename($0)} [--output=PATH] [--template=PATH] <parse.y>" parser.on('--output=PATH', 'An output file.') {|path| output = path } + parser.on('--template=PATH', 'An template file.') {|path| + template = path + } parser.on('--help', 'Prints this message and quit.') { puts parser.help exit true @@ -17,50 +21,56 @@ def main 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)" + warn err.message + abort parser.help 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 + if ARGV[0] == "-" + unless ARGV.size == 2 + abort "wrong number of arguments (#{ARGV.size} for 2)" + end + process STDIN, out, ARGV[1], template + else + unless ARGV.size == 1 + abort "wrong number of arguments (#{ARGV.size} for 1)" + end + File.open(ARGV[0]) {|f| + process f, out, ARGV[0], template } + end + if output + File.write(output, out) else print out end end -def prelude(f, out) - @exprs = {} - lex_state_def = false +def process(f, out, path, template) + prelude f, out + grammar f, out + usercode f, out, path, template +end + +require_relative 'dsl' + +def generate_line(f, out) while line = f.gets - case line - when /\A%%/ + case + when gen = DSL.line?(line, f.lineno) + out << gen.generate << "\n" + when line.start_with?("%%") out << "%%\n" - return - when /\A%token/ - out << line.sub(/<\w+>/, '<val>') - when /\A%type/ - out << line.sub(/<\w+>/, '<val>') - when /^enum lex_state_(?:bits|e) \{/ - lex_state_def = true - out << line - when /^\}/ - lex_state_def = false - out << line + break else - out << line + out << yield(line) end - if lex_state_def + end +end + +def prelude(f, out) + @exprs = {} + generate_line(f, out) do |line| + if (/^enum lex_state_(?:bits|e) \{/ =~ line)..(/^\}/ =~ line) case line when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\// @exprs[$1.chomp("_bit")] = $2.strip @@ -70,38 +80,45 @@ def prelude(f, out) @exprs[name] = "equals to " + (val.start_with?("(") ? "<tt>#{val}</tt>" : "+#{val}+") end end + line end end -require_relative "dsl" - def grammar(f, out) - while line = f.gets + generate_line(f, out) do |line| case line - when %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/> - out << DSL.new($2, ($1 || "").split(",")).generate << "\n" when %r</\*%%%\*/> - out << "#if 0\n" + "#if 0\n" when %r</\*%> - out << "#endif\n" + "#endif\n" when %r<%\*/> - out << "\n" - when /\A%%/ - out << "%%\n" - return + "\n" else - out << line + line end end end -def usercode(f, out) +def usercode(f, out, path, template) require 'erb' + lineno = nil + src = nil 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) + + if template + File.open(template) do |f| + out.clear + lineno = f.lineno + src, = compiler.compile(f.read) + path = template + end + else + lineno = f.lineno + src, = compiler.compile(f.read) + end + + eval(src, binding, path, lineno) end main |