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,12 +1467,33 @@ class state_stack {
bool
yyexpandGLRStack()
{
if (YYMAXDEPTH - YYHEADROOM < yyitems.size())
const size_t oldsize = yyitems.size();
if (YYMAXDEPTH - YYHEADROOM < oldsize)
return false;
const size_t yynewSize = YYMAXDEPTH < 2 * yyitems.size() ? YYMAXDEPTH : 2 * yyitems.size();
const size_t yynewSize = YYMAXDEPTH < 2 * oldsize ? YYMAXDEPTH : 2 * oldsize;
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;
}
public:
#else
bool yyexpandGLRStackIfNeeded ()
@@ -1486,11 +1507,12 @@ class state_stack {
}
bool
reduceToOneStack() {
const std::vector<glr_state*>::iterator yybegin = yytops.begin();
const std::vector<glr_state*>::iterator yyend = yytops.end();
const std::vector<glr_state*>::iterator yyit =
std::find_if(yybegin, yyend, glr_state_not_null);
reduceToOneStack ()
{
typedef std::vector<glr_state*>::iterator iterator;
const iterator yybegin = yytops.begin();
const iterator yyend = yytops.end();
const iterator yyit = std::find_if(yybegin, yyend, glr_state_not_null);
if (yyit == yyend)
return false;
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_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1])
AT_GLR2_CC_IF([AT_XFAIL_IF([true])])
AT_DATA_GRAMMAR([glr-regr14.y],
[[