bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bison 1.50 breaks reentrant yyerror() usage


From: Paul Eggert
Subject: Re: Bison 1.50 breaks reentrant yyerror() usage
Date: Fri, 11 Oct 2002 14:01:36 -0700 (PDT)

> Date: Fri, 11 Oct 2002 20:01:14 +0200
> From: "Ralf S. Engelschall" <address@hidden>
> 
> You recently introduced an internal function yyreport_parse_error()
> and inside this one you're using yyerror(). If the user #defined an
> own yyerror() which relies on YYPARSE_PARAM this is now broken on
> Bison >= 1.50 because YYPARSE_PARAM is not passed to yyreport_parse_error().
> 
> This is nasty because for good error reporting one has to override
> yyerror() and for reentrant reasons one cannot use a global variable for
> passing the application context through. So please at least pass through
> YYPARSE_PARAM to yyreport_parse_error().
> 
> Just to make sure you're understand our problem: For instance in OSSP
> cfg (http://www.ossp.org/pkg/lib/cfg/) we're using...
> 
> | [...]
> | /* make sure yyparse() accepts a context pointer and
> |    passes through its inlined scanner context to yylex() */
> | #define CTX           ((cfg_syn_ctx_t *)ctx)
> | #define YYPARSE_PARAM ctx
> | #define YYLEX_PARAM   CTX->yyscan
> | [...]
> | /* generate verbose error messages and remember them inside the context */
> | #undef  yyerror
> | #define yyerror(msg) \
> |     cfg_syn_error(CTX, CFG_ERR_SYN, &yylloc, msg)
> | #define YYERROR_VERBOSE
> | [...]
> 
> ...for full reentrancy throughout Flex & Bison. This worked fine until
> recently with Flex 2.5.2x and Bison 1.3x. But now with Bison 1.50 this
> is broken and I don't see any way how to fix it now without changing the
> output of Bison. Did I missed something?

I don't think so.  Apparently we need to rethink subroutines within
the parser; in the meantime the simplest fix is to undo the introduction
of yyreport_parse_error, so I've installed the following patch.

PS.  In the future, can you please send bug reports to
address@hidden  We like having them archived by the GNU project.
Thanks.

2002-10-11  Paul Eggert  <address@hidden>

        * data/yacc.c (yyreport_parse_error): Remove, putting its body into...
        (yyparse): here.  This undoes some of the 2002-07-25 change.
        Compatibility problem reported by Ralf S. Engelschall with
        OSSP cfg <http://www.ossp.org/pkg/lib/cfg/>.

Index: yacc.c
===================================================================
RCS file: /cvsroot/bison/bison/data/yacc.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -p -u -r1.14 -r1.15
--- yacc.c      7 Sep 2002 06:32:24 -0000       1.14
+++ yacc.c      11 Oct 2002 20:53:39 -0000      1.15
@@ -648,74 +648,6 @@ m4_map([b4_symbol_actions], m4_defn([b4_
 #endif /* YYDEBUG. */
 
 
-/*----------------------------------------------------------.
-| yyreport_parse_error -- report a parse error in YYSTATE.  |
-`----------------------------------------------------------*/
-
-b4_c_function([yyreport_parse_error],
-             [static void],
-             [[int],     [yystate]],
-             [[int],     [yychar]],
-             [[YYSTYPE], [yyvalue]]b4_location_if([,
-             [[YYLTYPE], [yylloc]]]))
-[{
-#if YYERROR_VERBOSE
-  int yyn = yypact[yystate];
-
-  if (YYPACT_NINF < yyn && yyn < YYLAST)
-    {
-      YYSIZE_T yysize = 0;
-      int yytype = YYTRANSLATE (yychar);
-      char *yymsg;
-      int yyx, yycount;
-
-      yycount = 0;
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-        YYCHECK.  */
-      for (yyx = yyn < 0 ? -yyn : 0;
-          yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
-       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-         yysize += yystrlen (yytname[yyx]) + 15, yycount++;
-      yysize += yystrlen ("parse error, unexpected ") + 1;
-      yysize += yystrlen (yytname[yytype]);
-      yymsg = (char *) YYSTACK_ALLOC (yysize);
-      if (yymsg != 0)
-       {
-         char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
-         yyp = yystpcpy (yyp, yytname[yytype]);
-
-         if (yycount < 5)
-           {
-             yycount = 0;
-             for (yyx = yyn < 0 ? -yyn : 0;
-                  yyx < (int) (sizeof (yytname) / sizeof (char *));
-                  yyx++)
-               if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-                 {
-                   const char *yyq = ! yycount ? ", expecting " : " or ";
-                   yyp = yystpcpy (yyp, yyq);
-                   yyp = yystpcpy (yyp, yytname[yyx]);
-                   yycount++;
-                 }
-           }
-         yyerror (yymsg);
-         YYSTACK_FREE (yymsg);
-       }
-      else
-       yyerror ("parse error; also virtual memory exhausted");
-    }
-  else
-#endif /* YYERROR_VERBOSE */
-    yyerror ("parse error");
-
-  /* Pacify ``unused variable'' warnings.  */
-  (void) yystate;
-  (void) yychar;
-  (void) yyvalue;
-  ]b4_location_if([(void) yylloc;])[
-}]
-
-
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
 `-----------------------------------------------*/
@@ -1127,7 +1059,54 @@ yyerrlab:
   if (!yyerrstatus)
     {
       ++yynerrs;
-      yyreport_parse_error (yystate, yychar, yylval]b4_location_if([, 
yylloc])[);
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+       {
+         YYSIZE_T yysize = 0;
+         int yytype = YYTRANSLATE (yychar);
+         char *yymsg;
+         int yyx, yycount;
+
+         yycount = 0;
+         /* Start YYX at -YYN if negative to avoid negative indexes in
+            YYCHECK.  */
+         for (yyx = yyn < 0 ? -yyn : 0;
+              yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+             yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+         yysize += yystrlen ("parse error, unexpected ") + 1;
+         yysize += yystrlen (yytname[yytype]);
+         yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg != 0)
+           {
+             char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+             yyp = yystpcpy (yyp, yytname[yytype]);
+
+             if (yycount < 5)
+               {
+                 yycount = 0;
+                 for (yyx = yyn < 0 ? -yyn : 0;
+                      yyx < (int) (sizeof (yytname) / sizeof (char *));
+                      yyx++)
+                   if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+                     {
+                       const char *yyq = ! yycount ? ", expecting " : " or ";
+                       yyp = yystpcpy (yyp, yyq);
+                       yyp = yystpcpy (yyp, yytname[yyx]);
+                       yycount++;
+                     }
+               }
+             yyerror (yymsg);
+             YYSTACK_FREE (yymsg);
+           }
+         else
+           yyerror ("parse error; also virtual memory exhausted");
+       }
+      else
+#endif /* YYERROR_VERBOSE */
+       yyerror ("parse error");
     }
   goto yyerrlab1;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]