Track Rule IDs

This commit is contained in:
Josh Holtrop 2021-09-27 21:29:44 -04:00
parent d6779aef00
commit 280b749e38
4 changed files with 49 additions and 38 deletions

View File

@ -81,8 +81,8 @@ class Imbecile
elsif input.slice!(/\A(\S+)\s*:\s*\[(.*?)\] <<\n(.*?)^>>\n/m) elsif input.slice!(/\A(\S+)\s*:\s*\[(.*?)\] <<\n(.*?)^>>\n/m)
rule_name, components, code = $1, $2, $3 rule_name, components, code = $1, $2, $3
components = components.strip.split(/\s+/) components = components.strip.split(/\s+/)
@rules[rule_name] ||= [] @rules[rule_name] ||= Rule.new(rule_name, @rules.size)
@rules[rule_name] << Rule.new(rule_name, components, code) @rules[rule_name].add_pattern(components, code)
else else
if input.size > 25 if input.size > 25
input = input.slice(0..20) + "..." input = input.slice(0..20) + "..."
@ -106,8 +106,8 @@ class Imbecile
unless @rules["Start"] unless @rules["Start"]
raise Error.new("Start rule not found") raise Error.new("Start rule not found")
end end
@rules.each do |rule_name, rules| @rules.each do |rule_name, rule|
rules.each do |rule| rule.patterns.each do |rule|
rule.components.map! do |component| rule.components.map! do |component|
if token_names[component] if token_names[component]
token_names[component] token_names[component]

View File

@ -6,9 +6,9 @@ class Imbecile
@token_eof = Token.new("$", nil, TOKEN_EOF) @token_eof = Token.new("$", nil, TOKEN_EOF)
@item_sets = [] @item_sets = []
@item_sets_set = {} @item_sets_set = {}
start_items = rules["Start"].map do |rule| start_items = rules["Start"].patterns.map do |pattern|
rule.components << @token_eof pattern.components << @token_eof
Item.new(rule, 0) Item.new(pattern, 0)
end end
eval_item_sets = Set.new eval_item_sets = Set.new
eval_item_sets << ItemSet.new(start_items) eval_item_sets << ItemSet.new(start_items)
@ -40,12 +40,7 @@ class Imbecile
end end
puts item_set puts item_set
item_set.follow_item_set.each do |follow_symbol, follow_item_set| item_set.follow_item_set.each do |follow_symbol, follow_item_set|
if follow_symbol.is_a?(Token) puts " #{follow_symbol.name} => #{follow_item_set.id}"
name = follow_symbol.name
else
name = follow_symbol[0].name
end
puts " #{name} => #{follow_item_set.id}"
end end
puts puts
end end

View File

@ -3,24 +3,24 @@ class Imbecile
class Item class Item
attr_reader :rule attr_reader :pattern
attr_reader :position attr_reader :position
def initialize(rule, position) def initialize(pattern, position)
@rule = rule @pattern = pattern
@position = position @position = position
end end
def next_component def next_component
@rule.components[@position] @pattern.components[@position]
end end
def hash def hash
[@rule, @position].hash [@pattern, @position].hash
end end
def ==(other) def ==(other)
@rule == other.rule && @position == other.position @pattern == other.pattern && @position == other.position
end end
def eql?(other) def eql?(other)
@ -28,9 +28,9 @@ class Imbecile
end end
def closed_items def closed_items
if @rule.components[@position].is_a?(Array) if @pattern.components[@position].is_a?(Rule)
@rule.components[@position].map do |rule| @pattern.components[@position].patterns.map do |pattern|
Item.new(rule, 0) Item.new(pattern, 0)
end end
else else
[] []
@ -38,7 +38,7 @@ class Imbecile
end end
def follow_symbol def follow_symbol
@rule.components[@position] @pattern.components[@position]
end end
def followed_by?(symbol) def followed_by?(symbol)
@ -46,25 +46,21 @@ class Imbecile
end end
def next_position def next_position
Item.new(@rule, @position + 1) Item.new(@pattern, @position + 1)
end end
def to_s def to_s
parts = [] parts = []
@rule.components.each_with_index do |symbol, index| @pattern.components.each_with_index do |symbol, index|
if @position == index if @position == index
parts << "." parts << "."
end end
if symbol.is_a?(Token) parts << symbol.name
parts << symbol.name
else
parts << symbol[0].name
end
end end
if @position == @rule.components.size if @position == @pattern.components.size
parts << "." parts << "."
end end
"#{@rule.name} -> #{parts.join(" ")}" "#{@pattern.rule.name} -> #{parts.join(" ")}"
end end
end end

View File

@ -2,16 +2,36 @@ class Imbecile
class Rule class Rule
class Pattern
attr_reader :rule
attr_reader :components
attr_reader :code
def initialize(rule, components, code)
@rule = rule
@components = components
@code = code
end
end
attr_reader :id
attr_reader :name attr_reader :name
attr_reader :components attr_reader :patterns
attr_reader :code def initialize(name, id)
def initialize(name, components, code)
@name = name @name = name
@components = components @id = id
@code = code @patterns = []
end
def add_pattern(components, code)
@patterns << Pattern.new(self, components, code)
end end
end end