From ebeb7c56b3ca56d870112f2aa3f114922f58dba3 Mon Sep 17 00:00:00 2001 From: ydah Date: Thu, 22 Jan 2026 23:40:39 +0900 Subject: [PATCH] Fix unused variable warning in no_result_var mode with EBNF operators --- lib/racc/grammarfileparser.rb | 22 +++++- test/test_grammar_file_parser.rb | 112 +++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/lib/racc/grammarfileparser.rb b/lib/racc/grammarfileparser.rb index 69870257..a19ff7e9 100644 --- a/lib/racc/grammarfileparser.rb +++ b/lib/racc/grammarfileparser.rb @@ -295,7 +295,7 @@ def _add_many_rule(prev) return target if target target = _gen_target_name("many", prev) @many_rule_registry[prev.to_s] = target - src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1) + src = SourceText.new(_many_action_code, @filename, @scanner.lineno + 1) act = UserAction.source_text(src) @grammar.add Rule.new(target, [], act) @grammar.add Rule.new(target, [prev, target], act) @@ -308,13 +308,29 @@ def _add_many1_rule(prev) return target if target target = _gen_target_name("many1", prev) @many1_rule_registry[prev.to_s] = target - src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1) + src = SourceText.new(_many_action_code, @filename, @scanner.lineno + 1) act = UserAction.source_text(src) @grammar.add Rule.new(target, [prev], act) @grammar.add Rule.new(target, [prev, target], act) target end + def _many_action_code + if @result.params.result_var? + "result = val[1] ? val[1].unshift(val[0]) : val" + else + "val[1] ? val[1].unshift(val[0]) : val" + end + end + + def _group_action_code + if @result.params.result_var? + "result = val" + else + "val" + end + end + def _add_group_rule(enum) target = @grammar.intern("-temp-group", true) rules, _ = _add_rule_block(target, enum) @@ -323,7 +339,7 @@ def _add_group_rule(enum) unless target = @group_rule_registry[target_name] target = @grammar.intern("-group@#{target_name}", true) @group_rule_registry[target_name] = target - src = SourceText.new("result = val", @filename, @scanner.lineno + 1) + src = SourceText.new(_group_action_code, @filename, @scanner.lineno + 1) act = UserAction.source_text(src) rules.each do |syms, sprec| rule = Rule.new(target, syms, act) diff --git a/test/test_grammar_file_parser.rb b/test/test_grammar_file_parser.rb index 8f6e090c..2cc450ae 100644 --- a/test/test_grammar_file_parser.rb +++ b/test/test_grammar_file_parser.rb @@ -11,5 +11,117 @@ def test_parse parser = Racc::GrammarFileParser.new(debug_flags) parser.parse(File.read(file), File.basename(file)) end + + def test_no_result_var_with_many_operator + grammar_source = <<~GRAMMAR + class TestParser + options no_result_var + + rule + root + : 'a' 'b'* + GRAMMAR + + debug_flags = Racc::DebugFlags.parse_option_string('') + parser = Racc::GrammarFileParser.new(debug_flags) + result = parser.parse(grammar_source, 'test.y') + + assert_equal false, result.params.result_var? + + actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact + actions.each do |action| + refute_match(/\Aresult\s*=/, action, "Action should not start with 'result =' when no_result_var is set") + end + end + + def test_no_result_var_with_many1_operator + grammar_source = <<~GRAMMAR + class TestParser + options no_result_var + + rule + root + : 'a' 'b'+ + GRAMMAR + + debug_flags = Racc::DebugFlags.parse_option_string('') + parser = Racc::GrammarFileParser.new(debug_flags) + result = parser.parse(grammar_source, 'test.y') + + assert_equal false, result.params.result_var? + + actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact + actions.each do |action| + refute_match(/\Aresult\s*=/, action, "Action should not start with 'result =' when no_result_var is set") + end + end + + def test_no_result_var_with_group_operator + grammar_source = <<~GRAMMAR + class TestParser + options no_result_var + + rule + root + : ('a' | 'b') + GRAMMAR + + debug_flags = Racc::DebugFlags.parse_option_string('') + parser = Racc::GrammarFileParser.new(debug_flags) + result = parser.parse(grammar_source, 'test.y') + + assert_equal false, result.params.result_var? + + actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact + actions.each do |action| + refute_match(/\Aresult\s*=/, action, "Action should not start with 'result =' when no_result_var is set") + end + end + + def test_result_var_with_many_operator + grammar_source = <<~GRAMMAR + class TestParser + + rule + root + : 'a' 'b'* + GRAMMAR + + debug_flags = Racc::DebugFlags.parse_option_string('') + parser = Racc::GrammarFileParser.new(debug_flags) + result = parser.parse(grammar_source, 'test.y') + + assert_equal true, result.params.result_var? + + actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact.reject(&:empty?) + assert actions.any? { |action| action.match?(/\Aresult\s*=/) }, "Action should start with 'result =' when result_var is enabled" + end + + def test_no_result_var_no_warnings + grammar_file = Tempfile.new(['test_no_result_var', '.y']) + grammar_file.write(<<~GRAMMAR) + class TestParser + options no_result_var + + rule + root + : 'a' 'b'* + | 'c' 'd'+ + | ('e' | 'f') + GRAMMAR + grammar_file.close + + output_file = Tempfile.new(['test_no_result_var', '.rb']) + output_file.close + + system("ruby", "-I#{LIB_DIR}", "-S", RACC, "-o", output_file.path, grammar_file.path) + assert $?.success?, "racc command failed" + + warnings = `ruby -W #{output_file.path} 2>&1` + assert_equal "", warnings, "Expected no warnings but got: #{warnings}" + ensure + grammar_file&.unlink + output_file&.unlink + end end end