Class: Lrama::State::InadequacyAnnotation

Inherits:
Object
  • Object
show all
Defined in:
lib/lrama/state/inadequacy_annotation.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(state, token, actions, contribution_matrix) ⇒ InadequacyAnnotation

Returns a new instance of InadequacyAnnotation.



16
17
18
19
20
21
# File 'lib/lrama/state/inadequacy_annotation.rb', line 16

def initialize(state, token, actions, contribution_matrix)
  @state = state
  @token = token
  @actions = actions
  @contribution_matrix = contribution_matrix
end

Instance Attribute Details

#actionsObject

: Array



12
13
14
# File 'lib/lrama/state/inadequacy_annotation.rb', line 12

def actions
  @actions
end

#contribution_matrixObject

: Hash[action, Hash[Item, bool]]



13
14
15
# File 'lib/lrama/state/inadequacy_annotation.rb', line 13

def contribution_matrix
  @contribution_matrix
end

#stateObject

@rbs!

type action = Action::Shift | Action::Reduce


10
11
12
# File 'lib/lrama/state/inadequacy_annotation.rb', line 10

def state
  @state
end

#tokenObject

: Grammar::Symbol



11
12
13
# File 'lib/lrama/state/inadequacy_annotation.rb', line 11

def token
  @token
end

Instance Method Details

#contributed?(item) ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/lrama/state/inadequacy_annotation.rb', line 24

def contributed?(item)
  @contribution_matrix.any? {|action, contributions| !contributions.nil? && contributions[item] }
end

#dominant_contribution(lookaheads) ⇒ Object

Definition 3.42 (dominant_contribution)



43
44
45
46
47
48
49
50
# File 'lib/lrama/state/inadequacy_annotation.rb', line 43

def dominant_contribution(lookaheads)
  actions = @actions.select {|action|
    contribution_matrix[action].nil? || contribution_matrix[action].any? {|item, contributed| contributed && lookaheads[item].include?(@token) }
  }
  return nil if actions.empty?

  resolve_conflict(actions)
end

#merge_matrix(another_matrixes) ⇒ Object



29
30
31
32
33
34
35
36
37
38
# File 'lib/lrama/state/inadequacy_annotation.rb', line 29

def merge_matrix(another_matrixes)
  another_matrixes.each do |another_matrix|
    @contribution_matrix.merge!(another_matrix) {|action, contributions, another_contributions|
      next contributions if another_contributions.nil?
      next another_contributions if contributions.nil?

      contributions.merge!(another_contributions) {|_, contributed, another_contributed| contributed || another_contributed }
    }
  end
end

#resolve_conflict(actions) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/lrama/state/inadequacy_annotation.rb', line 53

def resolve_conflict(actions)
  # @type var shifts: Array[Action::Shift]
  # @type var reduces: Array[Action::Reduce]
  shifts = actions.select {|action| action.is_a?(Action::Shift)}
  reduces = actions.select {|action| action.is_a?(Action::Reduce) }

  shifts.each do |shift|
    reduces.each do |reduce|
      sym = shift.next_sym

      shift_prec = sym.precedence
      reduce_prec = reduce.item.rule.precedence

      # Can resolve only when both have prec
      unless shift_prec && reduce_prec
        next
      end

      case
      when shift_prec < reduce_prec
        # Reduce is selected
        actions.delete(shift)
        next
      when shift_prec > reduce_prec
        # Shift is selected
        actions.delete(reduce)
        next
      end

      # shift_prec == reduce_prec, then check associativity
      case sym.precedence&.type
      when :precedence
        # %precedence only specifies precedence and not specify associativity
        # then a conflict is unresolved if precedence is same.
        next
      when :right
        # Shift is selected
        actions.delete(reduce)
        next
      when :left
        # Reduce is selected
        actions.delete(shift)
        next
      when :nonassoc
        # Can not resolve
        #
        # nonassoc creates "run-time" error, precedence creates "compile-time" error.
        # Then omit both the shift and reduce.
        #
        # https://www.gnu.org/software/bison/manual/html_node/Using-Precedence.html
        actions.delete(shift)
        actions.delete(reduce)
      else
        raise "Unknown precedence type. #{sym}"
      end
    end
  end

  actions
end

#to_sObject



115
116
117
# File 'lib/lrama/state/inadequacy_annotation.rb', line 115

def to_s
  "State: #{@state.id}, Token: #{@token.id.s_value}, Actions: #{actions_to_s}, Contributions: #{contribution_matrix_to_s}"
end