Sha256: f649e465e1cd2d6bb398e3865b3f6a87812611c4fc894021448907f5daa03c99

Contents?: true

Size: 1.91 KB

Versions: 1

Compression:

Stored size: 1.91 KB

Contents

module Antelope
  module Generation

    class UnresolvableConflictError < StandardError; end

    class Tableizer

      attr_accessor :parser
      attr_accessor :table
      attr_accessor :rules

      def initialize(parser)
        @parser = parser
      end

      def call
        tablize
        conflictize
      end

      def tablize
        @table = Array.new(parser.states.size) do
          Hash.new { |h, k| h[k] = [] }
        end
        @rules = []

        parser.states.each do |state|
          state.transitions.each do |on, to|
            table[state.id][on] << [:state, to.id]
          end

          state.rules.each do |rule|
            @rules[rule.id] = rule
            if rule.final?
              rule.lookahead.each do |look|
                table[state.id][look.name] <<
                  [:reduce, rule.production.id]
              end

              if rule.production.id.zero?
                table[state.id][:"$"] = [[:accept, rule.production.id]]
              end
            end
          end
        end

        table
      end

      def conflictize
        @table.each_with_index do |v, state|
          v.each do |on, data|
            if data.size == 1
              @table[state][on] = data[0]
              next
            end

            terminal = parser.presidence_for(on)

            state_part = data.select { |(t, d)| t == :state }.first
            rule_part  = data.select { |(t, d)| t == :reduce}.first

            result = @rules[rule_part[1]].presidence <=> terminal

            case result
            when 0
              p v, terminal, @rules[rule_part[1]].presidence
              raise UnresolvableConflictError,
                "Could not determine move for #{on} in state #{state}"
            when 1
              @table[state][on] = rule_part
            when -1
              @table[state][on] = state_part
            end
          end
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
antelope-0.0.1 lib/antelope/generation/tableizer.rb