Skip to content

Commit ebeb7c5

Browse files
committed
Fix unused variable warning in no_result_var mode with EBNF operators
1 parent e1e6e76 commit ebeb7c5

2 files changed

Lines changed: 131 additions & 3 deletions

File tree

lib/racc/grammarfileparser.rb

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def _add_many_rule(prev)
295295
return target if target
296296
target = _gen_target_name("many", prev)
297297
@many_rule_registry[prev.to_s] = target
298-
src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1)
298+
src = SourceText.new(_many_action_code, @filename, @scanner.lineno + 1)
299299
act = UserAction.source_text(src)
300300
@grammar.add Rule.new(target, [], act)
301301
@grammar.add Rule.new(target, [prev, target], act)
@@ -308,13 +308,29 @@ def _add_many1_rule(prev)
308308
return target if target
309309
target = _gen_target_name("many1", prev)
310310
@many1_rule_registry[prev.to_s] = target
311-
src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1)
311+
src = SourceText.new(_many_action_code, @filename, @scanner.lineno + 1)
312312
act = UserAction.source_text(src)
313313
@grammar.add Rule.new(target, [prev], act)
314314
@grammar.add Rule.new(target, [prev, target], act)
315315
target
316316
end
317317

318+
def _many_action_code
319+
if @result.params.result_var?
320+
"result = val[1] ? val[1].unshift(val[0]) : val"
321+
else
322+
"val[1] ? val[1].unshift(val[0]) : val"
323+
end
324+
end
325+
326+
def _group_action_code
327+
if @result.params.result_var?
328+
"result = val"
329+
else
330+
"val"
331+
end
332+
end
333+
318334
def _add_group_rule(enum)
319335
target = @grammar.intern("-temp-group", true)
320336
rules, _ = _add_rule_block(target, enum)
@@ -323,7 +339,7 @@ def _add_group_rule(enum)
323339
unless target = @group_rule_registry[target_name]
324340
target = @grammar.intern("-group@#{target_name}", true)
325341
@group_rule_registry[target_name] = target
326-
src = SourceText.new("result = val", @filename, @scanner.lineno + 1)
342+
src = SourceText.new(_group_action_code, @filename, @scanner.lineno + 1)
327343
act = UserAction.source_text(src)
328344
rules.each do |syms, sprec|
329345
rule = Rule.new(target, syms, act)

test/test_grammar_file_parser.rb

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,117 @@ def test_parse
1111
parser = Racc::GrammarFileParser.new(debug_flags)
1212
parser.parse(File.read(file), File.basename(file))
1313
end
14+
15+
def test_no_result_var_with_many_operator
16+
grammar_source = <<~GRAMMAR
17+
class TestParser
18+
options no_result_var
19+
20+
rule
21+
root
22+
: 'a' 'b'*
23+
GRAMMAR
24+
25+
debug_flags = Racc::DebugFlags.parse_option_string('')
26+
parser = Racc::GrammarFileParser.new(debug_flags)
27+
result = parser.parse(grammar_source, 'test.y')
28+
29+
assert_equal false, result.params.result_var?
30+
31+
actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact
32+
actions.each do |action|
33+
refute_match(/\Aresult\s*=/, action, "Action should not start with 'result =' when no_result_var is set")
34+
end
35+
end
36+
37+
def test_no_result_var_with_many1_operator
38+
grammar_source = <<~GRAMMAR
39+
class TestParser
40+
options no_result_var
41+
42+
rule
43+
root
44+
: 'a' 'b'+
45+
GRAMMAR
46+
47+
debug_flags = Racc::DebugFlags.parse_option_string('')
48+
parser = Racc::GrammarFileParser.new(debug_flags)
49+
result = parser.parse(grammar_source, 'test.y')
50+
51+
assert_equal false, result.params.result_var?
52+
53+
actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact
54+
actions.each do |action|
55+
refute_match(/\Aresult\s*=/, action, "Action should not start with 'result =' when no_result_var is set")
56+
end
57+
end
58+
59+
def test_no_result_var_with_group_operator
60+
grammar_source = <<~GRAMMAR
61+
class TestParser
62+
options no_result_var
63+
64+
rule
65+
root
66+
: ('a' | 'b')
67+
GRAMMAR
68+
69+
debug_flags = Racc::DebugFlags.parse_option_string('')
70+
parser = Racc::GrammarFileParser.new(debug_flags)
71+
result = parser.parse(grammar_source, 'test.y')
72+
73+
assert_equal false, result.params.result_var?
74+
75+
actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact
76+
actions.each do |action|
77+
refute_match(/\Aresult\s*=/, action, "Action should not start with 'result =' when no_result_var is set")
78+
end
79+
end
80+
81+
def test_result_var_with_many_operator
82+
grammar_source = <<~GRAMMAR
83+
class TestParser
84+
85+
rule
86+
root
87+
: 'a' 'b'*
88+
GRAMMAR
89+
90+
debug_flags = Racc::DebugFlags.parse_option_string('')
91+
parser = Racc::GrammarFileParser.new(debug_flags)
92+
result = parser.parse(grammar_source, 'test.y')
93+
94+
assert_equal true, result.params.result_var?
95+
96+
actions = result.grammar.each_rule.map { |rule| rule.action.source&.text }.compact.reject(&:empty?)
97+
assert actions.any? { |action| action.match?(/\Aresult\s*=/) }, "Action should start with 'result =' when result_var is enabled"
98+
end
99+
100+
def test_no_result_var_no_warnings
101+
grammar_file = Tempfile.new(['test_no_result_var', '.y'])
102+
grammar_file.write(<<~GRAMMAR)
103+
class TestParser
104+
options no_result_var
105+
106+
rule
107+
root
108+
: 'a' 'b'*
109+
| 'c' 'd'+
110+
| ('e' | 'f')
111+
GRAMMAR
112+
grammar_file.close
113+
114+
output_file = Tempfile.new(['test_no_result_var', '.rb'])
115+
output_file.close
116+
117+
system("ruby", "-I#{LIB_DIR}", "-S", RACC, "-o", output_file.path, grammar_file.path)
118+
assert $?.success?, "racc command failed"
119+
120+
warnings = `ruby -W #{output_file.path} 2>&1`
121+
assert_equal "", warnings, "Expected no warnings but got: #{warnings}"
122+
ensure
123+
grammar_file&.unlink
124+
output_file&.unlink
125+
end
14126
end
15127
end

0 commit comments

Comments
 (0)