bison-patches
[Top][All Lists]
Advanced

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

proposed namespace cleanup for bison.simple


From: Paul Eggert
Subject: proposed namespace cleanup for bison.simple
Date: Thu, 29 Nov 2001 23:54:52 -0800 (PST)

Bison's bison.simple file unnecessarily infringes on the user name
space in several places.  It uses several local variables whose names
do not begin with YY or yy, which can collide with user-defined
macros.  It uses a couple of macros and functions that begin with _YY
or __yy, which can collide with system names.  (Part of the problem is
due to patches I've contributed over the years without fully
understanding the name space issues -- sorry!)

Conversely, in some cases bison.simple does not include system headers
or contain declarations even when it needs to in order to conform to
the C standard, e.g. to declare fprintf, malloca, or alloca.  This can
cause incorrect code to be generated on some systems.

Here is a proposed patch that attempts to clarify the system header
situation in the documentation, and to clean up the name definitions
in bison.simple.  Historically the trickiest header to include is
<string.h>, so the patch below removes all uses of the builtin string
functions to avoid any problems there.


2001-11-29  Paul Eggert  <address@hidden>

        Name space cleanup in generated parser.

        * doc/bison.texinfo (Bison Parser): Discuss system headers
        and their effect on the user name space.

        * src/bison.simple:
        (YYSTACK_ALLOC, YYSTACK_FREE, union yyalloc, YYSTACK_GAP_MAX,
        YYSTACK_BYTES, YYSTACK_RELOCATE): Do not define unless necessary,
        i.e. unless ! defined (yyoverflow) || defined (YYERROR_VERBOSE).

        (YYSIZE_T): New macro.  Use it instead of size_t, to avoid infringing
        on user names when possible.

        (YYSTACK_USE_ALLOCA): Do not define; just use any existing defn.
        Simplify test for whather <alloca.h> exists.

        (<stdlib.h>): Include if we will use malloc, and if standard C or C++.

        (<stdio.h>): Include if YYDEBUG.

        (yymemcpy): Renamed from __yy_memcpy.  Do not define unless
        ! defined (yyoverflow) && ! defined (yymemcpy).

        (yymemcpy, yyparse): Rename local variables as needed so that
        they all begin with 'yy'.

        (yystrlen, yystpcpy): New functions.

        (YY_DECL_NON_LSP_VARIABLES): Renamed from _YY_DECL_VARIABLES.
        All uses changed.

        (yyparse): size_t -> YYSIZE_T.  Use yystrlen and yystpcpy
        instead of relying on string.h functions.  Use YYSTACK_ALLOC
        and YYSTACK_FREE instead of malloc and free.

===================================================================
RCS file: doc/bison.texinfo,v
retrieving revision 1.30.5.1
retrieving revision 1.30.5.2
diff -pu -r1.30.5.1 -r1.30.5.2
--- doc/bison.texinfo   2001/11/26 19:19:21     1.30.5.1
+++ doc/bison.texinfo   2001/11/30 07:37:17     1.30.5.2
@@ -693,7 +693,7 @@ arrange for it to call @code{yyparse} or
 @xref{Interface, ,Parser C-Language Interface}.
 
 Aside from the token type names and the symbols in the actions you
-write, all variable and function names used in the Bison parser file
+write, all symbols defined in the Bison parser file itself
 begin with @samp{yy} or @samp{YY}.  This includes interface functions
 such as the lexical analyzer function @code{yylex}, the error reporting
 function @code{yyerror} and the parser function @code{yyparse} itself.
@@ -702,6 +702,14 @@ Therefore, you should avoid using C iden
 or @samp{YY} in the Bison grammar file except for the ones defined in
 this manual.
 
+In some cases the Bison parser file includes system headers, and in
+those cases your code should respect the identifiers reserved by those
+headers.  On some address@hidden hosts, @code{<alloca.h>},
address@hidden<stddef.h>}, and @code{<stdlib.h>} are included as needed to
+declare memory allocators and related types.  On all hosts,
address@hidden<stdio.h>} is included if you define @code{YYDEBUG}
+(@pxref{Debugging, ,Debugging Your Parser}).
+
 @node Stages
 @section Stages in Using Bison
 @cindex stages in using Bison
===================================================================
RCS file: src/bison.simple,v
retrieving revision 1.30.5.4
retrieving revision 1.30.5.6
diff -pu -r1.30.5.4 -r1.30.5.6
--- src/bison.simple    2001/11/29 01:36:07     1.30.5.4
+++ src/bison.simple    2001/11/30 07:35:16     1.30.5.6
@@ -28,103 +28,113 @@
    It was written by Richard Stallman by simplifying the hairy parser
    used when %semantic_parser is specified.  */
 
