mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-17 08:13:02 +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;
|
int count = 0;
|
||||||
for (int j = 0; j < reds->num; ++j)
|
for (int j = 0; j < reds->num; ++j)
|
||||||
count += bitset_test (reds->lookahead_tokens[j], i);
|
count += bitset_test (reds->lookahead_tokens[j], i);
|
||||||
if (count >= 2)
|
if (2 <= count)
|
||||||
res += count-1;
|
res += count-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,23 +546,25 @@ count_rule_sr_conflicts (rule *r)
|
|||||||
| involved in reduce/reduce conflicts. |
|
| involved in reduce/reduce conflicts. |
|
||||||
`-----------------------------------------------------------------*/
|
`-----------------------------------------------------------------*/
|
||||||
|
|
||||||
static bool
|
static size_t
|
||||||
rule_has_state_rr_conflicts (rule *r, state *s)
|
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)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
if (reds->rules[i] == r)
|
if (reds->rules[i] == r)
|
||||||
{
|
for (int j = 0; j < reds->num; ++j)
|
||||||
bitset lookaheads = reds->lookahead_tokens[i];
|
if (reds->rules[j] != r)
|
||||||
for (int j = 0; j < reds->num; ++j)
|
{
|
||||||
if (reds->rules[j] != r &&
|
bitset_and (lookaheads,
|
||||||
!bitset_disjoint_p (lookaheads, reds->lookahead_tokens[j]))
|
reds->lookahead_tokens[i],
|
||||||
return true;
|
reds->lookahead_tokens[j]);
|
||||||
break;
|
res += bitset_count (lookaheads);
|
||||||
}
|
}
|
||||||
|
bitset_free (lookaheads);
|
||||||
return false;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
@@ -570,8 +572,7 @@ count_rule_rr_conflicts (rule *r)
|
|||||||
{
|
{
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
for (state_number i = 0; i < nstates; ++i)
|
for (state_number i = 0; i < nstates; ++i)
|
||||||
if (conflicts[i] && rule_has_state_rr_conflicts (r, states[i]))
|
res += count_rule_state_rr_conflicts (r, states[i]);
|
||||||
res++;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1318,6 +1318,89 @@ AT_BISON_CHECK([-o input.c input.y], 1, [],
|
|||||||
AT_CLEANUP
|
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. ##
|
## %prec with user strings. ##
|
||||||
## ------------------------- ##
|
## ------------------------- ##
|
||||||
|
|||||||
Reference in New Issue
Block a user