From 36c74e439e78f69bdc3c2c1f76dd7d41a10aacb8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 24 Sep 2024 20:05:39 -0400 Subject: [PATCH] Log conflicting rules on reduce/reduce conflict - close #31 --- lib/propane/parser.rb | 15 +++++++++++++-- spec/propane_spec.rb | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/propane/parser.rb b/lib/propane/parser.rb index 703ac69..9f7a373 100644 --- a/lib/propane/parser.rb +++ b/lib/propane/parser.rb @@ -14,6 +14,7 @@ class Propane @item_sets = [] @item_sets_set = {} @warnings = Set.new + @errors = Set.new @options = options start_item = Item.new(grammar.rules.first, 0) eval_item_sets = Set[ItemSet.new([start_item])] @@ -41,8 +42,18 @@ class Propane build_reduce_actions! build_tables! write_log! + errormessage = "" + if @errors.size > 0 + errormessage += @errors.join("\n") + end if @warnings.size > 0 && @options[:warnings_as_errors] - raise Error.new("Fatal errors (-w):\n" + @warnings.join("\n")) + if errormessage != "" + errormessage += "\n" + end + errormessage += "Fatal errors (-w):\n" + @warnings.join("\n") + end + if errormessage != "" + raise Error.new(errormessage) end end @@ -171,7 +182,7 @@ class Propane lookahead_tokens_for_rule = build_lookahead_tokens_to_reduce(reduce_rule, item_sets) lookahead_tokens_for_rule.each do |lookahead_token| if existing_reduce_rule = reduce_actions[lookahead_token] - raise Error.new("Error: reduce/reduce conflict (state #{item_set.id}) between rule #{existing_reduce_rule.name}##{existing_reduce_rule.id} (defined on line #{existing_reduce_rule.line_number}) and rule #{reduce_rule.name}##{reduce_rule.id} (defined on line #{reduce_rule.line_number})") + @errors << "Error: reduce/reduce conflict (state #{item_set.id}) between rule #{existing_reduce_rule.name}##{existing_reduce_rule.id} (defined on line #{existing_reduce_rule.line_number}) and rule #{reduce_rule.name}##{reduce_rule.id} (defined on line #{reduce_rule.line_number}) for lookahead token #{lookahead_token}" end reduce_actions[lookahead_token] = reduce_rule end diff --git a/spec/propane_spec.rb b/spec/propane_spec.rb index 9e961b1..3f056e9 100644 --- a/spec/propane_spec.rb +++ b/spec/propane_spec.rb @@ -689,6 +689,7 @@ EOF results = run_propane(capture: true, language: language) expect(results.status).to_not eq 0 expect(results.stderr).to match %r{Error: reduce/reduce conflict \(state \d+\) between rule E#\d+ \(defined on line 10\) and rule F#\d+ \(defined on line 11\)} + expect(File.binread("spec/run/testparser.log")).to match %r{Reduce.actions:} end it "provides matched text to user code blocks" do