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: Wed, 7 Nov 2018 22:46:33 +0100

> Le 7 nov. 2018 à 22:40, Akim Demaille <address@hidden> a écrit :
> 
>> Le 7 nov. 2018 à 22:39, Akim Demaille <address@hidden> a écrit :
>> 
>> I have rebased Paul’s original proposal, and pushed in ‘expect’ branch.
>> 
>> commit f4d7d30ece4a0c7c9d5911d972b93c1544155dd6
>> Author: Paul Hilfinger <address@hidden>
>> Date:   Tue Feb 26 16:28:36 2013 -0800
>> 
>>   allow %expect and %expect-rr modifiers on individual rules
> 
> On top of this, I have this stylistic/modernization commit.
> 
> commit 2cd225a361dae9af86ab04623a2a37f257eea2ae
> Author: Akim Demaille <address@hidden>
> Date:   Wed Feb 27 14:43:20 2013 +0100

And then, I propose this change, which follows some of the
comments I had made in
https://lists.gnu.org/archive/html/bison-patches/2013-02/msg00106.html.

I do not plan this for 3.2.1, obviously.  I am still waiting for
bug reports to pacify and then to publish 3.2.1.  _Then_ we will
start including these things into master.

commit 33744260cccbe104fa91fb58fbcbdbbb9700fdb3
Author: Akim Demaille <address@hidden>
Date:   Wed Nov 7 22:27:35 2018 +0100

    %expect: tune the number of conflicts per rule
    
    Currently on a grammar such as
    
        exp: "number" | exp "+" exp | exp "*" exp
    
    we count only one sr-conflict for both binary rules, i.e., we expect:
    
        exp: "number" | exp "+" exp  %expect 1 | exp "*" exp  %expect 1
    
    although there are 4 conflicts in total.  That's because in the states
    in conflict, for instance that for the "+" rule:
    
        State 6
    
            2 exp: exp . "+" exp
            2    | exp "+" exp .  [$end, "+", "*"]
            3    | exp . "*" exp
    
            "+"  shift, and go to state 4
            "*"  shift, and go to state 5
    
            "+"       [reduce using rule 2 (exp)]
            "*"       [reduce using rule 2 (exp)]
            $default  reduce using rule 2 (exp)
    
    we count only a single conflict, although there are two (one on "+"
    and another with "*").
    
    See https://lists.gnu.org/archive/html/bison-patches/2013-02/msg00106.html.
    
    * src/conflicts.c (rule_has_state_sr_conflicts): Rename as...
    (count_rule_state_sr_conflicts): this.
    DWIM.
    (count_rule_sr_conflicts): Adjust.
    * tests/conflicts.at (%expect in grammar rules): New.

diff --git a/src/conflicts.c b/src/conflicts.c
index 5e7268a7..2838243e 100644
--- a/src/conflicts.c
+++ b/src/conflicts.c
@@ -504,14 +504,15 @@ count_rr_conflicts (bool one_per_token)
 }
 
 
-/*----------------------------------------------------------------------.
-| For a given rule, count the number of states for which it is involved |
-| in shift/reduce conflicts.                                            |
-`----------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| For a given rule, the number of shift/reduce conflicts in a given |
+| state.                                                            |
+`------------------------------------------------------------------*/
 
-static bool
-rule_has_state_sr_conflicts (rule *r, state *s)
+static size_t
+count_rule_state_sr_conflicts (rule *r, state *s)
 {
+  size_t res = 0;
   transitions *trans = s->transitions;
   reductions *reds = s->reductions;
 
@@ -521,21 +522,24 @@ rule_has_state_sr_conflicts (rule *r, state *s)
         bitset lookaheads = reds->lookahead_tokens[i];
         int j;
         FOR_EACH_SHIFT (trans, j)
-          if (bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j)))
-            return true;
-        break;
+          res += bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j));
       }
 
-  return false;
+  return res;
 }
 
+/*----------------------------------------------------------------------.
+| For a given rule, count the number of states for which it is involved |
+| in shift/reduce conflicts.                                            |
+`----------------------------------------------------------------------*/
+
 static size_t
 count_rule_sr_conflicts (rule *r)
 {
   size_t res = 0;
   for (state_number i = 0; i < nstates; ++i)
-    if (conflicts[i] && rule_has_state_sr_conflicts (r, states[i]))
-      res++;
+    if (conflicts[i])
+      res += count_rule_state_sr_conflicts (r, states[i]);
   return res;
 }
 
diff --git a/tests/conflicts.at b/tests/conflicts.at
index 03c9acdc..35c3ed0c 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1280,6 +1280,25 @@ AT_BISON_CHECK([-o input.c input.y])
 AT_CLEANUP
 
 
+## -------------------------- ##
+## %expect in grammar rules.  ##
+## -------------------------- ##
+
+AT_SETUP([%expect in grammar rules])
+
+AT_DATA([input.y],
+[[%expect 4
+%%
+exp:
+  "number"
+| exp "+" exp  %expect 2
+| exp "*" exp  %expect 2
+]])
+
+AT_BISON_CHECK([-o input.c -rall input.y])
+AT_CLEANUP
+
+
 ## ---------------------------------- ##
 ## %expect in grammar rule too much.  ##
 ## ---------------------------------- ##




reply via email to

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