Let nondeterministic skeletons be usable with deterministic
authorAkim Demaille <akim@epita.fr>
Sun, 13 Oct 2002 18:50:40 +0000 (18:50 +0000)
committerAkim Demaille <akim@epita.fr>
Sun, 13 Oct 2002 18:50:40 +0000 (18:50 +0000)
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
data/glr.c
src/output.c
src/tables.c

index e677c61..e9253f1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 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.
        (O0FLAGS): New.
        (VALGRIND, GXX): New.
index 680d120..523c092 100644 (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;
index f82daee..57744b1 100644 (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);
 }
 
 \f
index 47d9d6a..35e7e62 100644 (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;