summaryrefslogtreecommitdiff
path: root/ext/ripper/tools/preproc.rb
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ripper/tools/preproc.rb')
-rw-r--r--ext/ripper/tools/preproc.rb115
1 files changed, 66 insertions, 49 deletions
diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb
index b838a78db7..a92be93d5b 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)
+ 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