bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC] Allow %expect and %expect annotations on rules


From: Akim Demaille
Subject: Re: [RFC] Allow %expect and %expect annotations on rules
Date: Thu, 22 Nov 2018 07:06:21 +0100

I’m surprised (and somewhat disappointed) that there are no answers about this 
thread.  I like Paul’s contribution a lot, and was expecting some comments.

Since none of the 0 responses were about critical issue I failed to see, I will 
install these patches in master (when the CI is done checking the one below).

The previous email was about fixing the computation of per-rule SR conflicts.  
This one is about fixing the computation of the per-rule RR conflicts.  In both 
cases ‘fixing’ might be an unfair way to describe the change: I find ‘my’ way 
to compute easier to understand that Paul’s, since when you sum them, you get 
the overall numbers of conflicts.  It’s also easier for the human to compute, 
since you get the numbers of conflicts that you see in the *.output file.

However, Paul’s computations might have advantages that I have not foreseen, or 
are more important than I think (e.g., robustness to changes in the lookahead 
sets).


While I’m very happy with per-rule %expect (s/r), I’m not entirely satisfied 
with the current %expect-rr (r/r).  More on this later.


commit 6ca1b418e4ff6e5c7e61e00fb26b401b33d7cb1e
Author: Akim Demaille <address@hidden>
Date:   Fri Nov 9 17:29:29 2018 +0100

    %expect-rr: tune the number of conflicts per rule
    
    Currently on a grammar such as
    
        exp : a '1' | a '2' | a '3' | b '1' | b '2' | b '3'
        a:
        b:
    
    we count only one rr-conflict on the `b:` rule, i.e., we expect:
    
        b: %expect-rr 1
    
    although there are 3 conflicts in total.  That's because in the
    conflicted state we count only a single conflict, although there are
    three (one for each of the lookaheads: '1', '2', '3').
    
        State 0
    
            0 $accept: . exp $end
            1 exp: . a '1'
            2    | . a '2'
            3    | . a '3'
            4    | . b '1'
            5    | . b '2'
            6    | . b '3'
            7 a: . %empty  ['1', '2', '3']
            8 b: . %empty  ['1', '2', '3']
    
            '1'       reduce using rule 7 (a)
            '1'       [reduce using rule 8 (b)]
            '2'       reduce using rule 7 (a)
            '2'       [reduce using rule 8 (b)]
            '3'       reduce using rule 7 (a)
            '3'       [reduce using rule 8 (b)]
            $default  reduce using rule 7 (a)
    
            exp  go to state 1
            a    go to state 2
            b    go to state 3
    
    See https://lists.gnu.org/archive/html/bison-patches/2013-02/msg00106.html.
    
    * src/conflicts.c (rule_has_state_rr_conflicts): Rename as...
    (count_rule_state_sr_conflicts): this.
    DWIM.
    (count_rule_rr_conflicts): Adjust.
    * tests/conflicts.at (%expect-rr in grammar rules)
    (%expect-rr too much in grammar rules)
    (%expect-rr not enough in grammar rules): New.

diff --git a/src/conflicts.c b/src/conflicts.c
index af67aaea..f081f2af 100644
--- a/src/conflicts.c
+++ b/src/conflicts.c
@@ -483,7 +483,7 @@ count_state_rr_conflicts (state *s)
       int count = 0;
       for (int j = 0; j < reds->num; ++j)
         count += bitset_test (reds->lookahead_tokens[j], i);
-      if (count >= 2)
+      if (2 <= count)
         res += count-1;
     }
 
@@ -546,23 +546,25 @@ count_rule_sr_conflicts (rule *r)
 | involved in reduce/reduce conflicts.                             |
 `-----------------------------------------------------------------*/
 
-static bool
-rule_has_state_rr_conflicts (rule *r, state *s)
+static size_t
+count_rule_state_rr_conflicts (rule *r, state *s)
 {
-  reductions *reds = s->reductions;
+  size_t res = 0;
+  const reductions *reds = s->reductions;
+  bitset lookaheads = bitset_create (ntokens, BITSET_FIXED);
 
   for (int i = 0; i < reds->num; ++i)
     if (reds->rules[i] == r)
-      {
-        bitset lookaheads = reds->lookahead_tokens[i];
-        for (int j = 0; j < reds->num; ++j)
-          if (reds->rules[j] != r &&
-              !bitset_disjoint_p (lookaheads, reds->lookahead_tokens[j]))
-            return true;
-        break;
-      }
-
-  return false;
+      for (int j = 0; j < reds->num; ++j)
+        if (reds->rules[j] != r)
+          {
+            bitset_and (lookaheads,
+                        reds->lookahead_tokens[i],
+                        reds->lookahead_tokens[j]);
+            res += bitset_count (lookaheads);
+          }
+  bitset_free (lookaheads);
+  return res;
 }
 
 static size_t
@@ -570,8 +572,7 @@ count_rule_rr_conflicts (rule *r)
 {
   size_t res = 0;
   for (state_number i = 0; i < nstates; ++i)
-    if (conflicts[i] && rule_has_state_rr_conflicts (r, states[i]))
-      res++;
+    res += count_rule_state_rr_conflicts (r, states[i]);
   return res;
 }
 
diff --git a/tests/conflicts.at b/tests/conflicts.at
index c5fd512f..bddd8b83 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1318,6 +1318,89 @@ AT_BISON_CHECK([-o input.c input.y], 1, [],
 AT_CLEANUP
 
 
+## ---------------------------- ##
+## %expect-rr in grammar rule.  ##
+## ---------------------------- ##
+
+AT_SETUP([%expect-rr in grammar rule])
+
+AT_DATA([input.y],
+[[%glr-parser
+%expect-rr 3
+%%
+exp
+: a '1'
+| a '2'
+| a '3'
+| b '1'
+| b '2'
+| b '3'
+a:
+b: %expect-rr 3
+]])
+
+AT_BISON_CHECK([-o input.c input.y])
+AT_CLEANUP
+
+
+## ------------------------------------- ##
+## %expect-rr too much in grammar rule.  ##
+## ------------------------------------- ##
+
+AT_SETUP([%expect-rr too much in grammar rule])
+
+AT_DATA([input.y],
+[[%glr-parser
+%expect-rr 3
+%%
+exp
+: a '1'
+| a '2'
+| a '3'
+| b '1'
+| b '2'
+| b '3'
+a:
+b: %expect-rr 4
+]])
+
+AT_BISON_CHECK([-fcaret -o input.c input.y], 1, [],
+[[input.y:12.4-15: error: reduce/reduce conflicts for rule 8: 3 found, 4 
expected
+ b: %expect-rr 4
+    ^^^^^^^^^^^^
+]])
+AT_CLEANUP
+
+
+## --------------------------------------- ##
+## %expect-rr not enough in grammar rule.  ##
+## --------------------------------------- ##
+
+AT_SETUP([%expect-rr not enough in grammar rule])
+
+AT_DATA([input.y],
+[[%glr-parser
+%expect-rr 3
+%%
+exp
+: a '1'
+| a '2'
+| a '3'
+| b '1'
+| b '2'
+| b '3'
+a:
+b: %expect-rr 2
+]])
+
+AT_BISON_CHECK([-fcaret -o input.c input.y], 1, [],
+[[input.y:12.4-15: error: reduce/reduce conflicts for rule 8: 3 found, 2 
expected
+ b: %expect-rr 2
+    ^^^^^^^^^^^^
+]])
+AT_CLEANUP
+
+
 ## ------------------------- ##
 ## %prec with user strings.  ##
 ## ------------------------- ##




reply via email to

[Prev in Thread] Current Thread [Next in Thread]