Let nondeterministic skeletons be usable with deterministic

tables.
With the patch, GAWK compiled by GCC without -O2 passes its test
suite using a GLR parser driven by LALR tables.  It fails with -O2
because `struct stat' gives two different answers on my machine:
88 (definition of an auto var) and later 96 (memset on this var).
Hence the stack is badly corrumpted.  The headers inclusion is to
blame: if I move the awk.h inclusion before GLR's system header
inclusion, the two struct stat have the same size.
* src/tables.c (pack_table): Always create conflict_table.
(token_actions): Always create conflict_list.
* data/glr.c (YYFLAG): Remove, unused.
This commit is contained in:
Akim Demaille
2002-10-13 18:50:40 +00:00
parent f377f69fec
commit ea99527d23
4 changed files with 44 additions and 35 deletions

View File

@@ -1,3 +1,20 @@
2002-10-13 Akim Demaille <akim@epita.fr>
Let nondeterministic skeletons be usable with deterministic
tables.
With the patch, GAWK compiled by GCC without -O2 passes its test
suite using a GLR parser driven by LALR tables. It fails with -O2
because `struct stat' gives two different answers on my machine:
88 (definition of an auto var) and later 96 (memset on this var).
Hence the stack is badly corrumpted. The headers inclusion is to
blame: if I move the awk.h inclusion before GLR's system header
inclusion, the two struct stat have the same size.
* src/tables.c (pack_table): Always create conflict_table.
(token_actions): Always create conflict_list.
* data/glr.c (YYFLAG): Remove, unused.
2002-10-13 Akim Demaille <akim@epita.fr>
* configure.ac (AC_GNU_SOURCE): Use it instead of hand written code.

View File

@@ -220,7 +220,6 @@ static YYLTYPE yyloc_default;
/* YYFINAL -- State number of the termination state. */
#define YYFINAL ]b4_final_state_number[
#define YYFLAG ]b4_flag[
#define YYLAST ]b4_last[
/* YYNTOKENS -- Number of terminals. */
@@ -341,17 +340,17 @@ static const ]b4_int_type_for([b4_table])[ yytable[] =
]b4_table[
};
/* YYCONFLP[YYPACT[STATE-NUM]] -- pointer into yyconfl of start of list
of conflicting reductions corresponding to action entry for state
STATE-NUM in yytable. 0 means no conflicts. The list in yyconfl
is terminated by a rule number of 0. */
/* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
list of conflicting reductions corresponding to action entry for
state STATE-NUM in yytable. 0 means no conflicts. The list in
yyconfl is terminated by a rule number of 0. */
static const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] =
{
]b4_conflict_list_heads[
};
/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated
by 0, pointed into by YYCONFLP. */
/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
0, pointed into by YYCONFLP. */
]dnl Do not use b4_int_type_for here, since there are places where
dnl pointers onto yyconfl are taken, which type is "short *".
dnl We probably ought to introduce a type for confl.
@@ -1591,7 +1590,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
/* Something's not right; we shouldn't be here. */
yyFail (yystack, NULL);
yyj += *yytokenp;
if (yyj < 0 || yyj > YYLAST || yycheck[yyj] != *yytokenp)
if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != *yytokenp)
{
if (yydefact[yystack->yytops.yystates[0]->yylrState] != 0)
return;

View File

@@ -503,19 +503,19 @@ prepare_actions (void)
muscle_insert_base_table ("check", check,
check[0], 1, high + 1);
if (glr_parser)
{
/* GLR parsing slightly modifies yytable and yycheck
(and thus yypact) so that in states with unresolved conflicts,
the default reduction is not used in the conflicted entries, so
that there is a place to put a conflict pointer. This means that
yyconflp and yyconfl are nonsense for a non-GLR parser, so we
avoid accidents by not writing them out in that case. */
muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
conflict_table[0], 1, high+1);
muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
conflict_list[0], 1, conflict_list_cnt);
}
/* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
YYPACT) so that in states with unresolved conflicts, the default
reduction is not used in the conflicted entries, so that there is
a place to put a conflict pointer.
This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
parser, so we could avoid accidents by not writing them out in
that case. Nevertheless, it seems even better to be able to use
the GLR skeletons even without the non-deterministic tables. */
muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
conflict_table[0], 1, high+1);
muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
conflict_list[0], 1, conflict_list_cnt);
}

View File

@@ -212,8 +212,7 @@ table_grow (size_t desired)
table = XREALLOC (table, base_t, table_size);
check = XREALLOC (check, base_t, table_size);
if (glr_parser)
conflict_table = XREALLOC (conflict_table, unsigned int, table_size);
conflict_table = XREALLOC (conflict_table, unsigned int, table_size);
for (/* Nothing. */; old_size < table_size; ++old_size)
{
@@ -470,27 +469,22 @@ token_actions (void)
symbol_number_t j;
rule_number_t r;
int nconflict = conflicts_total_count ();
int nconflict = glr_parser ? conflicts_total_count () : 0;
yydefact = XCALLOC (rule_number_t, nstates);
actrow = XCALLOC (action_t, ntokens);
conflrow = XCALLOC (unsigned int, ntokens);
conflict_list = XCALLOC (unsigned int, 1 + 2 * nconflict);
conflict_list_free = 2 * nconflict;
conflict_list_cnt = 1;
/* Find the rules which are reduced. */
if (!glr_parser)
for (r = 0; r < nrules; ++r)
rules[r].useful = FALSE;
if (glr_parser)
{
conflict_list = XCALLOC (unsigned int, 1 + 2 * nconflict);
conflict_list_free = 2 * nconflict;
conflict_list_cnt = 1;
}
else
conflict_list_free = conflict_list_cnt = 0;
for (i = 0; i < nstates; ++i)
{
rule_t *default_rule = action_row (states[i]);
@@ -799,8 +793,7 @@ pack_table (void)
base = XCALLOC (base_t, nvectors);
pos = XCALLOC (base_t, nentries);
table = XCALLOC (base_t, table_size);
if (glr_parser)
conflict_table = XCALLOC (unsigned int, table_size);
conflict_table = XCALLOC (unsigned int, table_size);
check = XCALLOC (base_t, table_size);
lowzero = 0;