> Le 7 nov. 2018 à 22:40, Akim Demaille <[email protected]> a écrit : > >> Le 7 nov. 2018 à 22:39, Akim Demaille <[email protected]> a écrit : >> >> I have rebased Paul’s original proposal, and pushed in ‘expect’ branch. >> >> commit f4d7d30ece4a0c7c9d5911d972b93c1544155dd6 >> Author: Paul Hilfinger <[email protected]> >> 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 <[email protected]> > 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 <[email protected]> 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. ## ## ---------------------------------- ##
