Class: Ibex::ErrorMessages::SentenceSearch

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/error_messages/sentence_search.rb

Overview

Finds deterministic shortest token sentences that reach each syntax error state without running semantic actions.

Defined Under Namespace

Classes: Witness

Constant Summary collapse

DEFAULT_MAX_TOKENS =

: Integer

LALR::ConflictSearchLimits::DEFAULT_MAX_TOKENS
DEFAULT_MAX_CONFIGURATIONS =

: Integer

LALR::ConflictSearchLimits::DEFAULT_MAX_CONFIGURATIONS

Instance Method Summary collapse

Constructor Details

#initialize(automaton, max_tokens: DEFAULT_MAX_TOKENS, max_configurations: DEFAULT_MAX_CONFIGURATIONS) ⇒ SentenceSearch

Returns a new instance of SentenceSearch.



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ibex/error_messages/sentence_search.rb', line 29

def initialize(automaton, max_tokens: DEFAULT_MAX_TOKENS,
               max_configurations: DEFAULT_MAX_CONFIGURATIONS)
  LALR::ConflictSearchLimits.validate!(
    max_tokens: max_tokens, max_configurations: max_configurations
  )
  @automaton = automaton
  @grammar = automaton.grammar
  @max_tokens = max_tokens
  @max_configurations = max_configurations
  @candidates = grammar_terminals
  @input_candidates = @candidates.reject { |symbol| symbol.id.zero? }
  @explored = 0
end

Instance Method Details

#allObject



44
45
46
47
48
49
50
51
52
# File 'lib/ibex/error_messages/sentence_search.rb', line 44

def all
  targets = ErrorMessages.error_states(@automaton).to_h { |state| [state.id, true] }
  witnesses = {} #: Hash[Integer, Witness]
  @automaton.entry_states.each do |entry, initial_state|
    search_entry(entry, initial_state, targets, witnesses)
    break if witnesses.length == targets.length
  end
  witnesses.sort.to_h.freeze
end

#state_for(tokens, entry: nil) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/ibex/error_messages/sentence_search.rb', line 55

def state_for(tokens, entry: nil)
  return nil if tokens.empty?

  start = entry || @grammar.start
  initial = @automaton.entry_states[start]
  return nil unless initial

  states = [initial]
  tokens.each_with_index do |name, index|
    status, value = consume_sentence_token(states, name, index == tokens.length - 1)
    return value if status == :error && value.is_a?(Integer)
    return nil unless status == :continue && value.is_a?(Array)

    states = value
  end
  nil
end