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> 2002-10-13 Akim Demaille <akim@epita.fr>
* configure.ac (AC_GNU_SOURCE): Use it instead of hand written code. * 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. */ /* YYFINAL -- State number of the termination state. */
#define YYFINAL ]b4_final_state_number[ #define YYFINAL ]b4_final_state_number[
#define YYFLAG ]b4_flag[
#define YYLAST ]b4_last[ #define YYLAST ]b4_last[
/* YYNTOKENS -- Number of terminals. */ /* YYNTOKENS -- Number of terminals. */
@@ -341,17 +340,17 @@ static const ]b4_int_type_for([b4_table])[ yytable[] =
]b4_table[ ]b4_table[
}; };
/* YYCONFLP[YYPACT[STATE-NUM]] -- pointer into yyconfl of start of list /* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
of conflicting reductions corresponding to action entry for state list of conflicting reductions corresponding to action entry for
STATE-NUM in yytable. 0 means no conflicts. The list in yyconfl state STATE-NUM in yytable. 0 means no conflicts. The list in
is terminated by a rule number of 0. */ yyconfl is terminated by a rule number of 0. */
static const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] = static const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] =
{ {
]b4_conflict_list_heads[ ]b4_conflict_list_heads[
}; };
/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated /* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
by 0, pointed into by YYCONFLP. */ 0, pointed into by YYCONFLP. */
]dnl Do not use b4_int_type_for here, since there are places where ]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 pointers onto yyconfl are taken, which type is "short *".
dnl We probably ought to introduce a type for confl. 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. */ /* Something's not right; we shouldn't be here. */
yyFail (yystack, NULL); yyFail (yystack, NULL);
yyj += *yytokenp; 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) if (yydefact[yystack->yytops.yystates[0]->yylrState] != 0)
return; return;

View File

@@ -503,19 +503,19 @@ prepare_actions (void)
muscle_insert_base_table ("check", check, muscle_insert_base_table ("check", check,
check[0], 1, high + 1); 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
/* GLR parsing slightly modifies yytable and yycheck reduction is not used in the conflicted entries, so that there is
(and thus yypact) so that in states with unresolved conflicts, a place to put a conflict pointer.
the default reduction is not used in the conflicted entries, so
that there is a place to put a conflict pointer. This means that This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
yyconflp and yyconfl are nonsense for a non-GLR parser, so we parser, so we could avoid accidents by not writing them out in
avoid accidents by not writing them out in that case. */ that case. Nevertheless, it seems even better to be able to use
muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table, the GLR skeletons even without the non-deterministic tables. */
conflict_table[0], 1, high+1); muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list, conflict_table[0], 1, high+1);
conflict_list[0], 1, conflict_list_cnt); 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); table = XREALLOC (table, base_t, table_size);
check = XREALLOC (check, 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) for (/* Nothing. */; old_size < table_size; ++old_size)
{ {
@@ -470,27 +469,22 @@ token_actions (void)
symbol_number_t j; symbol_number_t j;
rule_number_t r; rule_number_t r;
int nconflict = conflicts_total_count (); int nconflict = glr_parser ? conflicts_total_count () : 0;
yydefact = XCALLOC (rule_number_t, nstates); yydefact = XCALLOC (rule_number_t, nstates);
actrow = XCALLOC (action_t, ntokens); actrow = XCALLOC (action_t, ntokens);
conflrow = XCALLOC (unsigned int, 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. */ /* Find the rules which are reduced. */
if (!glr_parser) if (!glr_parser)
for (r = 0; r < nrules; ++r) for (r = 0; r < nrules; ++r)
rules[r].useful = FALSE; 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) for (i = 0; i < nstates; ++i)
{ {
rule_t *default_rule = action_row (states[i]); rule_t *default_rule = action_row (states[i]);
@@ -799,8 +793,7 @@ pack_table (void)
base = XCALLOC (base_t, nvectors); base = XCALLOC (base_t, nvectors);
pos = XCALLOC (base_t, nentries); pos = XCALLOC (base_t, nentries);
table = XCALLOC (base_t, table_size); 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); check = XCALLOC (base_t, table_size);
lowzero = 0; lowzero = 0;