-#ifndef YYSTACK_USE_ALLOCA
-# ifdef alloca
-#  define YYSTACK_USE_ALLOCA 1
-# else /* alloca not defined */
-#  ifdef __GNUC__
-#   define YYSTACK_USE_ALLOCA 1
-#   define alloca __builtin_alloca
-#  else /* not GNU C.  */
-#   if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || 
defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
-#    define YYSTACK_USE_ALLOCA 1
-#    include <alloca.h>
-#   else /* not sparc */
-     /* We think this test detects Watcom and Microsoft C.  */
-     /* This used to test MSDOS, but that is a bad idea since that
-       symbol is in the user namespace.  */
-#    if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
-#     if 0
-       /* No need for malloc.h, which pollutes the namespace; instead,
-         just don't use alloca.  */
-#      include <malloc.h>
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary C library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+#  define YYSIZE_T size_t
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#    define YYSIZE_T size_t
+#   else
+#    if defined (__GNUC__) || defined (_AIX) || defined (__hpux)
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#    ifndef __GNUC__
+#     ifdef _AIX
+ #     pragma alloca
 #     endif
-#    else /* not MSDOS, or __TURBOC__ */
-#     if defined(_AIX)
-       /* I don't know what this was needed for, but it pollutes the
-         namespace.  So I turned it off.  rms, 2 May 1997.  */
-       /* #include <malloc.h>  */
- #pragma alloca
-#      define YYSTACK_USE_ALLOCA 1
-#     else /* not MSDOS, or __TURBOC__, or _AIX */
-#      if 0
-       /* address@hidden says this works for HPUX 9.05 and up, and on
-          HPUX 10.  Eventually we can turn this on.  */
-#       ifdef __hpux
-#        define YYSTACK_USE_ALLOCA 1
-#        define alloca __builtin_alloca
-#      endif /* __hpux */
-#      endif
-#     endif /* not _AIX */
-#    endif /* not MSDOS, or __TURBOC__ */
-#   endif /* not sparc */
-#  endif /* not GNU C */
-# endif /* alloca not defined */
-#endif /* YYSTACK_USE_ALLOCA not defined */
-
-#ifndef YYSTACK_USE_ALLOCA
-# define YYSTACK_USE_ALLOCA 0
-#endif
-
-#if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# define YYSTACK_FREE(Ptr) /* empty */
-#else
-# define YYSTACK_ALLOC malloc
-# define YYSTACK_FREE(Ptr) free (Ptr)
-#endif
+#     if defined (__sgi) || defined (__sparc__) || defined (__sparc) || 
defined (__sun)
+#      include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#      define YYSTACK_ALLOC alloca
+#      define YYSIZE_T size_t
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+#  define YYSTACK_FREE(Ptr) /* empty */
+# else
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE(Ptr) free (Ptr)
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+# endif
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
   short yys;
   YYSTYPE yyv;
-#if YYLSP_NEEDED
+# if YYLSP_NEEDED
   YYLTYPE yyl;
-#endif
+# endif
 };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
-#define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
 
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
-#if YYLSP_NEEDED
-# define YYSTACK_BYTES(N) \
-    ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))      \
-     + 2 * YYSTACK_GAP_MAX)
-#else
-# define YYSTACK_BYTES(N) \
-    ((N) * (sizeof (short) + sizeof (YYSTYPE))                         \
-     + YYSTACK_GAP_MAX)
-#endif
+# if YYLSP_NEEDED
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))     \
+      + 2 * YYSTACK_GAP_MAX)
+# else
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))                                
\
+      + YYSTACK_GAP_MAX)
+# endif
 
 /* Relocate the TYPE STACK from its old location to the new one.  The
-   local variables SIZE and YYSTACKSIZE give the old and new number of
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-#define YYSTACK_RELOCATE(Type, Stack)                                  \
-do                                                                     \
-  {                                                                    \
-    size_t yynewbytes;                                                 \
-    __yy_memcpy (yyptr, (char *) (Stack), size * sizeof (Type));       \
-    (Stack) = (Type *) yyptr;                                          \
-    yynewbytes = yystacksize * sizeof (Type) + YYSTACK_GAP_MAX;                
\
-    yynewbytes -= yynewbytes % sizeof (union yyalloc);                 \
-    yyptr += yynewbytes;                                               \
-  }                                                                    \
-while (0)
+# define YYSTACK_RELOCATE(Type, Stack)                                 \
+    do                                                                 \
+      {                                                                        
\
+       YYSIZE_T yynewbytes;                                            \
+       yymemcpy (yyptr, (char *) (Stack),                              \
+                 yysize * (YYSIZE_T) sizeof (Type));                   \
+       (Stack) = (Type *) yyptr;                                       \
+       yynewbytes = yystacksize * sizeof (Type) + YYSTACK_GAP_MAX;     \
+       yynewbytes -= yynewbytes % sizeof (union yyalloc);              \
+       yyptr += yynewbytes;                                            \
+      }                                                                        
\
+    while (0)
+
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
 
 #define yyerrok                (yyerrstatus = 0)
 #define yyclearin      (yychar = YYEMPTY)
@@ -196,6 +206,7 @@ while (0)
 
 /* Enable debugging if requested.  */
 #if YYDEBUG
