Warn on shift/reduce conflicts
This commit is contained in:
parent
69cc8fa67d
commit
4ae5ab79b3
@ -669,7 +669,7 @@ typedef struct
|
||||
/** Parser shift table. */
|
||||
static const shift_t parser_shift_table[] = {
|
||||
<% @parser.shift_table.each do |shift| %>
|
||||
{<%= shift[:symbol_id] %>u, <%= shift[:state_id] %>u},
|
||||
{<%= shift[:symbol].id %>u, <%= shift[:state_id] %>u},
|
||||
<% end %>
|
||||
};
|
||||
|
||||
|
@ -817,7 +817,7 @@ private struct state_value_t
|
||||
/** Parser shift table. */
|
||||
private immutable shift_t[] parser_shift_table = [
|
||||
<% @parser.shift_table.each do |shift| %>
|
||||
shift_t(<%= shift[:symbol_id] %>u, <%= shift[:state_id] %>u),
|
||||
shift_t(<%= shift[:symbol].id %>u, <%= shift[:state_id] %>u),
|
||||
<% end %>
|
||||
];
|
||||
|
||||
|
@ -13,6 +13,7 @@ class Propane
|
||||
@log = log
|
||||
@item_sets = []
|
||||
@item_sets_set = {}
|
||||
@sr_conflicts = Set.new
|
||||
start_item = Item.new(grammar.rules.first, 0)
|
||||
eval_item_sets = Set[ItemSet.new([start_item])]
|
||||
|
||||
@ -38,8 +39,8 @@ class Propane
|
||||
|
||||
build_reduce_actions!
|
||||
build_follow_sets!
|
||||
write_log!
|
||||
build_tables!
|
||||
write_log!
|
||||
end
|
||||
|
||||
private
|
||||
@ -57,10 +58,17 @@ class Propane
|
||||
item_set.next_item_set[next_symbol].id
|
||||
end
|
||||
{
|
||||
symbol_id: next_symbol.id,
|
||||
symbol: next_symbol,
|
||||
state_id: state_id,
|
||||
}
|
||||
end
|
||||
if item_set.reduce_actions
|
||||
shift_entries.each do |shift_entry|
|
||||
if item_set.reduce_actions.include?(shift_entry[:symbol])
|
||||
@sr_conflicts << [shift_entry[:symbol], item_set.reduce_actions[shift_entry[:symbol]]]
|
||||
end
|
||||
end
|
||||
end
|
||||
reduce_entries =
|
||||
if rule = item_set.reduce_rule
|
||||
[{token_id: @grammar.invalid_token_id, rule_id: rule.id, rule: rule,
|
||||
@ -310,6 +318,13 @@ class Propane
|
||||
end
|
||||
end
|
||||
end
|
||||
if @sr_conflicts.size > 0
|
||||
@log.puts
|
||||
@log.puts "Shift/Reduce Conflicts:"
|
||||
@sr_conflicts.each do |sr_conflict|
|
||||
@log.puts " Shift/Reduce conflict between #{sr_conflict[0].name} and #{sr_conflict[1].name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -184,6 +184,20 @@ EOF
|
||||
expect(results.status).to_not eq 0
|
||||
end
|
||||
|
||||
it "warns on shift/reduce conflicts" do
|
||||
write_grammar <<EOF
|
||||
token a;
|
||||
token b;
|
||||
Start -> As? b?;
|
||||
As -> a As2?;
|
||||
As2 -> b a As2?;
|
||||
EOF
|
||||
results = run_propane(capture: true)
|
||||
expect(results.stderr).to eq ""
|
||||
expect(results.status).to eq 0
|
||||
expect(File.binread("spec/run/testparser.log")).to match %r{Shift/Reduce conflict between b and As2}
|
||||
end
|
||||
|
||||
%w[d c].each do |language|
|
||||
|
||||
context "#{language.upcase} language" do
|
||||
|
Loading…
x
Reference in New Issue
Block a user