fix generator hang when state transition cycle is present - close #20
This commit is contained in:
parent
5b2cbe53e6
commit
918dc7b2bb
@ -134,7 +134,7 @@ class Propane
|
||||
# possible following tokens, we will only look in the item sets leading
|
||||
# up to this one. This restriction gives us a more precise lookahead set,
|
||||
# and allows us to parse LALR grammars.
|
||||
item_sets = item_set.leading_item_sets
|
||||
item_sets = Set[item_set] + item_set.leading_item_sets
|
||||
reduce_rules.reduce({}) do |reduce_actions, reduce_rule|
|
||||
lookahead_tokens_for_rule = build_lookahead_tokens_to_reduce(reduce_rule, item_sets)
|
||||
lookahead_tokens_for_rule.each do |lookahead_token|
|
||||
|
@ -87,14 +87,24 @@ class Propane
|
||||
|
||||
# Set of ItemSets that lead to this ItemSet.
|
||||
#
|
||||
# This set includes this ItemSet.
|
||||
#
|
||||
# @return [Set<ItemSet>]
|
||||
# Set of all ItemSets that lead up to this ItemSet.
|
||||
def leading_item_sets
|
||||
@in_sets.reduce(Set[self]) do |result, item_set|
|
||||
result + item_set.leading_item_sets
|
||||
result = Set.new
|
||||
eval_sets = Set[self]
|
||||
evaled = Set.new
|
||||
while eval_sets.size > 0
|
||||
eval_set = eval_sets.first
|
||||
eval_sets.delete(eval_set)
|
||||
evaled << eval_set
|
||||
eval_set.in_sets.each do |in_set|
|
||||
result << in_set
|
||||
unless evaled.include?(in_set)
|
||||
eval_sets << in_set
|
||||
end
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Represent the ItemSet as a String.
|
||||
|
@ -851,6 +851,20 @@ EOF
|
||||
"R",
|
||||
])
|
||||
end
|
||||
|
||||
it "handles when an item set leads to itself" do
|
||||
write_grammar <<EOF
|
||||
token one;
|
||||
token two;
|
||||
|
||||
Start -> Opt one Start;
|
||||
Start -> ;
|
||||
|
||||
Opt -> two;
|
||||
Opt -> ;
|
||||
EOF
|
||||
build_parser(language: language)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user