Class: Aurum::Builder::State

Inherits:
Array
  • Object
show all
Defined in:
lib/aurum/grammar/builder/set_of_items.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(augmented_grammar, items) ⇒ State

Returns a new instance of State.



40
41
42
43
44
45
46
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 40

def initialize augmented_grammar, items
  @augmented_grammar = augmented_grammar
  super(kernels_of_closure(items))
  @handles = find_all {|item| item.handle?}
  @actions, @goto_states, @predecessors, @expect_symbols = Hash.new([]), {}, {}, []
  @all_items.each {|item| @expect_symbols << item.dot_symbol unless item.handle?}        
end

Instance Attribute Details

#actionsObject (readonly)

Returns the value of attribute actions.



39
40
41
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 39

def actions
  @actions
end

#all_itemsObject (readonly)

Returns the value of attribute all_items.



39
40
41
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 39

def all_items
  @all_items
end

#expect_symbolsObject (readonly)

Returns the value of attribute expect_symbols.



39
40
41
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 39

def expect_symbols
  @expect_symbols
end

#handlesObject (readonly)

Returns the value of attribute handles.



39
40
41
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 39

def handles
  @handles
end

#indexObject

Returns the value of attribute index.



38
39
40
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 38

def index
  @index
end

Instance Method Details

#add_action(symbol, action) ⇒ Object



90
91
92
93
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 90

def add_action symbol, action
  @actions[symbol] = [] unless @actions.has_key?(symbol)
  @actions[symbol] << action unless @actions[symbol].include?(action)
end

#add_lookahead_shift(symbol, state) ⇒ Object



85
86
87
88
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 85

def add_lookahead_shift symbol, state
  add_goto_state(symbol, state)
  @actions[symbol] = [Aurum::ParsingTable::Action.new(:lookahead_shift, state.index)]
end

#add_read_reduce(symbol, production) ⇒ Object



76
77
78
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 76

def add_read_reduce symbol, production
  add_action(symbol, Aurum::ParsingTable::Action.new(:read_reduce, production))
end

#add_reduce(symbol, production) ⇒ Object



72
73
74
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 72

def add_reduce symbol, production
  add_action(symbol, Aurum::ParsingTable::Action.new(:reduce, production))
end

#add_shift(symbol, state) ⇒ Object



80
81
82
83
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 80

def add_shift symbol, state
  add_action(symbol, Aurum::ParsingTable::Action.new(:shift, state.index))
  add_goto_state(symbol, state)
end

#conflict?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 52

def conflict?
  @actions.values.any? {|actions| actions.size > 1 }
end

#conflictsObject



56
57
58
59
60
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 56

def conflicts
  conflict = []
  @actions.each {|symbol, actions| conflict << symbol if actions.size > 1}
  conflict
end

#goto(symbol) ⇒ Object



66
67
68
69
70
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 66

def goto symbol
  new_state = []
  @all_items.each {|item| new_state << item.next if item.dot_symbol == symbol}
  new_state.empty? ? nil : State.new(@augmented_grammar, new_state)
end

#include_each(nonterminal) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 113

def include_each nonterminal
  return unless @expect_symbols.include?(nonterminal)
  for item in @all_items
    for predecessor in predecessors(item.production.symbols[0, item.position])
      yield predecessor, item.production.nonterminal
    end if (item.dot_symbol == nonterminal && nullable?(item.remaining[1..-1]))
  end
end

#inconsistent?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 48

def inconsistent?
  @handles.size > 1 || (@handles.size != 0 && @handles.size != size)
end

#predecessors(symbols = nil) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 95

def predecessors(symbols = nil)
  return @predecessors unless symbols
  result = [self]
  symbols.reverse_each do |symbol|
    new_result = []
    result.each {|state| new_result |= state.predecessors[symbol] if state.predecessors[symbol]}
    result.replace(new_result)
  end
  result
end

#read(nonterminal) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 122

def read nonterminal
  return unless @expect_symbols.include?(nonterminal)
  for action in @actions[nonterminal]
    if action.shift_action?
      state, direct, indirect = @goto_states[nonterminal], [], []
      state.expect_symbols.each do |symbol|
        direct << symbol if symbol.is_terminal
        indirect << symbol if @augmented_grammar.nullable?(symbol)
      end
      yield(state, direct, indirect)
    end
  end
end

#read_reduceObject



62
63
64
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 62

def read_reduce
  (@handles.size == 1 && size == 1) ? first.production : nil
end

#read_reduce_items(nonterminal) ⇒ Object



136
137
138
139
140
141
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 136

def read_reduce_items nonterminal
  return unless @expect_symbols.include?(nonterminal)
  for item in @all_items
    yield(item.production, item.position) if item.reducable?(nonterminal)
  end
end

#read_set(symbol) ⇒ Object



106
107
108
109
110
111
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 106

def read_set symbol
  return [] unless @expect_symbols.include?(symbol)
  result, state =[].to_set, @goto_states[symbol]
  state.each {|item| result |= first_set_of(item.remaining)} if state
  result
end

#reducable_items(nonterminal) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/aurum/grammar/builder/set_of_items.rb', line 143

def reducable_items nonterminal
  return unless @expect_symbols.include?(nonterminal)
  for item in @all_items
    suffix = item.remaining[1..-1]
    yield(item.production, item.position) if item.dot_symbol == nonterminal && nullable?(suffix)
  end
end