summaryrefslogtreecommitdiff
path: root/ext/ripper/tools/preproc.rb
blob: 4b26c5bcb0707ac918e46319a932d8f7d92ab34b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# $Id$

require 'stringio'
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 0
  }
  begin
    parser.parse!
  rescue OptionParser::ParseError => err
    $stderr.puts err.message
    $stderr.puts parser.help
    exit 1
  end
  unless ARGV.size == 1
    $stderr.puts "wrong number of arguments (#{ARGV.size} for 1)"
    exit 1
  end
  out = StringIO.new
  File.open(ARGV[0]) {|f|
    prelude f, out
    grammar f, out
    usercode f, out
  }
  if output
    File.open(output, 'w') {|f|
      f.write out.string
    }
  else
    print out.string
  end
end

def prelude(f, out)
  while line = f.gets
    case line
    when %r</\*%%%\*/>
      out.puts '/*'
    when %r</\*%>
      out.puts '*/'
    when %r<%\*/>
      out.puts
    when /\A%%/
      out.puts '%%'
      return
    when /\A%token/
      out.puts line.sub(/<\w+>/, '<val>')
    when /\A%type/
      out.puts line.sub(/<\w+>/, '<val>')
    else
      out.print line
    end
  end
end

def grammar(f, out)
  while line = f.gets
    case line
    when %r</\*%%%\*/>
      out.puts '#if 0'
    when %r</\*%c%\*/>
      out.puts '/*'
    when %r</\*%c>
      out.puts '*/'
    when %r</\*%>
      out.puts '#endif'
    when %r<%\*/>
      out.puts
    when /\A%%/
      out.puts '%%'
      return
    else
      out.print line
    end
  end
end

def usercode(f, out)
  while line = f.gets
    out.print line
  end
end

main