Add RuleSet#id to use when reducing

Parser will know what state to go to after reducing a Rule based on the
RuleSet ID.
Start on Parser class.
This commit is contained in:
josh committed 2022-06-21 20:07:27 -04:00
1 parent 60e2818075
commit f17efe8c82
4 files changed
+85 -5

No files matched your search

+3 -1
View File
@@ -33,7 +33,9 @@ class Propane
if tokens_by_name.include?(rule.name)
raise Error.new("Rule name collides with token name #{rule.name.inspect}")
end
rule_sets[rule.name] ||= RuleSet.new(rule.name)
@_rule_set_id ||= @grammar.tokens.size
rule_sets[rule.name] ||= RuleSet.new(rule.name, @_rule_set_id)
@_rule_set_id += 1
rule.rule_set = rule_sets[rule.name]
rule_sets[rule.name] << rule
end
+23 -2
View File
@@ -60,22 +60,43 @@ class Propane
def build_tables
shift_table = []
state_table = []
reduce_table = []
@item_sets.each do |item_set|
shift_entries = item_set.following_symbols.select do |following_symbol|
following_symbol.is_a?(Token)
end.map do |following_symbol|
state_id =
if following_symbol == @eof_token
0
else
item_set.following_item_set[following_symbol].id
end
{
token_id: following_symbol.id,
state_id: item_set.following_item_set[following_symbol].id,
state_id: state_id,
}
end
reduce_entries =
case ra = item_set.reduce_actions
when Rule
[{token_id: TOKEN_NONE, rule_id: ra.id, rule_set_id: ra.rule_set.id}]
when Hash
ra.map do |token, rule|
{token_id: token.id, rule_id: rule.id, rule_set_id: rule.rule_set.id}
end
else
[]
end
state_table << {
shift_index: shift_table.size,
n_shifts: shift_entries.size,
reduce_index: reduce_table.size,
n_reduces: reduce_entries.size,
}
shift_table += shift_entries
reduce_table += reduce_entries
end
[state_table, shift_table]
[state_table, shift_table, reduce_table]
end
private
+8 -1
View File
@@ -2,6 +2,10 @@ class Propane
class RuleSet
# @return [Integer]
# ID of the RuleSet.
attr_accessor :id
# @return [String]
# Name of the RuleSet.
attr_reader :name
@@ -18,7 +22,10 @@ class Propane
#
# @param name [String]
# Name of the RuleSet.
def initialize(name)
# @param id [Integer]
# ID of the RuleSet.
def initialize(name, id)
@id = id
@name = name
@rules = []
@could_be_empty = false