# class Racc::LogFileGenerator

### Public Class Methods

new(states, debug_flags = DebugFlags.new) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 17
    def initialize(states, debug_flags = DebugFlags.new)
      @states = states
      @grammar = states.grammar
      @debug_flags = debug_flags
    end

### Public Instance Methods

action_out(f, state) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 92
    def action_out(f, state)
      sr = state.srconf && state.srconf.dup
      rr = state.rrconf && state.rrconf.dup
      acts = state.action
      keys = acts.keys
      keys.sort! {|a,b| a.ident <=> b.ident }

      [ Shift, Reduce, Error, Accept ].each do |klass|
        keys.delete_if do |tok|
          act = acts[tok]
          if act.kind_of?(klass)
            outact f, tok, act
            if sr and c = sr.delete(tok)
              outsrconf f, c
            end
            if rr and c = rr.delete(tok)
              outrrconf f, c
            end

            true
          else
            false
          end
        end
      end
      sr.each {|tok, c| outsrconf f, c } if sr
      rr.each {|tok, c| outrrconf f, c } if rr

      act = state.defact
      if not act.kind_of?(Error) or @debug_flags.any?
        outact f, '$default', act
      end

      f.puts
      state.goto_table.each do |t, st|
        if t.nonterminal?
          f.printf "  %-12s  go to state %d\n", t.to_s, st.ident
        end
      end
    end

outact(f, t, act) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 133
    def outact(f, t, act)
      case act
      when Shift
        f.printf "  %-12s  shift, and go to state %d\n",
                 t.to_s, act.goto_id
      when Reduce
        f.printf "  %-12s  reduce using rule %d (%s)\n",
                 t.to_s, act.ruleid, act.rule.target.to_s
      when Accept
        f.printf "  %-12s  accept\n", t.to_s
      when Error
        f.printf "  %-12s  error\n", t.to_s
      else
        raise "racc: fatal: wrong act for outact: act=#{act}(#{act.class})"
      end
    end

output(out) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 23
    def output(out)
      output_conflict out; out.puts
      output_useless  out; out.puts
      output_rule     out; out.puts
      output_token    out; out.puts
      output_state    out
    end

output_conflict(out) click to toggle source

Warnings

    # File lib/racc/logfilegenerator.rb, line 35
    def output_conflict(out)
      @states.each do |state|
        if state.srconf
          out.printf "state %d contains %d shift/reduce conflicts\n",
                     state.stateid, state.srconf.size
        end
        if state.rrconf
          out.printf "state %d contains %d reduce/reduce conflicts\n",
                     state.stateid, state.rrconf.size
        end
      end
    end

output_rule(out) click to toggle source

Rules

    # File lib/racc/logfilegenerator.rb, line 170
    def output_rule(out)
      out.print "-------- Grammar --------\n\n"
      @grammar.each do |rl|
        if @debug_flags.any? or rl.ident != 0
          out.printf "rule %d %s: %s\n",
                     rl.ident, rl.target.to_s, rl.symbols.join(' ')
        end
      end
    end

output_state(out) click to toggle source

`States`

    # File lib/racc/logfilegenerator.rb, line 66
    def output_state(out)
      out << "--------- State ---------\n"

      showall = @debug_flags.la || @debug_flags.state
      @states.each do |state|
        out << "\nstate #{state.ident}\n\n"

        (showall ? state.closure : state.core).each do |ptr|
          pointer_out(out, ptr) if ptr.rule.ident != 0 or showall
        end
        out << "\n"

        action_out out, state
      end
    end

output_token(out) click to toggle source

Tokens

    # File lib/racc/logfilegenerator.rb, line 184
        def output_token(out)
          out.print "------- Symbols -------\n\n"

          out.print "**Nonterminals, with rules where they appear\n\n"
          @grammar.each_nonterminal do |t|
            tmp = <<SRC
      %s (%d)
        on right: %s
        on left : %s
    SRC
            out.printf tmp, t.to_s, t.ident,
                       symbol_locations(t.locate).join(' '),
                       symbol_locations(t.heads).join(' ')
          end

          out.print "\n**Terminals, with rules where they appear\n\n"
          @grammar.each_terminal do |t|
            out.printf "  %s (%d) %s\n",
                       t.to_s, t.ident, symbol_locations(t.locate).join(' ')
          end
        end

output_useless(out) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 48
    def output_useless(out)
      @grammar.each do |rl|
        if rl.useless?
          out.printf "rule %d (%s) never reduced\n",
                     rl.ident, rl.target.to_s
        end
      end
      @grammar.each_nonterminal do |t|
        if t.useless?
          out.printf "useless nonterminal %s\n", t.to_s
        end
      end
    end

outrrconf(f, confs) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 158
    def outrrconf(f, confs)
      confs.each do |c|
        r = c.low_prec
        f.printf "  %-12s  [reduce using rule %d (%s)]\n",
                 c.token.to_s, r.ident, r.target.to_s
      end
    end

outsrconf(f, confs) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 150
    def outsrconf(f, confs)
      confs.each do |c|
        r = c.reduce
        f.printf "  %-12s  [reduce using rule %d (%s)]\n",
                 c.shift.to_s, r.ident, r.target.to_s
      end
    end

pointer_out(out, ptr) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 82
    def pointer_out(out, ptr)
      buf = sprintf("%4d) %s :", ptr.rule.ident, ptr.rule.target.to_s)
      ptr.rule.symbols.each_with_index do |tok, idx|
        buf << ' _' if idx == ptr.index
        buf << ' ' << tok.to_s
      end
      buf << ' _' if ptr.reduce?
      out.puts buf
    end

symbol_locations(locs) click to toggle source

    # File lib/racc/logfilegenerator.rb, line 206
    def symbol_locations(locs)
      locs.map {|loc| loc.rule.ident }.reject {|n| n == 0 }.uniq
    end