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