Skip to content

Commit 97d1a38

Browse files
marcandrehsbt
authored andcommitted
[Fixes #137] Improve reporting
1 parent 3da3c27 commit 97d1a38

File tree

4 files changed

+77
-25
lines changed

4 files changed

+77
-25
lines changed

lib/racc/grammar.rb

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,29 +86,31 @@ def useless_nonterminal_exist?
8686
end
8787

8888
def n_useless_nonterminals
89-
@n_useless_nonterminals ||=
90-
begin
91-
n = 0
92-
@symboltable.each_nonterminal do |sym|
93-
n += 1 if sym.useless?
94-
end
95-
n
96-
end
89+
@n_useless_nonterminals ||= each_useless_nonterminal.count
90+
end
91+
92+
def each_useless_nonterminal
93+
return to_enum __method__ unless block_given?
94+
95+
@symboltable.each_nonterminal do |sym|
96+
yield sym if sym.useless?
97+
end
9798
end
9899

99100
def useless_rule_exist?
100101
n_useless_rules() != 0
101102
end
102103

103104
def n_useless_rules
104-
@n_useless_rules ||=
105-
begin
106-
n = 0
107-
each do |r|
108-
n += 1 if r.useless?
109-
end
110-
n
111-
end
105+
@n_useless_rules ||= each_useless_rule.count
106+
end
107+
108+
def each_useless_rule
109+
return to_enum __method__ unless block_given?
110+
111+
each do |r|
112+
yield r if r.useless?
113+
end
112114
end
113115

114116
def nfa

libexec/racc

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env ruby
22
#
3-
# $Id$
3+
#
44
#
55
# Copyright (c) 1999-2006 Minero Aoki
66
#
@@ -184,8 +184,12 @@ def main
184184
log_useless states.grammar
185185
log_conflict states
186186
else
187-
report_useless states.grammar
188-
report_conflict states
187+
has_useless = report_useless states.grammar
188+
has_conflicts = report_conflict states
189+
if has_useless || has_conflicts
190+
preamble = make_logfile ? 'C' : 'Turn on logging with "-v" and c'
191+
$stderr.puts %Q{#{preamble}heck ".output" file for details}
192+
end
189193
end
190194

191195
profiler.report
@@ -201,13 +205,29 @@ def make_filename(path, suffix)
201205
path.sub(/(?:\..*?)?\z/, suffix)
202206
end
203207

208+
LIST_LIMIT = 10
209+
def report_list(enum, label)
210+
c = enum.count
211+
if c > 0
212+
$stderr.puts "#{c} #{label}:"
213+
enum.first(LIST_LIMIT).each do |item|
214+
$stderr.puts " #{yield item}"
215+
end
216+
$stderr.puts " ..." if c > LIST_LIMIT
217+
end
218+
end
219+
220+
# @return [Boolean] if anything was reported
204221
def report_conflict(states)
205222
if states.should_report_srconflict?
223+
reported = true
206224
$stderr.puts "#{states.n_srconflicts} shift/reduce conflicts"
207225
end
208226
if states.rrconflict_exist?
227+
reported = true
209228
$stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts"
210229
end
230+
reported
211231
end
212232

213233
def log_conflict(states)
@@ -222,16 +242,17 @@ def log_conflict(states)
222242
}
223243
end
224244

245+
# @return [Boolean] if anything was reported
225246
def report_useless(grammar)
226-
if grammar.useless_nonterminal_exist?
227-
$stderr.puts "#{grammar.n_useless_nonterminals} useless nonterminals"
228-
end
229-
if grammar.useless_rule_exist?
230-
$stderr.puts "#{grammar.n_useless_rules} useless rules"
231-
end
247+
reported = report_list(grammar.each_useless_nonterminal, 'useless nonterminals', &:to_s)
248+
249+
reported ||= report_list(grammar.each_useless_rule, 'useless rules') { |r| "##{r.ident} (#{r.target})" }
250+
232251
if grammar.start.useless?
233252
$stderr.puts 'fatal: start symbol does not derive any sentence'
253+
reported = true
234254
end
255+
reported
235256
end
236257

237258
def log_useless(grammar)

test/racc/assets/ifelse.y

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class C::Parser
2+
token tSOMETHING
3+
rule
4+
statement
5+
: tSOMETHING
6+
| 'if' statement 'then' statement
7+
| 'if' statement 'then' statement 'else' statement
8+
;
9+
10+
dummy
11+
: tSOMETHING '+' tSOMETHING
12+
| tSOMETHING '-' tSOMETHING
13+
;
14+

test/racc/test_racc_command.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,5 +318,20 @@ def test_tp_plus
318318
assert_debugfile 'tp_plus.y', [21, 0, 0, 0]
319319
assert_output_unchanged 'tp_plus.y'
320320
end
321+
322+
def test_ifelse
323+
stderr = nil
324+
racc "-o#{@TAB_DIR}/ifelse", "#{ASSET_DIR}/ifelse.y", stdout_filter: ->(s) { stderr = s }
325+
stderr = stderr.lines[1..-1].join if RUBY_PLATFORM.match? /java/
326+
assert_equal(<<~STDERR, stderr)
327+
1 useless nonterminals:
328+
dummy
329+
2 useless rules:
330+
#4 (dummy)
331+
#5 (dummy)
332+
1 shift/reduce conflicts
333+
Turn on logging with "-v" and check ".output" file for details
334+
STDERR
335+
end
321336
end
322337
end

0 commit comments

Comments
 (0)