[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]