Rename to propane
This commit is contained in:
1 parent
fbd215098b
commit
ddadc2008b
32 files changed
+60
-100
No files matched your search
@@ -0,0 +1,69 @@
|
||||
class Propane
|
||||
class Parser
|
||||
|
||||
class Item
|
||||
|
||||
attr_reader :pattern
|
||||
attr_reader :position
|
||||
|
||||
def initialize(pattern, position)
|
||||
@pattern = pattern
|
||||
@position = position
|
||||
end
|
||||
|
||||
def next_component
|
||||
@pattern.components[@position]
|
||||
end
|
||||
|
||||
def hash
|
||||
[@pattern, @position].hash
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
@pattern == other.pattern && @position == other.position
|
||||
end
|
||||
|
||||
def eql?(other)
|
||||
self == other
|
||||
end
|
||||
|
||||
def closed_items
|
||||
if @pattern.components[@position].is_a?(Rule)
|
||||
@pattern.components[@position].patterns.map do |pattern|
|
||||
Item.new(pattern, 0)
|
||||
end
|
||||
else
|
||||
[]
|
||||
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
|
||||
"#{@pattern.rule.name} -> #{parts.join(" ")}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
class Propane
|
||||
class Parser
|
||||
|
||||
class ItemSet
|
||||
|
||||
attr_reader :items
|
||||
|
||||
attr_accessor :id
|
||||
|
||||
# @return [Hash]
|
||||
# Maps a follow symbol to its item set.
|
||||
attr_reader :follow_item_set
|
||||
|
||||
# @return [Set]
|
||||
# Item sets leading to this item set.
|
||||
attr_reader :in_sets
|
||||
|
||||
def initialize(items)
|
||||
@items = Set.new(items)
|
||||
@follow_item_set = {}
|
||||
@in_sets = Set.new
|
||||
close!
|
||||
end
|
||||
|
||||
def follow_symbols
|
||||
Set.new(@items.map(&:follow_symbol).compact)
|
||||
end
|
||||
|
||||
def build_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
|
||||
this_eval_items = eval_items
|
||||
eval_items = Set.new
|
||||
this_eval_items.each do |item|
|
||||
item.closed_items.each do |new_item|
|
||||
unless @items.include?(new_item)
|
||||
eval_items << new_item
|
||||
end
|
||||
end
|
||||
end
|
||||
@items += eval_items
|
||||
end
|
||||
end
|
||||
|
||||
def items_followed_by(symbol)
|
||||
@items.select do |item|
|
||||
item.followed_by?(symbol)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user