Start building following item sets

This commit is contained in:
Josh Holtrop 2021-08-29 09:41:00 -04:00
parent 9cc1890ddc
commit 6026bf1514
4 changed files with 77 additions and 2 deletions

View File

@ -3,11 +3,21 @@ class Imbecile
class Parser
def initialize(tokens, rules)
@item_sets = []
item_sets_set = Set.new
start_items = rules["Start"].patterns.map do |pattern|
Item.new(pattern, 0)
end
start_item_set = ItemSet.new(start_items)
start_item_set.close!
puts "Start item set:"
puts start_item_set
start_item_set.follow_symbols.each do |follow_symbol|
follow_set = start_item_set.follow_set(follow_symbol)
puts
puts "follow set:"
puts follow_set
end
end
end

View File

@ -37,6 +37,32 @@ class Imbecile
end
end
def follow_symbol
@pattern.components[@position]
end
def followed_by?(symbol)
follow_symbol == symbol
end
def next_position
Item.new(@pattern, @position + 1)
end
def to_s
parts = []
@pattern.components.each_with_index do |symbol, index|
if @position == index
parts << "."
end
parts << symbol.name
end
if @position == @pattern.components.size
parts << "."
end
parts.join(" ")
end
end
end

View File

@ -3,10 +3,39 @@ class Imbecile
class ItemSet
attr_reader :items
def initialize(items)
@items = Set.new(items)
close!
end
def follow_symbols
Set.new(@items.map(&:follow_symbol))
end
def follow_set(symbol)
ItemSet.new(items_followed_by(symbol).map(&:next_position))
end
def hash
@items.hash
end
def ==(other)
@items.eql?(other.items)
end
def eql?(other)
self == other
end
def to_s
@items.map(&:to_s).join("\n")
end
private
def close!
eval_items = @items
while eval_items.size > 0
@ -19,6 +48,12 @@ class Imbecile
end
end
def items_followed_by(symbol)
@items.select do |item|
item.followed_by?(symbol)
end
end
end
end

View File

@ -31,7 +31,11 @@ token int \\d+
token plus \\+
token times \\*
drop \\s+
Start: [] <<
Start: [Foo] <<
>>
Foo: [int] <<
>>
Foo: [plus] <<
>>
EOF
build_parser