Class: Antelope::Generation::Tableizer
- Inherits:
-
Object
- Object
- Antelope::Generation::Tableizer
- Defined in:
- lib/antelope/generation/tableizer.rb
Overview
Constructs the table required for the parser.
Instance Attribute Summary collapse
-
#conflicts ⇒ Object
readonly
Returns the value of attribute conflicts.
-
#grammar ⇒ Ace::Grammar
The grammar that the table is based off of.
-
#rules ⇒ Hash<(Numeric, Recognizer::Rule)>
All rules in the grammar.
-
#table ⇒ Array<Hash<(Symbol, Array<(Symbol, Numeric)>)>>
The table itself.
Instance Method Summary collapse
-
#call ⇒ void
Construct the table, and then check the table for conflicts.
-
#conflictize ⇒ void
Resolve any conflicts through precedence, if we can.
-
#initialize(grammar) ⇒ Tableizer
constructor
Initialize.
-
#tablize ⇒ void
Construct a table based on the grammar.
Constructor Details
#initialize(grammar) ⇒ Tableizer
Initialize.
29 30 31 |
# File 'lib/antelope/generation/tableizer.rb', line 29 def initialize(grammar) @grammar = grammar end |
Instance Attribute Details
#conflicts ⇒ Object (readonly)
Returns the value of attribute conflicts.
24 25 26 |
# File 'lib/antelope/generation/tableizer.rb', line 24 def conflicts @conflicts end |
#grammar ⇒ Ace::Grammar
The grammar that the table is based off of.
12 13 14 |
# File 'lib/antelope/generation/tableizer.rb', line 12 def grammar @grammar end |
#rules ⇒ Hash<(Numeric, Recognizer::Rule)>
All rules in the grammar.
22 23 24 |
# File 'lib/antelope/generation/tableizer.rb', line 22 def rules @rules end |
#table ⇒ Array<Hash<(Symbol, Array<(Symbol, Numeric)>)>>
The table itself.
17 18 19 |
# File 'lib/antelope/generation/tableizer.rb', line 17 def table @table end |
Instance Method Details
#call ⇒ void
This method returns an undefined value.
Construct the table, and then check the table for conflicts.
38 39 40 41 |
# File 'lib/antelope/generation/tableizer.rb', line 38 def call tablize conflictize end |
#conflictize ⇒ void
This method returns an undefined value.
Resolve any conflicts through precedence, if we can. If we can't, let the user know. This makes sure that every value of the hashes is a single array.
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 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/antelope/generation/tableizer.rb', line 86 def conflictize @conflicts = Hash.new { |h, k| h[k] = {} } @table.each_with_index do |v, state| v.each do |on, data| if data.size == 1 @table[state][on] = data[0] next end terminal = grammar.precedence_for(on) rule_part, other_part = data.sort_by { |(t, d)| t } unless other_part[0] == :state $stderr.puts \ "Could not determine move for #{on} in state " \ "#{state} (reduce/reduce conflict)" next end result = @rules[rule_part[1]].prec <=> terminal case result when 0 conflicts[state][on] = [ rule_part, other_part, terminal, @rules[rule_part[1]].prec ] $stderr.puts \ "Could not determine move for #{on} in state " \ "#{state} (shift/reduce conflict)" when 1 @table[state][on] = rule_part when -1 @table[state][on] = other_part end end end end |
#tablize ⇒ void
This method returns an undefined value.
Construct a table based on the grammar. The table itself is an array whose elements are hashes; the index of the array corresponds to the state ID, and the keys of the hashes correspond to acceptable tokens. The values of the hashes should be an array of arrays (at this point).
50 51 52 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 |
# File 'lib/antelope/generation/tableizer.rb', line 50 def tablize @table = Array.new(grammar.states.size) do Hash.new { |h, k| h[k] = [] } end @rules = [] grammar.states.each do |state| state.transitions.each do |on, to| table[state.id][on] << [:state, to.id] end state.rules.each do |rule| @rules[rule.production.id] = rule.production if rule.final? rule.lookahead.each do |look| table[state.id][look.name] << [:reduce, rule.production.id] end if rule.production.id.zero? table[state.id][:"$"] = [[:accept, rule.production.id]] end end end end table end |