+# include <stdio.h>
 # define YYDPRINTF(Args)                       \
 do {                                           \
   if (yydebug)                                 \
@@ -230,30 +241,83 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-#if __GNUC__ > 1               /* GNU C and GNU C++ define this.  */
-# define __yy_memcpy(To, From, Count)  __builtin_memcpy (To, From, Count)
-#else                          /* not GNU C or C++ */
+#if ! defined (yyoverflow) && ! defined (yymemcpy)
+# if __GNUC__ > 1              /* GNU C and GNU C++ define this.  */
+#  define yymemcpy __builtin_memcpy
+# else                         /* not GNU C or C++ */
 
 /* This is the most reliable way to avoid incompatibilities
    in available built-in functions on various systems.  */
 static void
-# ifndef __cplusplus
-__yy_memcpy (to, from, count)
-     char *to;
-     const char *from;
-     size_t count;
-# else /* __cplusplus */
-__yy_memcpy (char *to, const char *from, size_t count)
+#  if defined (__STDC__) || defined (__cplusplus)
+yymemcpy (char *yyto, const char *yyfrom, YYSIZE_T yycount)
+#  else
+yymemcpy (yyto, yyfrom, yycount)
+     char *yyto;
+     const char *yyfrom;
+     YYSIZE_T yycount;
+#  endif
+{
+  register const char *yyf = yyfrom;
+  register char *yyt = yyto;
+  register YYSIZE_T yyi = yycount;
+
+  while (yyi-- != 0)
+    *yyt++ = *yyf++;
+}
 # endif
+#endif
+
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
 {
-  register const char *f = from;
-  register char *t = to;
-  register size_t i = count;
+  register const char *yys = yystr;
 
-  while (i-- != 0)
-    *t++ = *f++;
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
 }
+#  endif
+# endif
 
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   ifndef __cplusplus
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   else
+yystpcpy (char *yydest, const char *yysrc)
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
 #endif
 
 #line
@@ -289,7 +353,7 @@ int yyparse (void);
 /* YY_DECL_VARIABLES -- depending whether we use a pure parser,
    variables are global, or local to YYPARSE.  */
 
-#define _YY_DECL_VARIABLES                             \
+#define YY_DECL_NON_LSP_VARIABLES                      \
 /* The lookahead symbol.  */                           \
 int yychar;                                            \
                                                        \
@@ -301,13 +365,13 @@ int yynerrs;
 
 #if YYLSP_NEEDED
 # define YY_DECL_VARIABLES                     \
-_YY_DECL_VARIABLES                             \
+YY_DECL_NON_LSP_VARIABLES                      \
                                                \
 /* Location data for the lookahead symbol.  */ \
 YYLTYPE yylloc;
 #else
 # define YY_DECL_VARIABLES                     \
-_YY_DECL_VARIABLES
+YY_DECL_NON_LSP_VARIABLES
 #endif
 
 
@@ -365,15 +429,15 @@ yyparse (YYPARSE_PARAM_ARG)
 # define YYPOPSTACK   (yyvsp--, yyssp--)
 #endif
 
-  size_t yystacksize = YYINITDEPTH;
+  YYSIZE_T yystacksize = YYINITDEPTH;
 
 
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
-# if YYLSP_NEEDED
+#if YYLSP_NEEDED
   YYLTYPE yyloc;
-# endif
+#endif
 
   /* When reducing, the number of symbols on the RHS of the reduced
      rule. */
@@ -413,7 +477,7 @@ yyparse (YYPARSE_PARAM_ARG)
   if (yyssp >= yyss + yystacksize - 1)
     {
       /* Get the current used size of the three stacks, in elements.  */
-      size_t size = yyssp - yyss + 1;
+      YYSIZE_T yysize = yyssp - yyss + 1;
 
 #ifdef yyoverflow
       {
@@ -430,15 +494,15 @@ yyparse (YYPARSE_PARAM_ARG)
        /* This used to be a conditional around just the two extra args,
           but that might be undefined if yyoverflow is a macro.  */
        yyoverflow ("parser stack overflow",
-                   &yyss1, size * sizeof (*yyssp),
-                   &yyvs1, size * sizeof (*yyvsp),
-                   &yyls1, size * sizeof (*yylsp),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+                   &yyls1, yysize * sizeof (*yylsp),
                    &yystacksize);
        yyls = yyls1;
 # else
        yyoverflow ("parser stack overflow",
-                   &yyss1, size * sizeof (*yyssp),
-                   &yyvs1, size * sizeof (*yyvsp),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
                    &yystacksize);
 # endif
        yyss = yyss1;
@@ -468,10 +532,10 @@ yyparse (YYPARSE_PARAM_ARG)
       }
 #endif /* no yyoverflow */
 
-      yyssp = yyss + size - 1;
-      yyvsp = yyvs + size - 1;
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
 #if YYLSP_NEEDED
-      yylsp = yyls + size - 1;
+      yylsp = yyls + yysize - 1;
 #endif
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
@@ -627,14 +691,14 @@ yyreduce:
      are defined only if `YYDEBUG' is set.  */
   if (yydebug)
     {
-      int i;
+      int yyi;
 
       fprintf (stderr, "Reducing via rule %d (line %d), ",
               yyn, yyrline[yyn]);
 
       /* Print the symbols being reduced, and their result.  */
-      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
-       fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
+       fprintf (stderr, "%s ", yytname[yyrhs[yyi]]);
       fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
     }
 #endif
@@ -650,10 +714,10 @@ yyreduce:
 #if YYDEBUG
   if (yydebug)
     {
-      short *ssp1 = yyss - 1;
+      short *yyssp1 = yyss - 1;
       fprintf (stderr, "state stack now");
-      while (ssp1 != yyssp)
-       fprintf (stderr, " %d", *++ssp1);
+      while (yyssp1 != yyssp)
+       fprintf (stderr, " %d", *++yyssp1);
       fprintf (stderr, "\n");
     }
 #endif
@@ -692,39 +756,41 @@ yyerrlab:
 
       if (yyn > YYFLAG && yyn < YYLAST)
        {
-         size_t size = 0;
-         char *msg;
-         int x, count;
+         YYSIZE_T yysize = 0;
+         char *yymsg;
+         int yyx, yycount;
 
-         count = 0;
-         /* Start X at -YYN if negative to avoid negative indexes in
+         yycount = 0;
+         /* Start YYX at -YYN if negative to avoid negative indexes in
             YYCHECK.  */
-         for (x = yyn < 0 ? -yyn : 0;
-              x < (int) (sizeof (yytname) / sizeof (char *)); x++)
-           if (yycheck[x + yyn] == x)
-             size += strlen (yytname[x]) + 15, count++;
-         size += strlen ("parse error, unexpected ") + 1;
-         size += strlen (yytname[YYTRANSLATE (yychar)]);
-         msg = (char *) malloc (size);
-         if (msg != 0)
+         for (yyx = yyn < 0 ? -yyn : 0;
+              yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+           if (yycheck[yyx + yyn] == yyx)
+             yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+         yysize += yystrlen ("parse error, unexpected ") + 1;
+         yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
+         yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg != 0)
            {
-             strcpy (msg, "parse error, unexpected ");
-             strcat (msg, yytname[YYTRANSLATE (yychar)]);
+             char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+             yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
 
-             if (count < 5)
+             if (yycount < 5)
                {
-                 count = 0;
-                 for (x = yyn < 0 ? -yyn : 0;
-                      x < (int) (sizeof (yytname) / sizeof (char *)); x++)
-                   if (yycheck[x + yyn] == x)
+                 yycount = 0;
+                 for (yyx = yyn < 0 ? -yyn : 0;
+                      yyx < (int) (sizeof (yytname) / sizeof (char *));
+                      yyx++)
+                   if (yycheck[yyx + yyn] == yyx)
                      {
-                       strcat (msg, count == 0 ? ", expecting " : " or ");
-                       strcat (msg, yytname[x]);
-                       count++;
+                       const char *yyq = ! yycount ? ", expecting " : " or ";
+                       yyp = yystpcpy (yyp, yyq);
+                       yyp = yystpcpy (yyp, yytname[yyx]);
+                       yycount++;
                      }
                }
-             yyerror (msg);
-             free (msg);
+             yyerror (yymsg);
+             YYSTACK_FREE (yymsg);
            }
          else
            yyerror ("parse error; also virtual memory exhausted");
@@ -793,10 +859,10 @@ yyerrpop:
 #if YYDEBUG
   if (yydebug)
     {
-      short *ssp1 = yyss - 1;
+      short *yyssp1 = yyss - 1;
       fprintf (stderr, "Error: state stack now");
-      while (ssp1 != yyssp)
-       fprintf (stderr, " %d", *++ssp1);
+      while (yyssp1 != yyssp)
+       fprintf (stderr, " %d", *++yyssp1);
       fprintf (stderr, "\n");
     }
 #endif



reply via email to

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