Class: Ibex::Impact::Seeds

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/impact/seeds.rb,
sig/ibex/impact/seeds.rbs

Overview

Converts command-line symbols and Diff rule ids into analysis seeds.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grammar, names, origin: "symbol") ⇒ Seeds

Returns a new instance of Seeds.

RBS:

  • (IR::Grammar grammar, Array[String] names, ?origin: String) -> void

Parameters:

  • grammar (IR::Grammar)
  • names (Array[String])
  • origin: (String) (defaults to: "symbol")


16
17
18
19
20
21
22
23
# File 'lib/ibex/impact/seeds.rb', line 16

def initialize(grammar, names, origin: "symbol")
  @grammar = grammar
  @sets = Analysis::Sets.new(grammar)
  @records = names.flat_map { |name| resolve(name, origin) }.sort_by { |record| seed_symbol(record) }
  @ids = @records.map { |record| seed_id(record) }.uniq.freeze
  @records = @records.freeze
  freeze
end

Instance Attribute Details

#idsArray[Integer] (readonly)

RBS:

  • @grammar: IR::Grammar

  • @sets: Analysis::Sets

  • @records: Array[Hash[Symbol, Object?]]

  • @ids: Array[Integer]

Returns:

  • (Array[Integer])


12
13
14
# File 'lib/ibex/impact/seeds.rb', line 12

def ids
  @ids
end

#recordsArray[Hash[Symbol, Object?]] (readonly)

Signature:

  • Array[Hash[Symbol, Object?]]

Returns:

  • (Array[Hash[Symbol, Object?]])


13
14
15
# File 'lib/ibex/impact/seeds.rb', line 13

def records
  @records
end

Class Method Details

.from_diff(grammar, diff, origin: "diff") ⇒ Seeds

RBS:

  • (IR::Grammar grammar, Hash[Symbol, Object?] diff, ?origin: String) -> Seeds

Parameters:

  • grammar (IR::Grammar)
  • diff (Hash[Symbol, Object?])
  • origin: (String) (defaults to: "diff")

Returns:



26
27
28
29
30
31
32
33
# File 'lib/ibex/impact/seeds.rb', line 26

def self.from_diff(grammar, diff, origin: "diff")
  rules = diff.fetch(:rules) #: Hash[Symbol, Object?]
  names = %i[added removed changed].flat_map do |section|
    records = rules.fetch(section) #: Array[Hash[Symbol, Object?]]
    records.map { |record| record.fetch(:id).to_s }
  end.uniq.sort
  new(grammar, names, origin: origin)
end

Instance Method Details

#nullable_boundary?(id) ⇒ Boolean

RBS:

  • (Integer) -> bool

Parameters:

  • (Integer)

Returns:

  • (Boolean)


58
59
60
61
62
63
64
65
66
# File 'lib/ibex/impact/seeds.rb', line 58

def nullable_boundary?(id)
  return true if @sets.nullable?(id)

  @grammar.productions.any? do |production|
    production.rhs.include?(id) && production.rhs.any? do |symbol_id|
      @grammar.symbol_by_id(symbol_id)&.nonterminal? && @sets.nullable?(symbol_id)
    end
  end
end

#resolve(name, origin) ⇒ Array[Hash[Symbol, Object?]]

RBS:

  • (String name, String origin) -> Array[Hash[Symbol, Object?]]

Parameters:

  • name (String)
  • origin (String)

Returns:

  • (Array[Hash[Symbol, Object?]])


48
49
50
51
52
53
54
55
# File 'lib/ibex/impact/seeds.rb', line 48

def resolve(name, origin)
  definition = @grammar.symbol(name)
  raise Ibex::Error, "(impact):1:1: unknown symbol #{name}" unless definition
  raise Ibex::Error, "(impact):1:1: impact seed #{name} is not a nonterminal" unless definition.nonterminal?

  [{ symbol: definition.name, id: definition.id, origin: origin,
     nullable_boundary: nullable_boundary?(definition.id) }]
end

#seed_id(record) ⇒ Integer

RBS:

  • (Hash[Symbol, Object?] record) -> Integer

Parameters:

  • record (Hash[Symbol, Object?])

Returns:

  • (Integer)


43
44
45
# File 'lib/ibex/impact/seeds.rb', line 43

def seed_id(record)
  record.fetch(:id) #: Integer
end

#seed_symbol(record) ⇒ String

RBS:

  • (Hash[Symbol, Object?] record) -> String

Parameters:

  • record (Hash[Symbol, Object?])

Returns:

  • (String)


38
39
40
# File 'lib/ibex/impact/seeds.rb', line 38

def seed_symbol(record)
  record.fetch(:symbol) #: String
end