ruby-changes:63174
From: Marc-Andre <ko1@a...>
Date: Mon, 28 Sep 2020 18:09:48 +0900 (JST)
Subject: [ruby-changes:63174] 97d1a381e1 (master): [Fixes #137] Improve reporting
https://git.ruby-lang.org/ruby.git/commit/?id=97d1a381e1 From 97d1a381e112e843ff014a05a083e42165b7bb01 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune <github@m...> Date: Thu, 13 Aug 2020 21:50:16 -0400 Subject: [Fixes #137] Improve reporting diff --git a/lib/racc/grammar.rb b/lib/racc/grammar.rb index fa81534..3444dfc 100644 --- a/lib/racc/grammar.rb +++ b/lib/racc/grammar.rb @@ -86,14 +86,15 @@ module Racc https://github.com/ruby/ruby/blob/trunk/lib/racc/grammar.rb#L86 end def n_useless_nonterminals - @n_useless_nonterminals ||= - begin - n = 0 - @symboltable.each_nonterminal do |sym| - n += 1 if sym.useless? - end - n - end + @n_useless_nonterminals ||= each_useless_nonterminal.count + end + + def each_useless_nonterminal + return to_enum __method__ unless block_given? + + @symboltable.each_nonterminal do |sym| + yield sym if sym.useless? + end end def useless_rule_exist? @@ -101,14 +102,15 @@ module Racc https://github.com/ruby/ruby/blob/trunk/lib/racc/grammar.rb#L102 end def n_useless_rules - @n_useless_rules ||= - begin - n = 0 - each do |r| - n += 1 if r.useless? - end - n - end + @n_useless_rules ||= each_useless_rule.count + end + + def each_useless_rule + return to_enum __method__ unless block_given? + + each do |r| + yield r if r.useless? + end end def nfa diff --git a/libexec/racc b/libexec/racc index 0f0f642..2edd6bb 100755 --- a/libexec/racc +++ b/libexec/racc @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/libexec/racc#L1 #!/usr/bin/env ruby # -# $Id$ +# # # Copyright (c) 1999-2006 Minero Aoki # @@ -184,8 +184,12 @@ def main https://github.com/ruby/ruby/blob/trunk/libexec/racc#L184 log_useless states.grammar log_conflict states else - report_useless states.grammar - report_conflict states + has_useless = report_useless states.grammar + has_conflicts = report_conflict states + if has_useless || has_conflicts + preamble = make_logfile ? 'C' : 'Turn on logging with "-v" and c' + $stderr.puts %Q{#{preamble}heck ".output" file for details} + end end profiler.report @@ -201,13 +205,29 @@ def make_filename(path, suffix) https://github.com/ruby/ruby/blob/trunk/libexec/racc#L205 path.sub(/(?:\..*?)?\z/, suffix) end +LIST_LIMIT = 10 +def report_list(enum, label) + c = enum.count + if c > 0 + $stderr.puts "#{c} #{label}:" + enum.first(LIST_LIMIT).each do |item| + $stderr.puts " #{yield item}" + end + $stderr.puts " ..." if c > LIST_LIMIT + end +end + +# @return [Boolean] if anything was reported def report_conflict(states) if states.should_report_srconflict? + reported = true $stderr.puts "#{states.n_srconflicts} shift/reduce conflicts" end if states.rrconflict_exist? + reported = true $stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts" end + reported end def log_conflict(states) @@ -222,16 +242,17 @@ def log_conflict(states) https://github.com/ruby/ruby/blob/trunk/libexec/racc#L242 } end +# @return [Boolean] if anything was reported def report_useless(grammar) - if grammar.useless_nonterminal_exist? - $stderr.puts "#{grammar.n_useless_nonterminals} useless nonterminals" - end - if grammar.useless_rule_exist? - $stderr.puts "#{grammar.n_useless_rules} useless rules" - end + reported = report_list(grammar.each_useless_nonterminal, 'useless nonterminals', &:to_s) + + reported ||= report_list(grammar.each_useless_rule, 'useless rules') { |r| "##{r.ident} (#{r.target})" } + if grammar.start.useless? $stderr.puts 'fatal: start symbol does not derive any sentence' + reported = true end + reported end def log_useless(grammar) diff --git a/test/racc/assets/ifelse.y b/test/racc/assets/ifelse.y new file mode 100644 index 0000000..18dbe4b --- /dev/null +++ b/test/racc/assets/ifelse.y @@ -0,0 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/test/racc/assets/ifelse.y#L1 +class C::Parser +token tSOMETHING +rule + statement + : tSOMETHING + | 'if' statement 'then' statement + | 'if' statement 'then' statement 'else' statement + ; + + dummy + : tSOMETHING '+' tSOMETHING + | tSOMETHING '-' tSOMETHING + ; + diff --git a/test/racc/test_racc_command.rb b/test/racc/test_racc_command.rb index b4fc0c6..f1116a3 100644 --- a/test/racc/test_racc_command.rb +++ b/test/racc/test_racc_command.rb @@ -318,5 +318,20 @@ module Racc https://github.com/ruby/ruby/blob/trunk/test/racc/test_racc_command.rb#L318 assert_debugfile 'tp_plus.y', [21, 0, 0, 0] assert_output_unchanged 'tp_plus.y' end + + def test_ifelse + stderr = nil + racc "-o#{@TAB_DIR}/ifelse", "#{ASSET_DIR}/ifelse.y", stdout_filter: ->(s) { stderr = s } + stderr = stderr.lines[1..-1].join if RUBY_PLATFORM.match? /java/ + assert_equal(<<~STDERR, stderr) + 1 useless nonterminals: + dummy + 2 useless rules: + #4 (dummy) + #5 (dummy) + 1 shift/reduce conflicts + Turn on logging with "-v" and check ".output" file for details + STDERR + end end end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/