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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#!/usr/bin/env ruby
require 'kpeg'
require 'kpeg/code_generator'
require 'kpeg/format_parser'
require 'kpeg/grammar_renderer'
require 'optparse'
options = {}
optparser = OptionParser.new do |o|
o.banner = "Usage: kpeg [options]"
o.on("-t", "--test", "Syntax check the file only") do |v|
options[:test] = v
end
o.on("--reformat", "Reformat your grammar and write it back out") do
options[:reformat] = true
end
o.on("-o", "--output FILE", "Where the output should go") do |v|
options[:output] = v
end
o.on("-n", "--name NAME", "Class name to use for the parser") do |v|
options[:name] = v
end
o.on("-f", "--force", "Overwrite the output if it exists") do |v|
options[:force] = v
end
o.on("-s", "--stand-alone", "Write the parser to run standalone") do |v|
options[:standalone] = v
end
o.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
o.on("-d", "--debug", "Debug parsing the file") do |v|
options[:debug] = v
end
end
optparser.parse!
if ARGV.empty?
puts optparser.help
exit 1
end
file = ARGV.shift
unless File.exist?(file)
puts "File '#{file}' does not exist"
exit 1
end
parser = KPeg::FormatParser.new File.read(file), true
unless m = parser.parse
puts "Syntax error in grammar #{file}"
parser.show_error
exit 1
end
grammar = parser.grammar
if options[:reformat]
if !options[:output]
puts "Please specify -o for where to write the new grammar"
exit 1
end
output = options[:output]
if File.exist?(output) and !options[:force]
puts "Output '#{output}' already exists, not overwriting (use -f)"
exit 1
end
rend = KPeg::GrammarRenderer.new(parser.grammar)
File.open output, "w" do |f|
rend.render(f)
end
puts "Wrote reformatted output to #{output}"
exit 0
end
if !options[:test] and !options[:name]
unless name = grammar.variables["name"]
puts "Please specify -n"
exit 1
end
else
name = options[:name]
end
if options[:output]
new_path = options[:output]
else
new_path = "#{file}.rb"
end
if !options[:test] and File.exist?(new_path) and !options[:force]
puts "Path #{new_path} already exists, not overwriting\n"
exit 1
end
if options[:test]
puts "Syntax ok"
if options[:debug]
gr = KPeg::GrammarRenderer.new(grammar)
gr.render(STDOUT)
end
exit 0
end
cg = KPeg::CodeGenerator.new name, grammar
cg.standalone = options[:standalone]
output = cg.output
open new_path, "w" do |io|
io << output
end
puts "Wrote #{name} to #{new_path}"
|