summaryrefslogtreecommitdiff
path: root/libexec/y2racc
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/y2racc')
-rwxr-xr-xlibexec/y2racc339
1 files changed, 0 insertions, 339 deletions
diff --git a/libexec/y2racc b/libexec/y2racc
deleted file mode 100755
index 7933f94153..0000000000
--- a/libexec/y2racc
+++ /dev/null
@@ -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