mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Removed the accidental files at 931815bfd8
This commit is contained in:
parent
ac7c2754c0
commit
b79be4b09c
8 changed files with 0 additions and 958 deletions
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Exit cleanly from an early interrupt
|
||||
Signal.trap("INT") do
|
||||
Bundler.ui.debug("\n#{caller.join("\n")}") if defined?(Bundler)
|
||||
exit 1
|
||||
end
|
||||
|
||||
base_path = File.expand_path("../lib", __dir__)
|
||||
|
||||
if File.exist?(base_path)
|
||||
require_relative "../lib/bundler"
|
||||
else
|
||||
require "bundler"
|
||||
end
|
||||
|
||||
# Check if an older version of bundler is installed
|
||||
$LOAD_PATH.each do |path|
|
||||
next unless path =~ %r{/bundler-0\.(\d+)} && $1.to_i < 9
|
||||
err = String.new
|
||||
err << "Looks like you have a version of bundler that's older than 0.9.\n"
|
||||
err << "Please remove your old versions.\n"
|
||||
err << "An easy way to do this is by running `gem cleanup bundler`."
|
||||
abort(err)
|
||||
end
|
||||
|
||||
if File.exist?(base_path)
|
||||
require_relative "../lib/bundler/friendly_errors"
|
||||
else
|
||||
require "bundler/friendly_errors"
|
||||
end
|
||||
|
||||
Bundler.with_friendly_errors do
|
||||
if File.exist?(base_path)
|
||||
require_relative "../lib/bundler/cli"
|
||||
else
|
||||
require "bundler/cli"
|
||||
end
|
||||
|
||||
# Allow any command to use --help flag to show help for that command
|
||||
help_flags = %w[--help -h]
|
||||
help_flag_used = ARGV.any? {|a| help_flags.include? a }
|
||||
args = help_flag_used ? Bundler::CLI.reformatted_help_args(ARGV) : ARGV
|
||||
|
||||
Bundler::CLI.start(args, :debug => true)
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
load File.expand_path("../bundle", __FILE__)
|
11
lib/exe/irb
11
lib/exe/irb
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# irb.rb - interactive ruby
|
||||
# $Release Version: 0.9.6 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
|
||||
require "irb"
|
||||
|
||||
IRB.start(__FILE__)
|
306
lib/exe/racc
306
lib/exe/racc
|
@ -1,306 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Copyright (c) 1999-2006 Minero Aoki
|
||||
#
|
||||
# This program is free software.
|
||||
# You can distribute/modify this program under the same terms of ruby.
|
||||
# see the file "COPYING".
|
||||
|
||||
require 'racc/static'
|
||||
require 'optparse'
|
||||
|
||||
def main
|
||||
output = nil
|
||||
debug_parser = false
|
||||
make_logfile = false
|
||||
logfilename = nil
|
||||
make_executable = false
|
||||
rubypath = nil
|
||||
embed_runtime = false
|
||||
debug_flags = Racc::DebugFlags.new
|
||||
line_convert = true
|
||||
line_convert_all = false
|
||||
omit_action_call = true
|
||||
superclass = nil
|
||||
check_only = false
|
||||
verbose = false
|
||||
profiler = RaccProfiler.new(false)
|
||||
|
||||
parser = OptionParser.new
|
||||
parser.banner = "Usage: #{File.basename($0)} [options] <input>"
|
||||
parser.on('-o', '--output-file=PATH',
|
||||
'output file name [<input>.tab.rb]') {|name|
|
||||
output = name
|
||||
}
|
||||
parser.on('-t', '--debug', 'Outputs debugging parser.') {|fl|
|
||||
debug_parser = fl
|
||||
}
|
||||
parser.on('-g', 'Equivalent to -t (obsolete).') {|fl|
|
||||
$stderr.puts "racc -g is obsolete. Use racc -t instead." if $VERBOSE
|
||||
debug_parser = fl
|
||||
}
|
||||
parser.on('-v', '--verbose',
|
||||
'Creates <filename>.output log file.') {|fl|
|
||||
make_logfile = fl
|
||||
}
|
||||
parser.on('-O', '--log-file=PATH',
|
||||
'Log file name [<input>.output]') {|path|
|
||||
make_logfile = true
|
||||
logfilename = path
|
||||
}
|
||||
parser.on('-e', '--executable [RUBYPATH]', 'Makes executable parser.') {|path|
|
||||
executable = true
|
||||
rubypath = (path == 'ruby' ? nil : path)
|
||||
}
|
||||
parser.on('-E', '--embedded', "Embeds Racc runtime in output.") {
|
||||
embed_runtime = true
|
||||
}
|
||||
parser.on('--line-convert-all', 'Converts line numbers of user codes.') {
|
||||
line_convert_all = true
|
||||
}
|
||||
parser.on('-l', '--no-line-convert', 'Never convert line numbers.') {
|
||||
line_convert = false
|
||||
line_convert_all = false
|
||||
}
|
||||
parser.on('-a', '--no-omit-actions', 'Never omit actions.') {
|
||||
omit_action_call = false
|
||||
}
|
||||
parser.on('--superclass=CLASSNAME',
|
||||
'Uses CLASSNAME instead of Racc::Parser.') {|name|
|
||||
superclass = name
|
||||
}
|
||||
parser.on('--runtime=FEATURE',
|
||||
"Uses FEATURE instead of 'racc/parser'") {|feat|
|
||||
runtime = feature
|
||||
}
|
||||
parser.on('-C', '--check-only', 'Checks syntax and quit immediately.') {|fl|
|
||||
check_only = fl
|
||||
}
|
||||
parser.on('-S', '--output-status', 'Outputs internal status time to time.') {
|
||||
verbose = true
|
||||
}
|
||||
parser.on('-P', 'Enables generator profile') {
|
||||
profiler = RaccProfiler.new(true)
|
||||
}
|
||||
parser.on('-D flags', "Flags for Racc debugging (do not use).") {|flags|
|
||||
debug_flags = Racc::DebugFlags.parse_option_string(flags)
|
||||
}
|
||||
#parser.on('--no-extensions', 'Run Racc without any Ruby extension.') {
|
||||
# Racc.const_set :Racc_No_Extentions, true
|
||||
#}
|
||||
parser.on('--version', 'Prints version and quit.') {
|
||||
puts "racc version #{Racc::Version}"
|
||||
exit 0
|
||||
}
|
||||
parser.on('--runtime-version', 'Prints runtime version and quit.') {
|
||||
printf "racc runtime version %s (rev. %s); %s\n",
|
||||
Racc::Parser::Racc_Runtime_Version,
|
||||
Racc::Parser::Racc_Runtime_Revision,
|
||||
if Racc::Parser.racc_runtime_type == 'ruby'
|
||||
sprintf('ruby core version %s (rev. %s)',
|
||||
Racc::Parser::Racc_Runtime_Core_Version_R,
|
||||
Racc::Parser::Racc_Runtime_Core_Revision_R)
|
||||
else
|
||||
sprintf('c core version %s (rev. %s)',
|
||||
Racc::Parser::Racc_Runtime_Core_Version_C,
|
||||
Racc::Parser::Racc_Runtime_Core_Revision_C)
|
||||
end
|
||||
exit 0
|
||||
}
|
||||
parser.on('--copyright', 'Prints copyright and quit.') {
|
||||
puts Racc::Copyright
|
||||
exit 0
|
||||
}
|
||||
parser.on('--help', 'Prints this message and quit.') {
|
||||
puts parser.help
|
||||
exit 1
|
||||
}
|
||||
begin
|
||||
parser.parse!
|
||||
rescue OptionParser::ParseError => err
|
||||
$stderr.puts err.message
|
||||
$stderr.puts parser.help
|
||||
exit 1
|
||||
end
|
||||
if ARGV.empty?
|
||||
$stderr.puts 'no input'
|
||||
exit 1
|
||||
end
|
||||
if ARGV.size > 1
|
||||
$stderr.puts 'too many input'
|
||||
exit 1
|
||||
end
|
||||
input = ARGV[0]
|
||||
|
||||
begin
|
||||
$stderr.puts 'Parsing grammar file...' if verbose
|
||||
result = profiler.section('parse') {
|
||||
parser = Racc::GrammarFileParser.new(debug_flags)
|
||||
parser.parse(File.read(input), File.basename(input))
|
||||
}
|
||||
if check_only
|
||||
$stderr.puts 'syntax ok'
|
||||
exit 0
|
||||
end
|
||||
|
||||
$stderr.puts 'Generating LALR states...' if verbose
|
||||
states = profiler.section('nfa') {
|
||||
Racc::States.new(result.grammar).nfa
|
||||
}
|
||||
|
||||
$stderr.puts "Resolving #{states.size} states..." if verbose
|
||||
profiler.section('dfa') {
|
||||
states.dfa
|
||||
}
|
||||
|
||||
$stderr.puts 'Creating parser file...' if verbose
|
||||
params = result.params.dup
|
||||
# Overwrites parameters given by a grammar file with command line options.
|
||||
params.superclass = superclass if superclass
|
||||
params.omit_action_call = true if omit_action_call
|
||||
# From command line option
|
||||
if make_executable
|
||||
params.make_executable = true
|
||||
params.interpreter = rubypath
|
||||
end
|
||||
params.debug_parser = debug_parser
|
||||
params.convert_line = line_convert
|
||||
params.convert_line_all = line_convert_all
|
||||
params.embed_runtime = embed_runtime
|
||||
profiler.section('generation') {
|
||||
generator = Racc::ParserFileGenerator.new(states, params)
|
||||
generator.generate_parser_file(output || make_filename(input, '.tab.rb'))
|
||||
}
|
||||
|
||||
if make_logfile
|
||||
profiler.section('logging') {
|
||||
$stderr.puts 'Creating log file...' if verbose
|
||||
logfilename ||= make_filename(output || File.basename(input), '.output')
|
||||
File.open(logfilename, 'w') {|f|
|
||||
Racc::LogFileGenerator.new(states, debug_flags).output f
|
||||
}
|
||||
}
|
||||
end
|
||||
if debug_flags.status_logging
|
||||
log_useless states.grammar
|
||||
log_conflict states
|
||||
else
|
||||
report_useless states.grammar
|
||||
report_conflict states
|
||||
end
|
||||
|
||||
profiler.report
|
||||
rescue Racc::Error, Errno::ENOENT, Errno::EPERM => err
|
||||
raise if $DEBUG or debug_flags.any?
|
||||
lineno = err.message.slice(/\A\d+:/).to_s
|
||||
$stderr.puts "#{File.basename $0}: #{input}:#{lineno} #{err.message.strip}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
def make_filename(path, suffix)
|
||||
path.sub(/(?:\..*?)?\z/, suffix)
|
||||
end
|
||||
|
||||
def report_conflict(states)
|
||||
if states.should_report_srconflict?
|
||||
$stderr.puts "#{states.n_srconflicts} shift/reduce conflicts"
|
||||
end
|
||||
if states.rrconflict_exist?
|
||||
$stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts"
|
||||
end
|
||||
end
|
||||
|
||||
def log_conflict(states)
|
||||
logging('w') {|f|
|
||||
f.puts "ex#{states.grammar.n_expected_srconflicts}"
|
||||
if states.should_report_srconflict?
|
||||
f.puts "sr#{states.n_srconflicts}"
|
||||
end
|
||||
if states.rrconflict_exist?
|
||||
f.puts "rr#{states.n_rrconflicts}"
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def report_useless(grammar)
|
||||
if grammar.useless_nonterminal_exist?
|
||||
$stderr.puts "#{grammar.n_useless_nonterminals} useless nonterminals"
|
||||
end
|
||||
if grammar.useless_rule_exist?
|
||||
$stderr.puts "#{grammar.n_useless_rules} useless rules"
|
||||
end
|
||||
if grammar.start.useless?
|
||||
$stderr.puts 'fatal: start symbol does not derive any sentence'
|
||||
end
|
||||
end
|
||||
|
||||
def log_useless(grammar)
|
||||
logging('a') {|f|
|
||||
if grammar.useless_nonterminal_exist?
|
||||
f.puts "un#{grammar.n_useless_nonterminals}"
|
||||
end
|
||||
if grammar.useless_rule_exist?
|
||||
f.puts "ur#{grammar.n_useless_rules}"
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def logging(mode, &block)
|
||||
File.open("log/#{File.basename(ARGV[0])}", mode, &block)
|
||||
end
|
||||
|
||||
class RaccProfiler
|
||||
def initialize(really)
|
||||
@really = really
|
||||
@log = []
|
||||
unless ::Process.respond_to?(:times)
|
||||
# Ruby 1.6
|
||||
@class = ::Time
|
||||
else
|
||||
@class = ::Process
|
||||
end
|
||||
end
|
||||
|
||||
def section(name)
|
||||
if @really
|
||||
t1 = @class.times.utime
|
||||
result = yield
|
||||
t2 = @class.times.utime
|
||||
@log.push [name, t2 - t1]
|
||||
result
|
||||
else
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def report
|
||||
return unless @really
|
||||
f = $stderr
|
||||
total = cumulative_time()
|
||||
f.puts '--task-----------+--sec------+---%-'
|
||||
@log.each do |name, time|
|
||||
f.printf "%-19s %s %3d%%\n", name, pjust(time,4,4), (time/total*100).to_i
|
||||
end
|
||||
f.puts '-----------------+-----------+-----'
|
||||
f.printf "%-20s%s\n", 'total', pjust(total,4,4)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cumulative_time
|
||||
t = @log.inject(0) {|sum, (name, time)| sum + time }
|
||||
t == 0 ? 0.01 : t
|
||||
end
|
||||
|
||||
def pjust(num, i, j)
|
||||
m = /(\d+)(\.\d+)?/.match(num.to_s)
|
||||
str = m[1].rjust(i)
|
||||
str.concat m[2].ljust(j+1)[0,j+1] if m[2]
|
||||
str
|
||||
end
|
||||
end
|
||||
|
||||
main
|
195
lib/exe/racc2y
195
lib/exe/racc2y
|
@ -1,195 +0,0 @@
|
|||
#!/usr/local/bin/ruby
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Copyright (c) 1999-2006 Minero Aoki
|
||||
#
|
||||
# This program is feee software.
|
||||
# You can distribute/modify this program under the terms of
|
||||
# the GNU LGPL, Lesser General Public License version 2.1.
|
||||
# For details of the LGPL, see the file "COPYING".
|
||||
#
|
||||
|
||||
require 'racc/grammarfileparser'
|
||||
require 'racc/info'
|
||||
require 'optparse'
|
||||
|
||||
def main
|
||||
@with_action = true
|
||||
with_header = false
|
||||
with_inner = false
|
||||
with_footer = false
|
||||
output = nil
|
||||
parser = OptionParser.new
|
||||
parser.banner = "Usage: #{File.basename($0)} [-AHIF] [-oFILENAME] GRAMMARFILE"
|
||||
parser.on('-o', '--output=FILENAME', 'output file name [<input>.yacc]') {|name|
|
||||
output = name
|
||||
}
|
||||
parser.on('-A', '--without-action', 'Does not include actions.') {
|
||||
@with_action = false
|
||||
}
|
||||
parser.on('-H', '--with-header', 'Includes header part.') {
|
||||
with_header = true
|
||||
}
|
||||
parser.on('-I', '--with-inner', 'Includes inner part.') {
|
||||
with_inner = true
|
||||
}
|
||||
parser.on('-F', '--with-footer', 'Includes footer part.') {
|
||||
with_footer = true
|
||||
}
|
||||
parser.on('--version', 'Prints version and quit.') {
|
||||
puts "racc2y version #{Racc::Version}"
|
||||
exit 0
|
||||
}
|
||||
parser.on('--copyright', 'Prints copyright and quit.') {
|
||||
puts Racc::Copyright
|
||||
exit 0
|
||||
}
|
||||
parser.on('--help', 'Prints this message and quit.') {
|
||||
puts parser.help
|
||||
exit 1
|
||||
}
|
||||
begin
|
||||
parser.parse!
|
||||
rescue OptionParser::ParseError => err
|
||||
$stderr.puts err.message
|
||||
$stderr.puts parser.help
|
||||
exit 1
|
||||
end
|
||||
if ARGV.empty?
|
||||
$stderr.puts "no input file"
|
||||
exit 1
|
||||
end
|
||||
unless ARGV.size == 1
|
||||
$stderr.puts "too many inputs"
|
||||
exit 1
|
||||
end
|
||||
input = ARGV[0]
|
||||
|
||||
begin
|
||||
result = Racc::GrammarFileParser.parse_file(input)
|
||||
result.grammar.init
|
||||
File.open(output || "#{input}.yacc", 'w') {|f|
|
||||
f.puts "/* generated from #{input} */"
|
||||
if with_header
|
||||
f.puts
|
||||
f.puts '%{'
|
||||
print_user_codes f, result.params.header
|
||||
f.puts '%}'
|
||||
end
|
||||
f.puts
|
||||
print_terminals f, result.grammar
|
||||
f.puts
|
||||
print_precedence_table f, precedence_table(result.grammar)
|
||||
f.puts
|
||||
f.puts '%%'
|
||||
print_grammar f, result.grammar
|
||||
f.puts '%%'
|
||||
if with_inner
|
||||
f.puts '/*---- inner ----*/'
|
||||
print_user_codes f, result.params.inner
|
||||
end
|
||||
if with_footer
|
||||
f.puts '/*---- footer ----*/'
|
||||
print_user_codes f, result.params.footer
|
||||
end
|
||||
}
|
||||
rescue SystemCallError => err
|
||||
$stderr.puts err.message
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
def print_terminals(f, grammar)
|
||||
init_indent = '%token'.size
|
||||
f.print '%token'
|
||||
columns = init_indent
|
||||
grammar.symboltable.each_terminal do |t|
|
||||
next unless t.terminal?
|
||||
next if t.dummy?
|
||||
next if t == grammar.symboltable.anchor
|
||||
next if t == grammar.symboltable.error
|
||||
unless t.value.kind_of?(String)
|
||||
if columns > 60
|
||||
f.puts
|
||||
f.print ' ' * init_indent
|
||||
columns = init_indent
|
||||
end
|
||||
columns += f.write(" #{yacc_symbol(t)}")
|
||||
end
|
||||
end
|
||||
f.puts
|
||||
end
|
||||
|
||||
def precedence_table(grammar)
|
||||
table = []
|
||||
grammar.symboltable.select {|sym| sym.precedence }.each do |sym|
|
||||
(table[sym.prec] ||= [sym.assoc]).push sym
|
||||
end
|
||||
table.compact
|
||||
end
|
||||
|
||||
def print_precedence_table(f, table)
|
||||
return if table.empty?
|
||||
f.puts '/* precedance table */'
|
||||
table.each do |syms|
|
||||
assoc = syms.shift
|
||||
f.printf '%%%-8s ', assoc.to_s.downcase
|
||||
f.puts syms.map {|s| yacc_symbol(s) }.join(' ')
|
||||
end
|
||||
f.puts
|
||||
end
|
||||
|
||||
def print_grammar(f, grammar)
|
||||
prev_target = nil
|
||||
indent = 10
|
||||
embactions = []
|
||||
grammar.each do |rule|
|
||||
if rule.target.dummy?
|
||||
embactions.push rule.action unless rule.action.empty?
|
||||
next
|
||||
end
|
||||
if rule.target == prev_target
|
||||
f.print ' ' * indent, '|'
|
||||
else
|
||||
prev_target = rule.target
|
||||
f.printf "\n%-10s:", yacc_symbol(prev_target)
|
||||
end
|
||||
rule.symbols.each do |s|
|
||||
if s.dummy? # target of dummy rule for embedded action
|
||||
f.puts
|
||||
print_action f, embactions.shift, indent
|
||||
f.print ' ' * (indent + 1)
|
||||
else
|
||||
f.print ' ', yacc_symbol(s)
|
||||
end
|
||||
end
|
||||
if rule.specified_prec
|
||||
f.print ' %prec ', yacc_symbol(rule.specified_prec)
|
||||
end
|
||||
f.puts
|
||||
unless rule.action.empty?
|
||||
print_action f, rule.action, indent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def print_action(f, action, indent)
|
||||
return unless @with_action
|
||||
f.print ' ' * (indent + 4), "{\n"
|
||||
f.print ' ' * (indent + 6), action.source.text.strip, "\n"
|
||||
f.print ' ' * (indent + 4) , "}\n"
|
||||
end
|
||||
|
||||
def print_user_codes(f, srcs)
|
||||
return if srcs.empty?
|
||||
srcs.each do |src|
|
||||
f.puts src.text
|
||||
end
|
||||
end
|
||||
|
||||
def yacc_symbol(s)
|
||||
s.to_s.gsub('"', "'")
|
||||
end
|
||||
|
||||
main
|
44
lib/exe/rdoc
44
lib/exe/rdoc
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# RDoc: Documentation tool for source code
|
||||
# (see lib/rdoc/rdoc.rb for more information)
|
||||
#
|
||||
# Copyright (c) 2003 Dave Thomas
|
||||
# Released under the same terms as Ruby
|
||||
|
||||
begin
|
||||
gem 'rdoc'
|
||||
rescue NameError => e # --disable-gems
|
||||
raise unless e.name == :gem
|
||||
rescue Gem::LoadError
|
||||
end
|
||||
|
||||
require 'rdoc/rdoc'
|
||||
|
||||
begin
|
||||
r = RDoc::RDoc.new
|
||||
r.document ARGV
|
||||
rescue Errno::ENOSPC
|
||||
$stderr.puts 'Ran out of space creating documentation'
|
||||
$stderr.puts
|
||||
$stderr.puts 'Please free up some space and try again'
|
||||
rescue SystemExit
|
||||
raise
|
||||
rescue Exception => e
|
||||
if $DEBUG_RDOC then
|
||||
$stderr.puts e.message
|
||||
$stderr.puts "#{e.backtrace.join "\n\t"}"
|
||||
$stderr.puts
|
||||
elsif Interrupt === e then
|
||||
$stderr.puts
|
||||
$stderr.puts 'Interrupted'
|
||||
else
|
||||
$stderr.puts "uh-oh! RDoc had a problem:"
|
||||
$stderr.puts e.message
|
||||
$stderr.puts
|
||||
$stderr.puts "run with --debug for full backtrace"
|
||||
end
|
||||
|
||||
exit 1
|
||||
end
|
||||
|
12
lib/exe/ri
12
lib/exe/ri
|
@ -1,12 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
begin
|
||||
gem 'rdoc'
|
||||
rescue NameError => e # --disable-gems
|
||||
raise unless e.name == :gem
|
||||
rescue Gem::LoadError
|
||||
end
|
||||
|
||||
require 'rdoc/ri/driver'
|
||||
|
||||
RDoc::RI::Driver.run ARGV
|
339
lib/exe/y2racc
339
lib/exe/y2racc
|
@ -1,339 +0,0 @@
|
|||
#!/usr/local/bin/ruby
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Copyright (c) 1999-2006 Minero Aoki
|
||||
#
|
||||
# This program is free software.
|
||||
# You can distribute/modify this program under the terms of
|
||||
# the GNU LGPL, Lesser General Public License version 2.1.
|
||||
# For details of the GNU LGPL, see the file "COPYING".
|
||||
#
|
||||
|
||||
require 'racc/info'
|
||||
require 'strscan'
|
||||
require 'forwardable'
|
||||
require 'optparse'
|
||||
|
||||
def main
|
||||
@with_action = true
|
||||
@with_header = false
|
||||
@with_usercode = false
|
||||
cname = 'MyParser'
|
||||
input = nil
|
||||
output = nil
|
||||
parser = OptionParser.new
|
||||
parser.banner = "Usage: #{File.basename($0)} [-Ahu] [-c <classname>] [-o <filename>] <input>"
|
||||
parser.on('-o', '--output=FILENAME', 'output file name [<input>.racc]') {|name|
|
||||
output = name
|
||||
}
|
||||
parser.on('-c', '--classname=NAME', "Name of the parser class. [#{cname}]") {|name|
|
||||
cname = name
|
||||
}
|
||||
parser.on('-A', '--without-action', 'Does not include actions.') {
|
||||
@with_action = false
|
||||
}
|
||||
parser.on('-h', '--with-header', 'Includes header (%{...%}).') {
|
||||
@with_header = true
|
||||
}
|
||||
parser.on('-u', '--with-user-code', 'Includes user code.') {
|
||||
@with_usercode = true
|
||||
}
|
||||
parser.on('--version', 'Prints version and quit.') {
|
||||
puts "y2racc version #{Racc::Version}"
|
||||
exit 0
|
||||
}
|
||||
parser.on('--copyright', 'Prints copyright and quit.') {
|
||||
puts Racc::Copyright
|
||||
exit 0
|
||||
}
|
||||
parser.on('--help', 'Prints this message and quit.') {
|
||||
puts parser.help
|
||||
exit 1
|
||||
}
|
||||
begin
|
||||
parser.parse!
|
||||
rescue OptionParser::ParseError => err
|
||||
$stderr.puts err.message
|
||||
$stderr.puts parser.help
|
||||
exit 1
|
||||
end
|
||||
if ARGV.empty?
|
||||
$stderr.puts 'no input'
|
||||
exit 1
|
||||
end
|
||||
if ARGV.size > 1
|
||||
$stderr.puts 'too many input'
|
||||
exit 1
|
||||
end
|
||||
input = ARGV[0]
|
||||
|
||||
begin
|
||||
result = YaccFileParser.parse_file(input)
|
||||
File.open(output || "#{input}.racc", 'w') {|f|
|
||||
convert cname, result, f
|
||||
}
|
||||
rescue SystemCallError => err
|
||||
$stderr.puts err.message
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
def convert(classname, result, f)
|
||||
init_indent = 'token'.size
|
||||
f.puts %<# Converted from "#{result.filename}" by y2racc version #{Racc::Version}>
|
||||
f.puts
|
||||
f.puts "class #{classname}"
|
||||
unless result.terminals.empty?
|
||||
f.puts
|
||||
f.print 'token'
|
||||
columns = init_indent
|
||||
result.terminals.each do |t|
|
||||
if columns > 60
|
||||
f.puts
|
||||
f.print ' ' * init_indent
|
||||
columns = init_indent
|
||||
end
|
||||
columns += f.write(" #{t}")
|
||||
end
|
||||
f.puts
|
||||
end
|
||||
unless result.precedence_table.empty?
|
||||
f.puts
|
||||
f.puts 'preclow'
|
||||
result.precedence_table.each do |assoc, toks|
|
||||
f.printf " %-8s %s\n", assoc, toks.join(' ') unless toks.empty?
|
||||
end
|
||||
f.puts 'prechigh'
|
||||
end
|
||||
if result.start
|
||||
f.puts
|
||||
f.puts "start #{@start}"
|
||||
end
|
||||
|
||||
f.puts
|
||||
f.puts 'rule'
|
||||
texts = @with_action ? result.grammar : result.grammar_without_actions
|
||||
texts.each do |text|
|
||||
f.print text
|
||||
end
|
||||
|
||||
if @with_header and result.header
|
||||
f.puts
|
||||
f.puts '---- header'
|
||||
f.puts result.header
|
||||
end
|
||||
if @with_usercode and result.usercode
|
||||
f.puts
|
||||
f.puts '---- footer'
|
||||
f.puts result.usercode
|
||||
end
|
||||
end
|
||||
|
||||
class ParseError < StandardError; end
|
||||
|
||||
class StringScanner_withlineno
|
||||
def initialize(src)
|
||||
@s = StringScanner.new(src)
|
||||
@lineno = 1
|
||||
end
|
||||
|
||||
extend Forwardable
|
||||
def_delegator "@s", :eos?
|
||||
def_delegator "@s", :rest
|
||||
|
||||
attr_reader :lineno
|
||||
|
||||
def scan(re)
|
||||
advance_lineno(@s.scan(re))
|
||||
end
|
||||
|
||||
def scan_until(re)
|
||||
advance_lineno(@s.scan_until(re))
|
||||
end
|
||||
|
||||
def skip(re)
|
||||
str = advance_lineno(@s.scan(re))
|
||||
str ? str.size : nil
|
||||
end
|
||||
|
||||
def getch
|
||||
advance_lineno(@s.getch)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def advance_lineno(str)
|
||||
@lineno += str.count("\n") if str
|
||||
str
|
||||
end
|
||||
end
|
||||
|
||||
class YaccFileParser
|
||||
|
||||
Result = Struct.new(:terminals, :precedence_table, :start,
|
||||
:header, :grammar, :usercode, :filename)
|
||||
class Result # reopen
|
||||
def initialize
|
||||
super
|
||||
self.terminals = []
|
||||
self.precedence_table = []
|
||||
self.start = nil
|
||||
self.grammar = []
|
||||
self.header = nil
|
||||
self.usercode = nil
|
||||
self.filename = nil
|
||||
end
|
||||
|
||||
def grammar_without_actions
|
||||
grammar().map {|text| text[0,1] == '{' ? '{}' : text }
|
||||
end
|
||||
end
|
||||
|
||||
def YaccFileParser.parse_file(filename)
|
||||
new().parse(File.read(filename), filename)
|
||||
end
|
||||
|
||||
def parse(src, filename = '-')
|
||||
@result = Result.new
|
||||
@filename = filename
|
||||
@result.filename = filename
|
||||
s = StringScanner_withlineno.new(src)
|
||||
parse_header s
|
||||
parse_grammar s
|
||||
@result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
COMMENT = %r</\*[^*]*\*+(?:[^/*][^*]*\*+)*/>
|
||||
CHAR = /'((?:[^'\\]+|\\.)*)'/
|
||||
STRING = /"((?:[^"\\]+|\\.)*)"/
|
||||
|
||||
def parse_header(s)
|
||||
skip_until_percent s
|
||||
until s.eos?
|
||||
case
|
||||
when t = s.scan(/left/)
|
||||
@result.precedence_table.push ['left', scan_symbols(s)]
|
||||
when t = s.scan(/right/)
|
||||
@result.precedence_table.push ['right', scan_symbols(s)]
|
||||
when t = s.scan(/nonassoc/)
|
||||
@result.precedence_table.push ['nonassoc', scan_symbols(s)]
|
||||
when t = s.scan(/token/)
|
||||
list = scan_symbols(s)
|
||||
list.shift if /\A<(.*)>\z/ =~ list[0]
|
||||
@result.terminals.concat list
|
||||
when t = s.scan(/start/)
|
||||
@result.start = scan_symbols(s)[0]
|
||||
when s.skip(%r<(?:
|
||||
type | union | expect | thong | binary |
|
||||
semantic_parser | pure_parser | no_lines |
|
||||
raw | token_table
|
||||
)\b>x)
|
||||
skip_until_percent s
|
||||
when s.skip(/\{/) # header (%{...%})
|
||||
str = s.scan_until(/\%\}/)
|
||||
str.chop!
|
||||
str.chop!
|
||||
@result.header = str
|
||||
skip_until_percent s
|
||||
when s.skip(/\%/) # grammar (%%...)
|
||||
return
|
||||
else
|
||||
raise ParseError, "#{@filename}:#{s.lineno}: scan error"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def skip_until_percent(s)
|
||||
until s.eos?
|
||||
s.skip /[^\%\/]+/
|
||||
next if s.skip(COMMENT)
|
||||
return if s.getch == '%'
|
||||
end
|
||||
end
|
||||
|
||||
def scan_symbols(s)
|
||||
list = []
|
||||
until s.eos?
|
||||
s.skip /\s+/
|
||||
if s.skip(COMMENT)
|
||||
;
|
||||
elsif t = s.scan(CHAR)
|
||||
list.push t
|
||||
elsif t = s.scan(STRING)
|
||||
list.push t
|
||||
elsif s.skip(/\%/)
|
||||
break
|
||||
elsif t = s.scan(/\S+/)
|
||||
list.push t
|
||||
else
|
||||
raise ParseError, "#{@filename}:#{@lineno}: scan error"
|
||||
end
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
def parse_grammar(s)
|
||||
buf = []
|
||||
until s.eos?
|
||||
if t = s.scan(/[^%'"{\/]+/)
|
||||
buf.push t
|
||||
break if s.eos?
|
||||
end
|
||||
if s.skip(/\{/)
|
||||
buf.push scan_action(s)
|
||||
elsif t = s.scan(/'(?:[^'\\]+|\\.)*'/) then buf.push t
|
||||
elsif t = s.scan(/"(?:[^"\\]+|\\.)*"/) then buf.push t
|
||||
elsif t = s.scan(COMMENT) then buf.push t
|
||||
elsif s.skip(/%prec\b/) then buf.push '='
|
||||
elsif s.skip(/%%/)
|
||||
@result.usercode = s.rest
|
||||
break
|
||||
else
|
||||
buf.push s.getch
|
||||
end
|
||||
end
|
||||
@result.grammar = buf
|
||||
end
|
||||
|
||||
def scan_action(s)
|
||||
buf = '{'
|
||||
nest = 1
|
||||
until s.eos?
|
||||
if t = s.scan(%r<[^/{}'"]+>)
|
||||
buf << t
|
||||
break if s.eos?
|
||||
elsif t = s.scan(COMMENT)
|
||||
buf << t
|
||||
elsif t = s.scan(CHAR)
|
||||
buf << t
|
||||
elsif t = s.scan(STRING)
|
||||
buf << t
|
||||
else
|
||||
c = s.getch
|
||||
buf << c
|
||||
case c
|
||||
when '{'
|
||||
nest += 1
|
||||
when '}'
|
||||
nest -= 1
|
||||
return buf if nest == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
$stderr.puts "warning: unterminated action in #{@filename}"
|
||||
buf
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
unless Object.method_defined?(:funcall)
|
||||
class Object
|
||||
alias funcall __send__
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
main
|
Loading…
Add table
Add a link
Reference in a new issue