glr2.cc: fix GLR stack expansion

When expanding the GLR stack, none of the pointers were updated to
reflect the new location of the displaced objects.

This fixes

    748: Incorrect lookahead during nondeterministic GLR: glr2.cc

* data/skeletons/glr2.cc (yyexpandGLRStack): Update the split point
and the stack tops.
(reduceToOneStack): Factor a bit.
This commit is contained in:
Akim Demaille
2020-12-20 08:27:18 +01:00
parent 718cb1ab38
commit fe0102d4d5
2 changed files with 31 additions and 10 deletions

View File

@@ -1467,13 +1467,34 @@ class state_stack {
bool bool
yyexpandGLRStack() yyexpandGLRStack()
{ {
if (YYMAXDEPTH - YYHEADROOM < yyitems.size()) const size_t oldsize = yyitems.size();
if (YYMAXDEPTH - YYHEADROOM < oldsize)
return false; return false;
const size_t yynewSize = YYMAXDEPTH < 2 * yyitems.size() ? YYMAXDEPTH : 2 * yyitems.size(); const size_t yynewSize = YYMAXDEPTH < 2 * oldsize ? YYMAXDEPTH : 2 * oldsize;
yyitems.reserve(yynewSize); const glr_stack_item *oldbase = &yyitems[0];
yyitems.reserve (yynewSize);
const glr_stack_item *newbase = &yyitems[0];
// Adjust the pointers. Perform raw pointer arithmetics, as there
// is no reason for objects to be aligned on their size.
const ptrdiff_t disp
= reinterpret_cast<const char*> (newbase) - reinterpret_cast<const char*> (oldbase);
if (yysplitPoint)
const_cast<glr_state*&> (yysplitPoint)
= reinterpret_cast<glr_state*> (reinterpret_cast<char*> (const_cast<glr_state*> (yysplitPoint)) + disp);
for (std::vector<glr_state*>::iterator
i = yytops.begin (),
yyend = yytops.end ();
i != yyend; ++i)
if (glr_state_not_null (*i))
*i = reinterpret_cast<glr_state*>(reinterpret_cast<char*>(*i) + disp);
return true; return true;
} }
public:
public:
#else #else
bool yyexpandGLRStackIfNeeded () bool yyexpandGLRStackIfNeeded ()
{ {
@@ -1486,11 +1507,12 @@ class state_stack {
} }
bool bool
reduceToOneStack() { reduceToOneStack ()
const std::vector<glr_state*>::iterator yybegin = yytops.begin(); {
const std::vector<glr_state*>::iterator yyend = yytops.end(); typedef std::vector<glr_state*>::iterator iterator;
const std::vector<glr_state*>::iterator yyit = const iterator yybegin = yytops.begin();
std::find_if(yybegin, yyend, glr_state_not_null); const iterator yyend = yytops.end();
const iterator yyit = std::find_if(yybegin, yyend, glr_state_not_null);
if (yyit == yyend) if (yyit == yyend)
return false; return false;
for (state_set_index yyk = create_state_set_index(yyit + 1 - yybegin); for (state_set_index yyk = create_state_set_index(yyit + 1 - yybegin);

View File

@@ -1388,7 +1388,6 @@ m4_pushdef([AT_TEST],
[AT_SETUP([Incorrect lookahead during nondeterministic GLR: $1]) [AT_SETUP([Incorrect lookahead during nondeterministic GLR: $1])
AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1]) AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1])
AT_GLR2_CC_IF([AT_XFAIL_IF([true])])
AT_DATA_GRAMMAR([glr-regr14.y], AT_DATA_GRAMMAR([glr-regr14.y],
[[ [[