mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
%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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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. ##
|
||||
## ---------------------------------- ##
|
||||
|
||||
Reference in New Issue
Block a user