Keep track of follow item sets by symbol for each item set
This commit is contained in:
parent
850e639e3a
commit
a2795bb531
@ -3,11 +3,11 @@ class Imbecile
|
|||||||
class Parser
|
class Parser
|
||||||
|
|
||||||
def initialize(tokens, rules)
|
def initialize(tokens, rules)
|
||||||
token_eof = Token.new("$", nil, TOKEN_EOF)
|
@token_eof = Token.new("$", nil, TOKEN_EOF)
|
||||||
@item_sets = []
|
@item_sets = []
|
||||||
item_sets_set = Set.new
|
@item_sets_set = {}
|
||||||
start_items = rules["Start"].map do |rule|
|
start_items = rules["Start"].map do |rule|
|
||||||
rule.components << token_eof
|
rule.components << @token_eof
|
||||||
Item.new(rule, 0)
|
Item.new(rule, 0)
|
||||||
end
|
end
|
||||||
eval_item_sets = Set.new
|
eval_item_sets = Set.new
|
||||||
@ -17,22 +17,45 @@ class Imbecile
|
|||||||
this_eval_item_sets = eval_item_sets
|
this_eval_item_sets = eval_item_sets
|
||||||
eval_item_sets = Set.new
|
eval_item_sets = Set.new
|
||||||
this_eval_item_sets.each do |item_set|
|
this_eval_item_sets.each do |item_set|
|
||||||
unless item_sets_set.include?(item_set)
|
unless @item_sets_set.include?(item_set)
|
||||||
item_set.id = @item_sets.size
|
item_set.id = @item_sets.size
|
||||||
@item_sets << item_set
|
@item_sets << item_set
|
||||||
item_sets_set << item_set
|
@item_sets_set[item_set] = item_set
|
||||||
puts "Item set #{item_set.id}:"
|
|
||||||
puts item_set
|
|
||||||
puts
|
|
||||||
item_set.follow_symbols.each do |follow_symbol|
|
item_set.follow_symbols.each do |follow_symbol|
|
||||||
unless follow_symbol == token_eof
|
unless follow_symbol == @token_eof
|
||||||
follow_set = item_set.follow_set(follow_symbol)
|
follow_set = item_set.build_follow_set(follow_symbol)
|
||||||
eval_item_sets << follow_set
|
eval_item_sets << follow_set
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@item_sets.each do |item_set|
|
||||||
|
process_item_set(item_set)
|
||||||
|
puts "Item set #{item_set.id}:"
|
||||||
|
puts item_set
|
||||||
|
item_set.follow_item_set.each do |follow_symbol, follow_item_set|
|
||||||
|
if follow_symbol.is_a?(Token)
|
||||||
|
name = follow_symbol.name
|
||||||
|
else
|
||||||
|
name = follow_symbol[0].name
|
||||||
|
end
|
||||||
|
puts " #{name} => #{follow_item_set.id}"
|
||||||
|
end
|
||||||
|
puts
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def process_item_set(item_set)
|
||||||
|
item_set.follow_symbols.each do |follow_symbol|
|
||||||
|
unless follow_symbol == @token_eof
|
||||||
|
follow_set = @item_sets_set[item_set.build_follow_set(follow_symbol)]
|
||||||
|
item_set.follow_item_set[follow_symbol] = follow_set
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -7,8 +7,13 @@ class Imbecile
|
|||||||
|
|
||||||
attr_accessor :id
|
attr_accessor :id
|
||||||
|
|
||||||
|
# @return [Hash]
|
||||||
|
# Maps a follow symbol to its item set.
|
||||||
|
attr_reader :follow_item_set
|
||||||
|
|
||||||
def initialize(items)
|
def initialize(items)
|
||||||
@items = Set.new(items)
|
@items = Set.new(items)
|
||||||
|
@follow_item_set = {}
|
||||||
close!
|
close!
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -16,7 +21,7 @@ class Imbecile
|
|||||||
Set.new(@items.map(&:follow_symbol).compact)
|
Set.new(@items.map(&:follow_symbol).compact)
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow_set(symbol)
|
def build_follow_set(symbol)
|
||||||
ItemSet.new(items_followed_by(symbol).map(&:next_position))
|
ItemSet.new(items_followed_by(symbol).map(&:next_position))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user