Class: Ibex::Runtime::RepairSearch

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/runtime/repair_search.rb

Overview

Bounded Dijkstra search over LR state stacks. Semantic actions never run. rubocop:disable Metrics/ClassLength -- queue policy and LR transitions form one bounded search invariant.

Defined Under Namespace

Classes: Configuration

Constant Summary collapse

NEED_INPUT =

@rbs! type configuration_key = [Array[Integer], Integer, Integer, bool] type priority = Array type lookup_table = Tables::action_table | Tables::goto_table type lookup_value = IR::runtime_action | Integer?

Object.new.freeze
LIMIT =

: Object

Object.new.freeze

Instance Method Summary collapse

Constructor Details

#initialize(tables, policy, tokens, complete:) ⇒ RepairSearch

Returns a new instance of RepairSearch.



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ibex/runtime/repair_search.rb', line 40

def initialize(tables, policy, tokens, complete:)
  @tables = tables
  @policy = policy
  @tokens = tokens
  @complete = complete
  @configurations = 0
  @heap = RepairPriorityQueue.new
  @best = {}
  reserved = [Parser::EOF_TOKEN, Parser::ERROR_TOKEN]
  token_names = tables.fetch(:token_names) #: Hash[Integer, String]
  @candidate_ids = token_names.keys.reject { |id| reserved.include?(id) }.sort.freeze
end

Instance Method Details

#search(state_stack) ⇒ Object

Compatibility projection used by the semantic runtime path.



55
56
57
58
59
60
61
# File 'lib/ibex/runtime/repair_search.rb', line 55

def search(state_stack)
  result = search_result(state_stack)
  return result.plan if result.selected?
  return NEED_INPUT if result.status == :need_input

  nil
end

#search_result(state_stack) ⇒ Object

Preserve the bounded outcome for syntax tooling and diagnostics.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ibex/runtime/repair_search.rb', line 65

def search_result(state_stack)
  empty_edits = [] #: Array[RepairEdit]
  push(
    Configuration.new(
      stack: state_stack.dup.freeze,
      input_index: 0,
      shifts: 0,
      cost: 0,
      edits: empty_edits.freeze,
      goal: false
    )
  )
  needs_input = false
  until @heap.empty?
    configuration = pop
    return outcome(:exhausted) if configuration.equal?(LIMIT)
    next unless configuration.is_a?(Configuration)

    result = visit(configuration)
    return outcome(:exhausted) if result.equal?(LIMIT)
    return outcome(:selected, plan: result) if result.is_a?(RepairPlan)

    needs_input = true if result.equal?(NEED_INPUT)
  end
  outcome(needs_input ? :need_input : :not_found)
end