class Rattler::Runner

Runner defines the command-line parser generator.

Constants

ERRNO_GEN_ERROR

Error generaing ruby code

ERRNO_PARSE_ERROR

Error parsing grammar

ERRNO_READ_ERROR

Error reading grammar file

ERRNO_USAGE

Invalid command line arguments

ERRNO_WRITE_ERROR

Error writing parser file

Public Class Methods

new(args) click to toggle source

Create a new command-line parser.

@param [Array<String>] args the command-line arguments

# File lib/rattler/runner.rb, line 35
def initialize(args)
  @optimize = true
  options.parse!(args)
  if args.size == 1
    @srcfname = Pathname.new(args.shift)
  else
    puts options
    exit ERRNO_USAGE
  end
end
run(args) click to toggle source

Run the command-line parser

@param (see initialize)

# File lib/rattler/runner.rb, line 28
def self.run(args)
  self.new(args).run
end

Public Instance Methods

run() click to toggle source

Run the command-line parser.

# File lib/rattler/runner.rb, line 47
def run
  if result = analyze
    synthesize(result)
  else
    puts parser.failure
    exit ERRNO_PARSE_ERROR
  end
end

Private Instance Methods

analyze() click to toggle source
# File lib/rattler/runner.rb, line 102
def analyze
  parser.parse
rescue Exception => e
  puts e
  exit ERRNO_READ_ERROR
end
code_for(g) click to toggle source
# File lib/rattler/runner.rb, line 123
def code_for(g)
  Rattler::Compiler::ParserGenerator.code_for g, generator_options
end
full_dest_name(g) click to toggle source
# File lib/rattler/runner.rb, line 152
def full_dest_name(g)
  names = g.name.split('::').map {|_| underscore _ }
  ofname = @ofname || (names[-1] + '.rb')
  if @destdir
    @destdir.join(ofname)
  else
    names[-1] = ofname
    libdir.join(*names)
  end
end
generator_options() click to toggle source
# File lib/rattler/runner.rb, line 127
def generator_options
  { :no_optimize => !@optimize }
end
libdir() click to toggle source
# File lib/rattler/runner.rb, line 163
def libdir
  @libdir ||= Pathname.getwd
end
open_output(g) { |$stdout| ... } click to toggle source
# File lib/rattler/runner.rb, line 131
def open_output(g)
  if @ofname == '-'
    yield $stdout
  else
    open_to_write(full_dest_name(g)) {|io| yield io }
  end
end
open_to_write(dest) { |f| ... } click to toggle source
# File lib/rattler/runner.rb, line 143
def open_to_write(dest)
  if dest.exist? and not @force
    raise "File exists - #{relative_path dest} (use --force to overwrite)"
  end
  dest.dirname.mkpath
  report(dest)
  dest.open('w') { |f| yield f }
end
options() click to toggle source
# File lib/rattler/runner.rb, line 58
def options
  @options ||= OptionParser.new do |opts|

    opts.banner = "Usage: #{File.basename($0)} FILENAME [options]"

    opts.separator ''

    opts.on '-l', '--lib DIRECTORY',
            'Specify the destination lib directory' do |libdir|
      @libdir = Pathname.new(libdir)
    end

    opts.on '-d', '--dest DIRECTORY',
            'Specify an explicit destination directory' do |destdir|
      @destdir = Pathname.new(destdir)
    end

    opts.on '-o', '--output FILENAME',
            'Specify a different output filename ("-" = STDOUT)' do |ofname|
      @ofname = ofname
    end

    opts.on '-f', '--force',
            'Force overwrite if the output file exists' do |f|
      @force = f
    end

    opts.on '-n', '--no-optimize',
            'Disable optimization' do |n|
      @optimize = n
    end

    opts.separator ''

    opts.on_tail '-h', '--help', 'Show this message' do
      abort "#{opts}\n"
    end
  end
end
parser() click to toggle source
# File lib/rattler/runner.rb, line 98
def parser
  @parser ||= Rattler::Compiler::GrammarParser.new(@srcfname.read)
end
relative_path(p) click to toggle source
# File lib/rattler/runner.rb, line 167
def relative_path(p)
  p.dirname.realpath.relative_path_from(Pathname.getwd) + p.basename
end
report(dest) click to toggle source
# File lib/rattler/runner.rb, line 139
def report(dest)
  puts "#{relative_path @srcfname} -> #{relative_path dest}"
end
synthesize(g) click to toggle source
# File lib/rattler/runner.rb, line 109
def synthesize(g)
  open_output(g) do |io|
    begin
      io.puts code_for(g)
    rescue Exception => e
      puts e
      exit ERRNO_GEN_ERROR
    end
  end
rescue Exception => e
  puts e
  exit ERRNO_WRITE_ERROR
end
underscore(camel_cased_word) click to toggle source

copied shamelessly from ActiveSupport

# File lib/rattler/runner.rb, line 172
def underscore(camel_cased_word)
  camel_cased_word.to_s.gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
    gsub(/([a-z\d])([A-Z])/,'\1_\2').
    tr("-", "_").
    downcase
end