mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 01:33:03 +00:00
tables: fix again the handling of useless tokens
The right-shift added in c22902e360
("tables: fix handling for useless tokens") is incorrect. In
particular, we need to reset the "new" bits.
Reported by Balázs Scheidler.
https://github.com/akimd/bison/issues/74
* src/tables.c (pos_set_set): Fix the right-shift.
This commit is contained in:
6
NEWS
6
NEWS
@@ -2,6 +2,12 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
*** Fix Table Generation
|
||||||
|
|
||||||
|
In some very rare conditions, when there are many useless tokens, it was
|
||||||
|
possible to generate incorrect parsers.
|
||||||
|
|
||||||
* Noteworthy changes in release 3.7.5 (2021-01-24) [stable]
|
* Noteworthy changes in release 3.7.5 (2021-01-24) [stable]
|
||||||
|
|
||||||
|
|||||||
15
src/tables.c
15
src/tables.c
@@ -180,21 +180,26 @@ pos_set_set (int pos)
|
|||||||
int bitno = pos - pos_set_base;
|
int bitno = pos - pos_set_base;
|
||||||
if (bitno < 0)
|
if (bitno < 0)
|
||||||
{
|
{
|
||||||
|
// Need more room on the left.
|
||||||
|
// DELTA is positive. Run 'pos_set >> delta'.
|
||||||
const int delta = pos_set_base - pos;
|
const int delta = pos_set_base - pos;
|
||||||
const int old_size = bitset_size (pos_set);
|
const int old_size = bitset_size (pos_set);
|
||||||
const int new_size = old_size + delta;
|
const int new_size = old_size + delta;
|
||||||
bitset_resize (pos_set, new_size);
|
bitset_resize (pos_set, new_size);
|
||||||
// Shift all the bits by DELTA.
|
// Right-shift all the bits by DELTA. Be sure to reset the new
|
||||||
|
// bits on the left.
|
||||||
|
//
|
||||||
// FIXME: add bitset_assign, and bitset_shift?
|
// FIXME: add bitset_assign, and bitset_shift?
|
||||||
for (int i = new_size - 1; delta <= i ; --i)
|
for (int i = new_size - 1; 0 <= i ; --i)
|
||||||
if (bitset_test (pos_set, i))
|
if (delta <= i && bitset_test (pos_set, i - delta))
|
||||||
bitset_set (pos_set, i + delta);
|
bitset_set (pos_set, i);
|
||||||
else
|
else
|
||||||
bitset_reset (pos_set, i + delta);
|
bitset_reset (pos_set, i);
|
||||||
pos_set_base = pos;
|
pos_set_base = pos;
|
||||||
bitno = 0;
|
bitno = 0;
|
||||||
}
|
}
|
||||||
else if (bitset_size (pos_set) <= bitno)
|
else if (bitset_size (pos_set) <= bitno)
|
||||||
|
// Need more room on the right.
|
||||||
bitset_resize (pos_set, bitno + 1);
|
bitset_resize (pos_set, bitno + 1);
|
||||||
bitset_set (pos_set, bitno);
|
bitset_set (pos_set, bitno);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user