From ea99527d23f1f4e1e4f358f9f495b2e4e26602af Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 13 Oct 2002 18:50:40 +0000 Subject: [PATCH] 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. --- ChangeLog | 17 +++++++++++++++++ data/glr.c | 15 +++++++-------- src/output.c | 26 +++++++++++++------------- src/tables.c | 21 +++++++-------------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index e677c615..e9253f1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-10-13 Akim Demaille + + 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 * configure.ac (AC_GNU_SOURCE): Use it instead of hand written code. diff --git a/data/glr.c b/data/glr.c index 680d1207..523c092d 100644 --- a/data/glr.c +++ b/data/glr.c @@ -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; diff --git a/src/output.c b/src/output.c index f82daee0..57744b10 100644 --- a/src/output.c +++ b/src/output.c @@ -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); } diff --git a/src/tables.c b/src/tables.c index 47d9d6af..35e7e625 100644 --- a/src/tables.c +++ b/src/tables.c @@ -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; -- 2.47.2