home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ruby164.zip / rbemx164.zip / ruby / share / doc / racc-1.3.9 / misc / racc2y next >
Text File  |  2001-04-07  |  5KB  |  268 lines

  1. #!/usr/local/bin/ruby
  2. #
  3. # r2yacc  ---  racc to yacc converter
  4. #
  5. #   Copyright (c) 1999-2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
  6. #
  7. #   This program is feee software.
  8. #   You can distribute/modify this program under the terms of
  9. #   the GNU Lesser General Public License version 2 or later.
  10. #
  11.  
  12. require 'getopts'
  13. require 'racc/compiler'
  14.  
  15.  
  16. class R
  17.  
  18.   Version = '1.1.0'
  19.  
  20.  
  21.   def initialize
  22.     @symboltable = Racc::SymbolTable.new( self )
  23.     @ruletable   = Racc::RuleTable.new( self )
  24.     @parser      = Racc::RaccParser.new( self )
  25.   end
  26.  
  27.   attr :ruletable
  28.   attr :symboltable
  29.   attr :parser
  30.  
  31.   def debug()   false end
  32.   def verbose() false end
  33.   def d_parse() false end
  34.   def d_token() false end
  35.   def d_rule()  false end
  36.   def d_state() false end
  37.  
  38.  
  39.   ###
  40.   ### parse
  41.   ###
  42.  
  43.   def parse( str, fname )
  44.     @fname = fname
  45.     @parser.parse( str )
  46.     @ruletable.init
  47.  
  48.     u = Racc::RaccParser.get_ucode( fname )
  49.     @header, = u['header']
  50.     @inner,  = u['inner']
  51.     @footer, = u['footer']
  52.   end
  53.  
  54.  
  55.   ###
  56.   ### output
  57.   ###
  58.  
  59.   def output( f )
  60.     rule = t = nil
  61.  
  62.     f.print <<SRC
  63. /*
  64.  
  65.     generated from #{@fname} by racc2y version #{R::Version}
  66.  
  67. */
  68.  
  69. SRC
  70.     if $OPT_H and @header then
  71.       f.puts '%{'
  72.       f.puts '/*---- header ----*/'
  73.       f.puts @header
  74.       f.puts '%}'
  75.       f.puts
  76.     end
  77.  
  78.     output_defs f
  79.     output_grammer f
  80.  
  81.     if $OPT_I and @inner then
  82.       f.puts
  83.       f.puts '/*---- inner ----*/'
  84.       f.puts
  85.       f.puts @inner
  86.     end
  87.     if $OPT_F and @footer then
  88.       f.puts
  89.       f.puts '/*---- footer ----*/'
  90.       f.puts
  91.       f.puts @footer
  92.     end
  93.   end
  94.  
  95.   def output_defs( f )
  96.     output_token f
  97.     f.puts
  98.     prec = getprecs
  99.     unless prec.empty? then
  100.       output_prec f, prec
  101.     end
  102.   end
  103.  
  104.   def output_token( f )
  105.     f.puts '/* tokens */'
  106.     anc = @symboltable.anchor
  107.     err = @symboltable.error
  108.     total = 6
  109.     f.print '%token'
  110.     @symboltable.each do |t|
  111.       next unless t.terminal?
  112.       next if t.dummy?
  113.       next if t == err
  114.       next if t == anc
  115.  
  116.       unless String === t.value then
  117.         if total > 60 then
  118.           f.print "\n     "
  119.           total = 0
  120.         end
  121.         total += f.write( " #{tok t}" )
  122.       end
  123.     end
  124.     f.puts
  125.   end
  126.  
  127.   def getprecs
  128.     prec = []
  129.     @symboltable.each do |t|
  130.       next unless t.prec
  131.       if a = prec[t.prec] then
  132.         a.push t
  133.       else
  134.         prec[t.prec] = [t.assoc, t]
  135.       end
  136.     end
  137.  
  138.     prec
  139.   end
  140.  
  141.   def output_prec( f, tab )
  142.     f.puts '/* precedance table */'
  143.     tab.each do |a|
  144.       if a then
  145.         f.printf '%%%-8s', a.shift.id2name.downcase
  146.         a.each do |t|
  147.           f.print ' ', tok(t)
  148.         end
  149.         f.puts
  150.       end
  151.     end
  152.     f.puts
  153.   end
  154.  
  155.  
  156.   def output_grammer( f )
  157.     f.puts '%%'
  158.  
  159.     targ   = nil
  160.     indent = 10
  161.     fmt    = "\n%-10s:"
  162.     emb    = []
  163.  
  164.     @ruletable.each do |rule|
  165.       if rule.target.dummy? then
  166.         emb.push rule.action if rule.action
  167.         next
  168.       end
  169.  
  170.       if rule.target == targ then
  171.         f.print ' ' * indent, '|'
  172.       else
  173.         targ = rule.target
  174.         f.printf fmt, tok(targ)
  175.       end
  176.       rule.symbols.each do |t|
  177.         if t.dummy? then   # target of dummy rule for embedded action
  178.           f.puts
  179.           output_act f,
  180.                      emb.shift,
  181.                      indent
  182.           f.print ' ' * (indent + 1)
  183.         else
  184.           f.print ' ', tok(t)
  185.         end
  186.       end
  187.       if rule.specified_prec then
  188.         f.print ' %prec ', tok(rule.specified_prec)
  189.       end
  190.       f.puts
  191.       if rule.action then
  192.         output_act f, rule.action, indent
  193.       end
  194.     end
  195.  
  196.     f.puts "\n%%"
  197.   end
  198.  
  199.   def output_act( f, str, indent )
  200.     f.print ' ' * (indent + 4), "{\n"
  201.     f.print ' ' * (indent + 6), str, "\n" unless $OPT_A
  202.     f.print ' ' * (indent + 4), "}\n"
  203.   end
  204.  
  205.   def tok( t )
  206.     s = t.to_s
  207.     s.gsub '"', "'"
  208.   end
  209.  
  210. end   # class R
  211.  
  212.  
  213. def usage( stat = 0 )
  214.   if stat != 0 then
  215.     $stderr.puts 'wrong option'
  216.   end
  217.   $stderr.print <<MSG
  218.  
  219. racc2y version #{R::Version}
  220.  
  221. usage:
  222.  
  223.     racc2y [-AHIF] [-o outfile] raccfile
  224.  
  225.     -o <file>  output file name  [y.<inputfile>]
  226.     -A         did not output actions
  227.     -H         output 'header'
  228.     -I         output 'inner'
  229.     -F         output 'footer'
  230.  
  231. MSG
  232.   exit stat
  233. end
  234.  
  235. unless getopts( 'AHIF', 'o:', 'version', 'help', 'copyright' ) then
  236.   usage 1
  237. end
  238. if $OPT_version then
  239.   $stderr.puts "racc2y version #{R::Version}"
  240.   exit 0
  241. end
  242. if $OPT_help then
  243.   usage 0
  244. end
  245. if $OPT_copyright then
  246.   $stderr.puts "Copyright (c) 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>"
  247.   exit 0
  248. end
  249. unless ARGV.size == 1 then
  250.   usage 1
  251. end
  252.  
  253.  
  254. fname = ARGV[0]
  255. outf = $OPT_o || 'y.' + fname
  256. begin
  257.   str = nil
  258.   File.open( fname ) {|f| str = f.read }
  259. rescue Errno::ENOENT
  260.   $stderr.puts "#{File.basename $0}: no such file: #{fname}"
  261.   exit 1
  262. end
  263. r = R.new
  264. r.parse( str, fname )
  265. File.open( outf, 'w' ) do |f|
  266.   r.output f
  267. end
  268.