bison-patches
[Top][All Lists]
Advanced

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

FYI: Merge maint into master


From: Akim Demaille
Subject: FYI: Merge maint into master
Date: Tue, 10 Dec 2013 08:55:17 +0100

commit b7d4c48e55a315a51e308347ca3c5e965ab013a3
Merge: fc6c856 b167e7b
Author: Akim Demaille <address@hidden>
Date:   Tue Dec 10 08:49:49 2013 +0100

    Merge remote-tracking branch 'origin/maint'
    
    * origin/maint:
      package: install the examples
      package: install README and the like in docdir
      diagnostics: fix the order of multiple declarations reports
      symbol: provide an easy means to compare them in source order
    
    Conflicts:
      src/symtab.c
      tests/input.at
    
    * tests/input.at: Comment out a test that master currently does not
    pass (because of a7280757105b2909f6a58fdd1c582de8e278319a).


Merge: 4f3cc9c 0bd5ee5
Author: Akim Demaille <address@hidden>
Date:   Mon Dec 9 10:43:37 2013 +0100

    Merge remote-tracking branch 'origin/maint'
    
    * origin/maint: (43 commits)
      maint: post-release administrivia
      version 3.0.2
      gnulib: update
      output: do not generate source files when late errors are caught
      output: record what generated files are source or report files
      output: do not generate source files when early errors are caught
      xml: also use "%empty" with html output
      style: formatting changes
      xml: also display %empty for empty right-hand sides
      reports: display %empty in the generated pointed-rules
      news: YYERROR vs variants
      style: scope reduction in lalr.cc
      lalr1.cc: formatting changes
      lalr1.cc: fix the support of YYERROR with variants
      tests: check $$'s destruction with variant, YYERROR, and no error recovery
      tests: simplify useless obfuscation
      skeletons: use better names when computing a "goto"
      maint: post-release administrivia
      version 3.0.1
      aver: it is no longer "protected against NDEBUG"
      ...
    
    Conflicts:
      data/glr.c


diff --git a/.gitignore b/.gitignore
index e9708d3..b857196 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,10 @@
 *.eps
+*.log
 *.o
 *.pdf
 *.png
 *.stamp
+*.trs
 *~
 .deps
 .dirstamp
diff --git a/.prev-version b/.prev-version
index 9f55b2c..b502146 100644
--- a/.prev-version
+++ b/.prev-version
@@ -1 +1 @@
-3.0
+3.0.2
diff --git a/Makefile.am b/Makefile.am
index 339a3c6..becd1d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,8 +24,10 @@ SUBDIRS = po runtime-po .
 aclocaldir = @aclocaldir@
 aclocal_DATA = m4/bison-i18n.m4
 
-EXTRA_DIST = .prev-version .version \
-  cfg.mk ChangeLog-1998 ChangeLog-2012 PACKAGING
+EXTRA_DIST = .prev-version .version cfg.mk PACKAGING \
+  ChangeLog-1998 ChangeLog-2012 ChangeLog
+
+dist_doc_DATA = AUTHORS COPYING NEWS README THANKS TODO
 
 ## Running the bison from this tarball.  To generate our own parser,
 ## but also to run the tests.  Of course, you ought to keep a sane
diff --git a/NEWS b/NEWS
index bbdcc0f..e6521bf 100644
--- a/NEWS
+++ b/NEWS
@@ -4,7 +4,94 @@ GNU Bison NEWS
 
 ** Bug fixes
 
-  Portability issues in the test suite.
+*** Redeclarations are reported in proper order
+
+  On
+
+    %token FOO "foo"
+    %printer {} "foo"
+    %printer {} FOO
+
+  bison used to report:
+
+    /tmp/foo.yy:2.10-11: error: %printer redeclaration for FOO
+     %printer {} "foo"
+              ^^
+    /tmp/foo.yy:3.10-11:     previous declaration
+     %printer {} FOO
+              ^^
+
+  Now, the "previous" declaration is always the first one.
+
+
+** Documentation
+
+  Bison now installs various files in its docdir (which defaults to
+  '/usr/local/share/doc/bison'), including the three fully blown examples
+  extracted from the documentation:
+
+   - rpcalc
+     Reverse polish calculator, a simple introductory example.
+   - mfcalc
+     Multi-function Calc, a calculator with memory and functions and located
+     error messages.
+   - calc++
+     a calculator in C++ using variant support and token constructors.
+
+* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
+
+** Bug fixes
+
+*** Generated source files when errors are reported
+
+  When warnings are issued and -Werror is set, bison would still generate
+  the source files (*.c, *.h...).  As a consequence, some runs of "make"
+  could fail the first time, but not the second (as the files were generated
+  anyway).
+
+  This is fixed: bison no longer generates this source files, but, of
+  course, still produces the various reports (*.output, *.xml, etc.).
+
+*** %empty is used in reports
+
+  Empty right-hand sides are denoted by '%empty' in all the reports (text,
+  dot, XML and formats derived from it).
+
+*** YYERROR and variants
+
+  When C++ variant support is enabled, an error triggered via YYERROR, but
+  not caught via error recovery, resulted in a double deletion.
+
+* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
+
+** Bug fixes
+
+*** Errors in caret diagnostics
+
+  On some platforms, some errors could result in endless diagnostics.
+
+*** Fixes of the -Werror option
+
+  Options such as "-Werror -Wno-error=foo" were still turning "foo"
+  diagnostics into errors instead of warnings.  This is fixed.
+
+  Actually, for consistency with GCC, "-Wno-error=foo -Werror" now also
+  leaves "foo" diagnostics as warnings.  Similarly, with "-Werror=foo
+  -Wno-error", "foo" diagnostics are now errors.
+
+*** GLR Predicates
+
+  As demonstrated in the documentation, one can now leave spaces between
+  "%?" and its "{".
+
+*** Installation
+
+  The yacc.1 man page is no longer installed if --disable-yacc was
+  specified.
+
+*** Fixes in the test suite
+
+  Bugs and portability issues.
 
 * Noteworthy changes in release 3.0 (2013-07-25) [stable]
 
diff --git a/README-hacking b/README-hacking
index 28870cb..ab82a3a 100644
--- a/README-hacking
+++ b/README-hacking
@@ -62,13 +62,22 @@ tools we depend upon, including:
 - Gettext <http://www.gnu.org/software/gettext/>
 - Graphviz <http://www.graphviz.org>
 - Gzip <http://www.gnu.org/software/gzip/>
+- Help2man <http://www.gnu.org/software/help2man/>
 - Perl <http://www.cpan.org/>
 - Rsync <http://samba.anu.edu.au/rsync/>
 - Tar <http://www.gnu.org/software/tar/>
+- Texinfo <http://www.gnu.org/software/texinfo/>
 
 Valgrind <http://valgrind.org/> is also highly recommended, if it supports
 your architecture.
 
+If you're using a GNU/Linux distribution, the easiest way to install the
+above packages depends on your system.  The following shell command should
+work for Debian-based systems such as Ubuntu:
+
+  sudo apt-get install \
+    autoconf automake autopoint flex graphviz help2man texinfo valgrind
+
 Bison is written using Bison grammars, so there are bootstrapping issues.
 The bootstrap script attempts to discover when the C code generated from the
 grammars is out of date, and to bootstrap with an out-of-date version of the
diff --git a/THANKS b/THANKS
index 2d4a6a9..ebadb44 100644
--- a/THANKS
+++ b/THANKS
@@ -66,6 +66,7 @@ Johan van Selst           address@hidden
 Jonathan Fabrizio         address@hidden
 Jonathan Nieder           address@hidden
 Juan Manuel Guerrero      address@hidden
+Ken Moffat                address@hidden
 Kees Zeelenberg           address@hidden
 Keith Browne              address@hidden
 Laurent Mascherpa         address@hidden
@@ -79,6 +80,7 @@ Martin Mokrejs            address@hidden
 Martin Nylin              address@hidden
 Matt Kraai                address@hidden
 Matt Rosing               address@hidden
+Michael Felt              address@hidden
 Michael Hayes             address@hidden
 Michael Raskin            address@hidden
 Michiel De Wilde          address@hidden
@@ -94,6 +96,7 @@ Odd Arild Olsen           address@hidden
 Oleg Smolsky              address@hidden
 Oleksii Taran             address@hidden
 Paolo Bonzini             address@hidden
+Paolo Simone Gasparello   address@hidden
 Pascal Bart               address@hidden
 Paul Eggert               address@hidden
 Paul Hilfinger            address@hidden
@@ -110,6 +113,7 @@ R Blake                   address@hidden
 Raja R Harinath           address@hidden
 Ralf Wildenhues           address@hidden
 Richard Stallman          address@hidden
+Rici Lake                 address@hidden
 Rob Vermaas               address@hidden
 Robert Anisko             address@hidden
 Rob Conde                 address@hidden
diff --git a/bootstrap b/bootstrap
index a37fb8a..e31d17d 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Print a version string.
-scriptversion=2013-07-03.20; # UTC
+scriptversion=2013-08-15.22; # UTC
 
 # Bootstrap this package from checked-out sources.
 
@@ -209,12 +209,16 @@ bootstrap_sync=false
 # Use git to update gnulib sources
 use_git=true
 
+check_exists() {
+  ($1 --version </dev/null) >/dev/null 2>&1
+  test $? -lt 126
+}
+
 # find_tool ENVVAR NAMES...
 # -------------------------
 # Search for a required program.  Use the value of ENVVAR, if set,
-# otherwise find the first of the NAMES that can be run (i.e.,
-# supports --version).  If found, set ENVVAR to the program name,
-# die otherwise.
+# otherwise find the first of the NAMES that can be run.
+# If found, set ENVVAR to the program name, die otherwise.
 #
 # FIXME: code duplication, see also gnu-web-doc-update.
 find_tool ()
@@ -224,27 +228,21 @@ find_tool ()
   find_tool_names=$@
   eval "find_tool_res=\$$find_tool_envvar"
   if test x"$find_tool_res" = x; then
-    for i
-    do
-      if ($i --version </dev/null) >/dev/null 2>&1; then
-       find_tool_res=$i
-       break
+    for i; do
+      if check_exists $i; then
+        find_tool_res=$i
+        break
       fi
     done
-  else
-    find_tool_error_prefix="\$$find_tool_envvar: "
   fi
-  test x"$find_tool_res" != x \
-    || die "one of these is required: $find_tool_names"
-  ($find_tool_res --version </dev/null) >/dev/null 2>&1 \
-    || die "${find_tool_error_prefix}cannot run $find_tool_res --version"
+  if test x"$find_tool_res" = x; then
+    warn_ "one of these is required: $find_tool_names;"
+    die   "alternatively set $find_tool_envvar to a compatible tool"
+  fi
   eval "$find_tool_envvar=\$find_tool_res"
   eval "export $find_tool_envvar"
 }
 
-# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
-find_tool SHA1SUM sha1sum gsha1sum shasum
-
 # Override the default configuration, if necessary.
 # Make sure that bootstrap.conf is sourced from the current directory
 # if we were invoked as "sh bootstrap".
@@ -326,7 +324,7 @@ insert_if_absent() {
     die "Error: Duplicate entries in $file: " $duplicate_entries
   fi
   linesold=$(gitignore_entries $file | wc -l)
-  linesnew=$(echo "$str" | gitignore_entries - $file | sort -u | wc -l)
+  linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc 
-l)
   if [ $linesold != $linesnew ] ; then
     { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
       || die "insert_if_absent $file $str: failed"
@@ -469,8 +467,7 @@ check_versions() {
     if [ "$req_ver" = "-" ]; then
       # Merely require app to exist; not all prereq apps are well-behaved
       # so we have to rely on $? rather than get_version.
-      $app --version >/dev/null 2>&1
-      if [ 126 -le $? ]; then
+      if ! check_exists $app; then
         warn_ "Error: '$app' not found"
         ret=1
       fi
@@ -503,6 +500,12 @@ print_versions() {
   # can't depend on column -t
 }
 
+# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
+# Also find the compatible sha1 utility on the BSDs
+if test x"$SKIP_PO" = x; then
+  find_tool SHA1SUM sha1sum gsha1sum shasum sha1
+fi
+
 use_libtool=0
 # We'd like to use grep -E, to see if any of LT_INIT,
 # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
@@ -551,10 +554,10 @@ fi
 echo "$0: Bootstrapping from checked-out $package sources..."
 
 # See if we can use gnulib's git-merge-changelog merge driver.
-if $use_git && test -d .git && (git --version) >/dev/null 2>/dev/null ; then
+if $use_git && test -d .git && check_exists git; then
   if git config merge.merge-changelog.driver >/dev/null ; then
     :
-  elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
+  elif check_exists git-merge-changelog; then
     echo "$0: initializing git-merge-changelog driver"
     git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
     git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
@@ -692,11 +695,10 @@ update_po_files() {
     cksum_file="$ref_po_dir/$po.s1"
     if ! test -f "$cksum_file" ||
         ! test -f "$po_dir/$po.po" ||
-        ! $SHA1SUM -c --status "$cksum_file" \
-            < "$new_po" > /dev/null; then
+        ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
       echo "$me: updated $po_dir/$po.po..."
       cp "$new_po" "$po_dir/$po.po" \
-          && $SHA1SUM < "$new_po" > "$cksum_file"
+          && $SHA1SUM < "$new_po" > "$cksum_file" || return
     fi
   done
 }
diff --git a/bootstrap.conf b/bootstrap.conf
index c58470e..186afa7 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -34,7 +34,8 @@ gnulib_modules='
   readme-release
   realloc-posix
   spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp
-  unistd unistd-safer unlocked-io update-copyright unsetenv verify
+  unistd unistd-safer unlink unlocked-io
+  update-copyright unsetenv verify
   warnings
   xalloc
   xalloc-die
diff --git a/configure.ac b/configure.ac
index 992e203..2658d73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,11 +33,7 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], 
[$PACKAGE_COPYRIGHT_YEAR],
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
 
-# Automake 1.10.3 and 1.11.1 fix a security flaw discussed here:
-#
-#   http://thread.gmane.org/gmane.comp.sysutils.autotools.announce/131
-#
-# To avoid 1.11, we make 1.11.1 the minimum version.
+# We use Automake 1.14's %D% and %C%.
 #
 # We want gnits strictness only when rolling a stable release.  For
 # release candidates, we use version strings like 2.4.3_rc1, but gnits
@@ -45,7 +41,7 @@ AC_CONFIG_MACRO_DIR([m4])
 # releases, we want to be able run make dist without being required to
 # add a bogus NEWS entry.  In that case, the version string
 # automatically contains a dash, which we also let disable gnits.
-AM_INIT_AUTOMAKE([1.11.1 dist-xz nostdinc
+AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc
                  color-tests parallel-tests
                  silent-rules]
                  m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
@@ -75,14 +71,17 @@ AC_CACHE_CHECK([whether pragma GCC diagnostic push works],
   CFLAGS=$save_CFLAGS])
 
 AC_ARG_ENABLE([gcc-warnings],
-[  --enable-gcc-warnings   turn on lots of GCC warnings (not recommended)],
+[  --enable-gcc-warnings   turn on lots of GCC warnings (not recommended).
+                           Also, issue synclines from the examples/ to
+                           the corresponding source in the Texinfo doc.],
 [case $enable_gcc_warnings in
    yes|no) ;;
    *)  AC_MSG_ERROR([invalid value for --gcc-warnings: $enable_gcc_warnings]);;
  esac],
               [enable_gcc_warnings=no])
+AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes])
 if test "$enable_gcc_warnings" = yes; then
-  warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align
+  warn_common='-Wall-Wextra -Wno-sign-compare -Wcast-align -Wdocumentation
     -Wformat -Wpointer-arith -Wwrite-strings'
   warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes'
   warn_cxx='-Wnoexcept'
@@ -161,16 +160,7 @@ AC_ARG_ENABLE([yacc],
   [AC_HELP_STRING([--disable-yacc],
      [do not build a yacc command or an -ly library])],
   , [enable_yacc=yes])
-case $enable_yacc in
-yes)
-  YACC_SCRIPT=src/yacc
-  YACC_LIBRARY=lib/liby.a;;
-*)
-  YACC_SCRIPT=
-  YACC_LIBRARY=;;
-esac
-AC_SUBST([YACC_SCRIPT])
-AC_SUBST([YACC_LIBRARY])
+AM_CONDITIONAL([ENABLE_YACC], [test "$enable_yacc" = yes])
 
 # Checks for programs.
 AM_MISSING_PROG([DOT], [dot])
@@ -179,6 +169,8 @@ $LEX_IS_FLEX || test "X$LEX" = X: || {
   AC_MSG_WARN([bypassing lex because flex is required])
   LEX=:
 }
+AM_CONDITIONAL([FLEX_CXX_WORKS],
+  [$LEX_IS_FLEX && test $bison_cv_cxx_works = yes])
 AC_PROG_YACC
 AC_PROG_RANLIB
 AC_PROG_GNU_M4
diff --git a/data/c.m4 b/data/c.m4
index b1b4394..b0524ef 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -205,13 +205,32 @@ m4_define([b4_table_value_equals],
 
 # b4_attribute_define
 # -------------------
-# Provide portability for __attribute__.
+# Provide portable compiler "attributes".
 m4_define([b4_attribute_define],
-[#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later.  */
-# if (! defined __GNUC__ || __GNUC__ < 2 \
-      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
-#  define __attribute__(Spec) /* empty */
+[#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
 # endif
 #endif
 
@@ -250,14 +269,14 @@ m4_define([b4_attribute_define],
 
 # b4_null_define
 # --------------
-# Portability issues: define a YY_NULL appropriate for the current
+# Portability issues: define a YY_NULLPTR appropriate for the current
 # language (C, C++98, or C++11).
 m4_define([b4_null_define],
-[# ifndef YY_NULL
+[# ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULL nullptr
+#   define YY_NULLPTR nullptr
 #  else
-#   define YY_NULL 0
+#   define YY_NULLPTR 0
 #  endif
 # endif[]dnl
 ])
@@ -266,7 +285,7 @@ m4_define([b4_null_define],
 # b4_null
 # -------
 # Return a null pointer constant.
-m4_define([b4_null], [YY_NULL])
+m4_define([b4_null], [YY_NULLPTR])
 
 # b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
 # -------------------------------------------------------------
@@ -783,7 +802,7 @@ m4_define([b4_yy_location_print_define],
 
 /* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
 
-__attribute__((__unused__))
+YY_ATTRIBUTE_UNUSED
 ]b4_function_define([yy_location_print_],
     [static unsigned],
                [[FILE *yyo],                    [yyo]],
diff --git a/data/glr.c b/data/glr.c
index 1f8f0b3..c627a9b 100644
--- a/data/glr.c
+++ b/data/glr.c
@@ -445,9 +445,9 @@ int yydebug;
 
 struct yyGLRStack;
 static void yypstack (struct yyGLRStack* yystackp, size_t yyk)
-  __attribute__ ((__unused__));
+  YY_ATTRIBUTE_UNUSED;
 static void yypdumpstack (struct yyGLRStack* yystackp)
-  __attribute__ ((__unused__));
+  YY_ATTRIBUTE_UNUSED;
 
 #else /* !]b4_api_PREFIX[DEBUG */
 
@@ -669,19 +669,15 @@ struct yyGLRStack {
 static void yyexpandGLRStack (yyGLRStack* yystackp);
 #endif
 
-static void yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
-  __attribute__ ((__noreturn__));
-static void
+static _Noreturn void
 yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
 {
-  if (yymsg != YY_NULL)
+  if (yymsg != YY_NULLPTR)
     yyerror (]b4_yyerror_args[yymsg);
   YYLONGJMP (yystackp->yyexception_buffer, 1);
 }
 
-static void yyMemoryExhausted (yyGLRStack* yystackp)
-  __attribute__ ((__noreturn__));
-static void
+static _Noreturn void
 yyMemoryExhausted (yyGLRStack* yystackp)
 {
   YYLONGJMP (yystackp->yyexception_buffer, 2);
@@ -702,7 +698,7 @@ yytokenName (yySymbol yytoken)
 /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
  *  at YYVSP[YYLOW0].yystate.yypred.  Leaves YYVSP[YYLOW1].yystate.yypred
  *  containing the pointer to the next state in the chain.  */
-static void yyfillin (yyGLRStackItem *, int, int) __attribute__ ((__unused__));
+static void yyfillin (yyGLRStackItem *, int, int) YY_ATTRIBUTE_UNUSED;
 static void
 yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
 {
@@ -719,7 +715,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
       else
         /* The effect of using yysval or yyloc (in an immediate rule) is
          * undefined.  */
-        yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULL;]b4_locations_if([[
+        yyvsp[i].yystate.yysemantics.yyfirstVal = 
YY_NULLPTR;]b4_locations_if([[
       yyvsp[i].yystate.yyloc = s->yyloc;]])[
       s = yyvsp[i].yystate.yypred = s->yypred;
     }
@@ -729,7 +725,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
  * YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
  * For convenience, always return YYLOW1.  */
 static inline int yyfill (yyGLRStackItem *, int *, int, yybool)
-     __attribute__ ((__unused__));
+     YY_ATTRIBUTE_UNUSED;
 static inline int
 yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
 {
@@ -751,8 +747,7 @@ yyuserAction (yyRuleNum yyn, size_t yyrhslen, 
yyGLRStackItem* yyvsp,
               yyGLRStack* yystackp,
               YYSTYPE* yyvalp]b4_locuser_formals[)
 {
-  yybool yynormal __attribute__ ((__unused__)) =
-    (yystackp->yysplitPoint == YY_NULL);
+  yybool yynormal YY_ATTRIBUTE_UNUSED = (yystackp->yysplitPoint == YY_NULLPTR);
   int yylow;
 ]b4_parse_param_use([yyvalp], [yylocp])dnl
 [  YYUSE (yyrhslen);
@@ -839,7 +834,7 @@ yydestroyGLRState (char const *yymsg, yyGLRState 
*yys]b4_user_formals[)
             YYFPRINTF (stderr, "%s unresolved", yymsg);
           else
             YYFPRINTF (stderr, "%s incomplete", yymsg);
-          YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULL, &yys->yyloc);
+          YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, 
&yys->yyloc);
         }
 #endif
 
@@ -915,14 +910,18 @@ yygetLRActions (yyStateNum yystate, int yytoken,
     }
 }
 
+/** Compute post-reduction state.
+ * \param yystate   the current state
+ * \param yysym     the nonterminal to push on the stack
+ */
 static inline yyStateNum
-yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
+yyLRgotoState (yyStateNum yystate, yySymbol yysym)
 {
-  int yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
+  int yyr = yypgoto[yysym - YYNTOKENS] + yystate;
   if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
     return yytable[yyr];
   else
-    return yydefgoto[yylhs - YYNTOKENS];
+    return yydefgoto[yysym - YYNTOKENS];
 }
 
 static inline yybool
@@ -992,7 +991,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
   yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
   if (! yyset->yystates)
     return yyfalse;
-  yyset->yystates[0] = YY_NULL;
+  yyset->yystates[0] = YY_NULLPTR;
   yyset->yylookaheadNeeds =
     (yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
   if (! yyset->yylookaheadNeeds)
@@ -1022,8 +1021,8 @@ yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
   if (!yystackp->yyitems)
     return yyfalse;
   yystackp->yynextFree = yystackp->yyitems;
-  yystackp->yysplitPoint = YY_NULL;
-  yystackp->yylastDeleted = YY_NULL;
+  yystackp->yysplitPoint = YY_NULLPTR;
+  yystackp->yylastDeleted = YY_NULLPTR;
   return yyinitStateSet (&yystackp->yytops);
 }
 
@@ -1062,10 +1061,10 @@ yyexpandGLRStack (yyGLRStack* yystackp)
         {
           yyGLRState* yys0 = &yyp0->yystate;
           yyGLRState* yys1 = &yyp1->yystate;
-          if (yys0->yypred != YY_NULL)
+          if (yys0->yypred != YY_NULLPTR)
             yys1->yypred =
               YYRELOC (yyp0, yyp1, yys0->yypred, yystate);
-          if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULL)
+          if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULLPTR)
             yys1->yysemantics.yyfirstVal =
               YYRELOC (yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption);
         }
@@ -1073,18 +1072,18 @@ yyexpandGLRStack (yyGLRStack* yystackp)
         {
           yySemanticOption* yyv0 = &yyp0->yyoption;
           yySemanticOption* yyv1 = &yyp1->yyoption;
-          if (yyv0->yystate != YY_NULL)
+          if (yyv0->yystate != YY_NULLPTR)
             yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate);
-          if (yyv0->yynext != YY_NULL)
+          if (yyv0->yynext != YY_NULLPTR)
             yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption);
         }
     }
-  if (yystackp->yysplitPoint != YY_NULL)
+  if (yystackp->yysplitPoint != YY_NULLPTR)
     yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems,
                                       yystackp->yysplitPoint, yystate);
 
   for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1)
-    if (yystackp->yytops.yystates[yyn] != YY_NULL)
+    if (yystackp->yytops.yystates[yyn] != YY_NULLPTR)
       yystackp->yytops.yystates[yyn] =
         YYRELOC (yystackp->yyitems, yynewItems,
                  yystackp->yytops.yystates[yyn], yystate);
@@ -1108,7 +1107,7 @@ yyfreeGLRStack (yyGLRStack* yystackp)
 static inline void
 yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
 {
-  if (yystackp->yysplitPoint != YY_NULL && yystackp->yysplitPoint > yys)
+  if (yystackp->yysplitPoint != YY_NULLPTR && yystackp->yysplitPoint > yys)
     yystackp->yysplitPoint = yys;
 }
 
@@ -1116,9 +1115,9 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
 static inline void
 yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
 {
-  if (yystackp->yytops.yystates[yyk] != YY_NULL)
+  if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
     yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
-  yystackp->yytops.yystates[yyk] = YY_NULL;
+  yystackp->yytops.yystates[yyk] = YY_NULLPTR;
 }
 
 /** Undelete the last stack in *YYSTACKP that was marked as deleted.  Can
@@ -1127,12 +1126,12 @@ yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
 static void
 yyundeleteLastStack (yyGLRStack* yystackp)
 {
-  if (yystackp->yylastDeleted == YY_NULL || yystackp->yytops.yysize != 0)
+  if (yystackp->yylastDeleted == YY_NULLPTR || yystackp->yytops.yysize != 0)
     return;
   yystackp->yytops.yystates[0] = yystackp->yylastDeleted;
   yystackp->yytops.yysize = 1;
   YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
-  yystackp->yylastDeleted = YY_NULL;
+  yystackp->yylastDeleted = YY_NULLPTR;
 }
 
 static inline void
@@ -1142,7 +1141,7 @@ yyremoveDeletes (yyGLRStack* yystackp)
   yyi = yyj = 0;
   while (yyj < yystackp->yytops.yysize)
     {
-      if (yystackp->yytops.yystates[yyi] == YY_NULL)
+      if (yystackp->yytops.yystates[yyi] == YY_NULLPTR)
         {
           if (yyi == yyj)
             {
@@ -1206,7 +1205,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, 
yyStateNum yylrState,
   yynewState->yyposn = yyposn;
   yynewState->yyresolved = yyfalse;
   yynewState->yypred = yystackp->yytops.yystates[yyk];
-  yynewState->yysemantics.yyfirstVal = YY_NULL;
+  yynewState->yysemantics.yyfirstVal = YY_NULLPTR;
   yystackp->yytops.yystates[yyk] = yynewState;
 
   /* Invokes YY_RESERVE_GLRSTACK.  */
@@ -1266,7 +1265,7 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum 
yyrule,
 {
   int yynrhs = yyrhsLength (yyrule);
 
-  if (yystackp->yysplitPoint == YY_NULL)
+  if (yystackp->yysplitPoint == YY_NULLPTR)
     {
       /* Standard special case: single stack.  */
       yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
@@ -1318,13 +1317,13 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, 
yyRuleNum yyrule,
 {
   size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
 
-  if (yyforceEval || yystackp->yysplitPoint == YY_NULL)
+  if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
     {
       YYSTYPE yysval;]b4_locations_if([[
       YYLTYPE yyloc;]])[
 
       YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, 
&yysval]b4_locuser_args([&yyloc])[);
-      if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULL)
+      if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
         {
           YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
                      (unsigned long int) yyk, yyrule - 1));
@@ -1357,7 +1356,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum 
yyrule,
                   "Now in state %d.\n",
                   (unsigned long int) yyk, yyrule - 1, yynewLRState));
       for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
-        if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULL)
+        if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
           {
             yyGLRState *yysplit = yystackp->yysplitPoint;
             yyGLRState *yyp = yystackp->yytops.yystates[yyi];
@@ -1384,7 +1383,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum 
yyrule,
 static size_t
 yysplitStack (yyGLRStack* yystackp, size_t yyk)
 {
-  if (yystackp->yysplitPoint == YY_NULL)
+  if (yystackp->yysplitPoint == YY_NULLPTR)
     {
       YYASSERT (yyk == 0);
       yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
@@ -1394,7 +1393,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
       yyGLRState** yynewStates;
       yybool* yynewLookaheadNeeds;
 
-      yynewStates = YY_NULL;
+      yynewStates = YY_NULLPTR;
 
       if (yystackp->yytops.yycapacity
           > (YYSIZEMAX / (2 * sizeof yynewStates[0])))
@@ -1405,7 +1404,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
         (yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
                                   (yystackp->yytops.yycapacity
                                    * sizeof yynewStates[0]));
-      if (yynewStates == YY_NULL)
+      if (yynewStates == YY_NULLPTR)
         yyMemoryExhausted (yystackp);
       yystackp->yytops.yystates = yynewStates;
 
@@ -1413,7 +1412,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
         (yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
                              (yystackp->yytops.yycapacity
                               * sizeof yynewLookaheadNeeds[0]));
-      if (yynewLookaheadNeeds == YY_NULL)
+      if (yynewLookaheadNeeds == YY_NULLPTR)
         yyMemoryExhausted (yystackp);
       yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
     }
@@ -1477,9 +1476,9 @@ yymergeOptionSets (yySemanticOption* yyy0, 
yySemanticOption* yyy1)
           yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal;
           while (yytrue)
             {
-              if (yyz1 == *yyz0p || yyz1 == YY_NULL)
+              if (yyz1 == *yyz0p || yyz1 == YY_NULLPTR)
                 break;
-              else if (*yyz0p == YY_NULL)
+              else if (*yyz0p == YY_NULLPTR)
                 {
                   *yyz0p = yyz1;
                   break;
@@ -1600,7 +1599,7 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
 
   for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred)
     yystates[yyi] = yys;
-  if (yys == YY_NULL)
+  if (yys == YY_NULLPTR)
     {
       yyleftmost_state.yyposn = 0;
       yystates[0] = &yyleftmost_state;
@@ -1719,7 +1718,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* 
yystackp]b4_user_formals[)
   YYRESULTTAG yyflag;]b4_locations_if([
   YYLTYPE *yylocp = &yys->yyloc;])[
 
-  for (yypp = &yyoptionList->yynext; *yypp != YY_NULL; )
+  for (yypp = &yyoptionList->yynext; *yypp != YY_NULLPTR; )
     {
       yySemanticOption* yyp = *yypp;
 
@@ -1761,7 +1760,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* 
yystackp]b4_user_formals[)
       int yyprec = yydprec[yybest->yyrule];
       yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
       if (yyflag == yyok)
-        for (yyp = yybest->yynext; yyp != YY_NULL; yyp = yyp->yynext)
+        for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext)
           {
             if (yyprec == yydprec[yyp->yyrule])
               {
@@ -1788,14 +1787,14 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* 
yystackp]b4_user_formals[)
       yys->yysemantics.yysval = yysval;
     }
   else
-    yys->yysemantics.yyfirstVal = YY_NULL;
+    yys->yysemantics.yyfirstVal = YY_NULLPTR;
   return yyflag;
 }
 
 static YYRESULTTAG
 yyresolveStack (yyGLRStack* yystackp]b4_user_formals[)
 {
-  if (yystackp->yysplitPoint != YY_NULL)
+  if (yystackp->yysplitPoint != YY_NULLPTR)
     {
       yyGLRState* yys;
       int yyn;
@@ -1815,10 +1814,10 @@ yycompressStack (yyGLRStack* yystackp)
 {
   yyGLRState* yyp, *yyq, *yyr;
 
-  if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULL)
+  if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR)
     return;
 
-  for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULL;
+  for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
        yyp != yystackp->yysplitPoint;
        yyr = yyp, yyp = yyq, yyq = yyp->yypred)
     yyp->yypred = yyr;
@@ -1826,10 +1825,10 @@ yycompressStack (yyGLRStack* yystackp)
   yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
   yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
   yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
-  yystackp->yysplitPoint = YY_NULL;
-  yystackp->yylastDeleted = YY_NULL;
+  yystackp->yysplitPoint = YY_NULLPTR;
+  yystackp->yylastDeleted = YY_NULLPTR;
 
-  while (yyr != YY_NULL)
+  while (yyr != YY_NULLPTR)
     {
       yystackp->yynextFree->yystate = *yyr;
       yyr = yyr->yypred;
@@ -1844,7 +1843,7 @@ static YYRESULTTAG
 yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
                    size_t yyposn]b4_pure_formals[)
 {
-  while (yystackp->yytops.yystates[yyk] != YY_NULL)
+  while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
     {
       yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
       YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
@@ -1966,13 +1965,13 @@ yyreportSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
 #else
   {
   yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-  size_t yysize0 = yytnamerr (YY_NULL, yytokenName (yytoken));
+  size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
   size_t yysize = yysize0;
   yybool yysize_overflow = yyfalse;
-  char* yymsg = YY_NULL;
+  char* yymsg = YY_NULLPTR;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
+  const char *yyformat = YY_NULLPTR;
   /* Arguments of yyformat. */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Number of reported tokens (one for the "unexpected", one per
@@ -2028,7 +2027,7 @@ yyreportSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
                   }
                 yyarg[yycount++] = yytokenName (yyx);
                 {
-                  size_t yysz = yysize + yytnamerr (YY_NULL, yytokenName 
(yyx));
+                  size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName 
(yyx));
                   yysize_overflow |= yysz < yysize;
                   yysize = yysz;
                 }
@@ -2106,7 +2105,7 @@ yyrecoverSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
       {
         yySymbol yytoken;
         if (yychar == YYEOF)
-          yyFail (yystackp][]b4_lpure_args[, YY_NULL);
+          yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
         if (yychar != YYEMPTY)
           {]b4_locations_if([[
             /* We throw away the lookahead, but the error range
@@ -2147,10 +2146,10 @@ yyrecoverSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
 
   /* Reduce to one stack.  */
   for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
-    if (yystackp->yytops.yystates[yyk] != YY_NULL)
+    if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
       break;
   if (yyk >= yystackp->yytops.yysize)
-    yyFail (yystackp][]b4_lpure_args[, YY_NULL);
+    yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
   for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
     yymarkStackDeleted (yystackp, yyk);
   yyremoveDeletes (yystackp);
@@ -2158,7 +2157,7 @@ yyrecoverSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
 
   /* Now pop stack until we find a state that shifts the error token.  */
   yystackp->yyerrState = 3;
-  while (yystackp->yytops.yystates[0] != YY_NULL)
+  while (yystackp->yytops.yystates[0] != YY_NULLPTR)
     {
       yyGLRState *yys = yystackp->yytops.yystates[0];
       yyj = yypact[yys->yylrState];
@@ -2182,14 +2181,14 @@ yyrecoverSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
             }
         }]b4_locations_if([[
       yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
-      if (yys->yypred != YY_NULL)
+      if (yys->yypred != YY_NULLPTR)
         yydestroyGLRState ("Error: popping", yys]b4_user_args[);
       yystackp->yytops.yystates[0] = yys->yypred;
       yystackp->yynextFree -= 1;
       yystackp->yyspaceLeft += 1;
     }
-  if (yystackp->yytops.yystates[0] == YY_NULL)
-    yyFail (yystackp][]b4_lpure_args[, YY_NULL);
+  if (yystackp->yytops.yystates[0] == YY_NULLPTR)
+    yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
 }
 
 #define YYCHK1(YYE)                                                          \
@@ -2432,7 +2431,7 @@ b4_dollar_popdef])[]dnl
                   {
                     yyGLRState *yys = yystates[yyk];
 ]b4_locations_if([[                 yystack.yyerror_range[1].yystate.yyloc = 
yys->yyloc;]]
-)[                  if (yys->yypred != YY_NULL)
+)[                  if (yys->yypred != YY_NULLPTR)
                       yydestroyGLRState ("Cleanup: popping", 
yys]b4_user_args[);
                     yystates[yyk] = yys->yypred;
                     yystack.yynextFree -= 1;
@@ -2464,7 +2463,7 @@ yy_yypstack (yyGLRState* yys)
 static void
 yypstates (yyGLRState* yyst)
 {
-  if (yyst == YY_NULL)
+  if (yyst == YY_NULLPTR)
     YYFPRINTF (stderr, "<null>");
   else
     yy_yypstack (yyst);
@@ -2478,7 +2477,7 @@ yypstack (yyGLRStack* yystackp, size_t yyk)
 }
 
 #define YYINDEX(YYX)                                                         \
-    ((YYX) == YY_NULL ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
+    ((YYX) == YY_NULLPTR ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
 
 
 static void
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 3294f59..876de8c 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -157,6 +157,7 @@ m4_define([b4_shared_declarations],
 ]b4_bison_locations_if([[# include "location.hh"]])])[
 ]b4_variant_if([b4_variant_includes])[
 
+]b4_attribute_define[
 ]b4_YYDEBUG_define[
 
 ]b4_namespace_open[
@@ -183,14 +184,14 @@ b4_location_define])])[
 
 #if ]b4_api_PREFIX[DEBUG
     /// The current debugging stream.
-    std::ostream& debug_stream () const;
+    std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
     /// Set the current debugging stream.
     void set_debug_stream (std::ostream &);
 
     /// Type for debugging levels.
     typedef int debug_level_type;
     /// The current debugging level.
-    debug_level_type debug_level () const;
+    debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
     /// Set the current debugging level.
     void set_debug_level (debug_level_type l);
 #endif
@@ -219,8 +220,8 @@ b4_location_define])])[
 
     /// Compute post-reduction state.
     /// \param yystate   the current state
-    /// \param yylhs     the nonterminal to push on the stack
-    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
+    /// \param yysym     the nonterminal to push on the stack
+    state_type yy_lr_goto_state_ (state_type yystate, int yysym);
 
     /// Whether the given \c yypact_ value indicates a defaulted state.
     /// \param yyvalue   the value to check
@@ -267,7 +268,7 @@ b4_location_define])])[
     /// \brief Reclaim the memory associated to a symbol.
     /// \param yymsg     Why this token is reclaimed.
     ///                  If null, print nothing.
-    /// \param s         The symbol.
+    /// \param yysym     The symbol.
     template <typename Base>
     void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
 
@@ -341,13 +342,13 @@ b4_location_define])])[
     enum
     {
       yyeof_ = 0,
-      yylast_ = ]b4_last[,           //< Last index in yytable_.
-      yynnts_ = ]b4_nterms_number[,  //< Number of nonterminal symbols.
+      yylast_ = ]b4_last[,     ///< Last index in yytable_.
+      yynnts_ = ]b4_nterms_number[,  ///< Number of nonterminal symbols.
       yyempty_ = -2,
-      yyfinal_ = ]b4_final_state_number[, //< Termination state number.
+      yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
       yyterror_ = 1,
       yyerrcode_ = 256,
-      yyntokens_ = ]b4_tokens_number[    //< Number of tokens.
+      yyntokens_ = ]b4_tokens_number[  ///< Number of tokens.
     };
 
 ]b4_parse_param_vars[
@@ -670,13 +671,13 @@ m4_if(b4_prefix, [yy], [],
 #endif // ]b4_api_PREFIX[DEBUG
 
   inline ]b4_parser_class_name[::state_type
-  ]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
+  ]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yysym)
   {
-    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+    int yyr = yypgoto_[yysym - yyntokens_] + yystate;
     if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
       return yytable_[yyr];
     else
-      return yydefgoto_[yylhs - yyntokens_];
+      return yydefgoto_[yysym - yyntokens_];
   }
 
   inline bool
@@ -699,6 +700,7 @@ m4_if(b4_prefix, [yy], [],
 
     // State.
     int yyn;
+    /// Length of the RHS of the rule being reduced.
     int yylen = 0;
 
     // Error handling.
@@ -711,9 +713,6 @@ m4_if(b4_prefix, [yy], [],
     /// The locations where the error started and ended.
     stack_symbol_type yyerror_range[3];]])[
 
-    /// $$ and @@$.
-    stack_symbol_type yylhs;
-
     /// The return value of parse ().
     int yyresult;
 
@@ -734,7 +733,7 @@ b4_dollar_popdef])[]dnl
        location values to have been already stored, initialize these
        stacks with a primary value.  */
     yystack_.clear ();
-    yypush_ (YY_NULL, 0, yyla);
+    yypush_ (YY_NULLPTR, 0, yyla);
 
     // A new symbol was pushed on the stack.
   yynewstate:
@@ -814,52 +813,55 @@ b4_dollar_popdef])[]dnl
   `-----------------------------*/
   yyreduce:
     yylen = yyr2_[yyn];
-    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, 
yyr1_[yyn]);]b4_variant_if([
-    /* Variants are always initialized to an empty instance of the
-       correct type. The default $$=$1 action is NOT applied when using
-       variants.  */
-    b4_symbol_variant(address@hidden@}]], [yylhs.value], [build])],[
-    /* If YYLEN is nonzero, implement the default value of the action:
-       '$$ = $1'.  Otherwise, use the top of the stack.
-
-       Otherwise, the following line sets YYLHS.VALUE to garbage.
-       This behavior is undocumented and Bison
-       users should not rely upon it.  */
-    if (yylen)
-      yylhs.value = address@hidden - address@hidden;
-    else
-      yylhs.value = address@hidden@}.value;])[
+    {
+      stack_symbol_type yylhs;
+      yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, 
yyr1_[yyn]);]b4_variant_if([
+      /* Variants are always initialized to an empty instance of the
+         correct type. The default '$$ = $1' action is NOT applied
+         when using variants.  */
+      b4_symbol_variant(address@hidden@}]], [yylhs.value], [build])], [
+      /* If YYLEN is nonzero, implement the default value of the
+         action: '$$ = $1'.  Otherwise, use the top of the stack.
+
+         Otherwise, the following line sets YYLHS.VALUE to garbage.
+         This behavior is undocumented and Bison users should not rely
+         upon it.  */
+      if (yylen)
+        yylhs.value = address@hidden - address@hidden;
+      else
+        yylhs.value = address@hidden@}.value;])[
 ]b4_locations_if([dnl
 [
-    // Compute the default @@$.
-    {
-      slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
-      YYLLOC_DEFAULT (yylhs.location, slice, yylen);
-    }]])[
-
-    // Perform the reduction.
-    YY_REDUCE_PRINT (yyn);
-    try
+      // Compute the default @@$.
       {
-        switch (yyn)
-          {
+        slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
+        YYLLOC_DEFAULT (yylhs.location, slice, yylen);
+      }]])[
+
+      // Perform the reduction.
+      YY_REDUCE_PRINT (yyn);
+      try
+        {
+          switch (yyn)
+            {
 ]b4_user_actions[
-          default:
-            break;
-          }
-      }
-    catch (const syntax_error& yyexc)
-      {
-        error (yyexc);
-        YYERROR;
-      }
-    YY_SYMBOL_PRINT ("-> $$ =", yylhs);
-    yypop_ (yylen);
-    yylen = 0;
-    YY_STACK_PRINT ();
+            default:
+              break;
+            }
+        }
+      catch (const syntax_error& yyexc)
+        {
+          error (yyexc);
+          YYERROR;
+        }
+      YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+      yypop_ (yylen);
+      yylen = 0;
+      YY_STACK_PRINT ();
 
-    // Shift the result of the reduction.
-    yypush_ (YY_NULL, yylhs);
+      // Shift the result of the reduction.
+      yypush_ (YY_NULLPTR, yylhs);
+    }
     goto yynewstate;
 
   /*--------------------------------------.
@@ -906,10 +908,7 @@ b4_dollar_popdef])[]dnl
        code.  */
     if (false)
       goto yyerrorlab;]b4_locations_if([[
-    yyerror_range[1].location = yystack_[yylen - 
1].location;]])b4_variant_if([[
-    /* $$ was initialized before running the user action.  */
-    YY_SYMBOL_PRINT ("Error: discarding", yylhs);
-    yylhs.~stack_symbol_type();]])[
+    yyerror_range[1].location = yystack_[yylen - 1].location;]])[
     /* Do not reclaim the symbols of the rule whose action triggered
        this YYERROR.  */
     yypop_ (yylen);
@@ -988,11 +987,11 @@ b4_dollar_popdef])[]dnl
         // Do not try to display the values of the reclaimed symbols,
         // as their printer might throw an exception.
         if (!yyempty)
-          yy_destroy_ (YY_NULL, yyla);
+          yy_destroy_ (YY_NULLPTR, yyla);
 
         while (1 < yystack_.size ())
           {
-            yy_destroy_ (YY_NULL, yystack_[0]);
+            yy_destroy_ (YY_NULLPTR, yystack_[0]);
             yypop_ ();
           }
         throw;
@@ -1074,7 +1073,7 @@ b4_error_verbose_if([state_type yystate, 
symbol_number_type yytoken],
           }
       }
 
-    char const* yyformat = YY_NULL;
+    char const* yyformat = YY_NULLPTR;
     switch (yycount)
       {
 #define YYCASE_(N, S)                         \
diff --git a/data/lalr1.java b/data/lalr1.java
index d137ed8..bd32fa7 100644
--- a/data/lalr1.java
+++ b/data/lalr1.java
@@ -453,6 +453,19 @@ b4_define_state])[
     return yyerrstatus_ == 0;
   }
 
+  /** Compute post-reduction state.
+   * @@param yystate   the current state
+   * @@param yysym     the nonterminal to push on the stack
+   */
+  private int yy_lr_goto_state_ (int yystate, int yysym)
+  {
+    int yyr = yypgoto_[yysym - yyntokens_] + yystate;
+    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+      return yytable_[yyr];
+    else
+      return yydefgoto_[yysym - yyntokens_];
+  }
+
   private int yyaction (int yyn, YYStack yystack, int yylen) 
]b4_maybe_throws([b4_throws])[
   {
     ]b4_yystype[ yyval;
@@ -483,14 +496,7 @@ b4_define_state])[
     yylen = 0;
 
     /* Shift the result of the reduction.  */
-    yyn = yyr1_[yyn];
-    int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
-    if (0 <= yystate && yystate <= yylast_
-        && yycheck_[yystate] == yystack.stateAt (0))
-      yystate = yytable_[yystate];
-    else
-      yystate = yydefgoto_[yyn - yyntokens_];
-
+    int yystate = yy_lr_goto_state_ (yystack.stateAt (0), yyr1_[yyn]);
     yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
     return YYNEWSTATE;
   }
diff --git a/data/location.cc b/data/location.cc
index 9a60f25..e80742a 100644
--- a/data/location.cc
+++ b/data/location.cc
@@ -27,7 +27,7 @@ m4_define([b4_position_define],
   {
   public:]m4_ifdef([b4_location_constructors], [[
     /// Construct a position.
-    explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
+    explicit position (]b4_percent_define_get([[filename_type]])[* f = 
YY_NULLPTR,
                        unsigned int l = ]b4_location_initial_line[u,
                        unsigned int c = ]b4_location_initial_column[u)
       : filename (f)
@@ -38,7 +38,7 @@ m4_define([b4_position_define],
 
 ]])[
     /// Initialization.
-    void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULL,
+    void initialize (]b4_percent_define_get([[filename_type]])[* fn = 
YY_NULLPTR,
                      unsigned int l = ]b4_location_initial_line[u,
                      unsigned int c = ]b4_location_initial_column[u)
     {
@@ -178,7 +178,7 @@ m4_define([b4_location_define],
 
 ])[
     /// Initialization.
-    void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
+    void initialize (]b4_percent_define_get([[filename_type]])[* f = 
YY_NULLPTR,
                      unsigned int l = ]b4_location_initial_line[u,
                      unsigned int c = ]b4_location_initial_column[u)
     {
diff --git a/data/variant.hh b/data/variant.hh
index 19538f6..633c29a 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -95,7 +95,7 @@ m4_define([b4_variant_define],
 
     /// Empty construction.
     variant ()]b4_parse_assert_if([
-      : yytname_ (YY_NULL)])[
+      : yytname_ (YY_NULLPTR)])[
     {}
 
     /// Construct and fill.
@@ -198,7 +198,7 @@ m4_define([b4_variant_define],
     destroy ()
     {
       as<T> ().~T ();]b4_parse_assert_if([
-      yytname_ = YY_NULL;])[
+      yytname_ = YY_NULLPTR;])[
     }
 
   private:
@@ -320,7 +320,6 @@ b4_join(b4_symbol_if([$1], [has_type],
     return symbol_type (b4_join([token::b4_symbol([$1], [id])],
                                 b4_symbol_if([$1], [has_type], [v]),
                                 b4_locations_if([l])));
-
   }
 
 ])])])
diff --git a/data/xslt/xml2dot.xsl b/data/xslt/xml2dot.xsl
index 93bec59..7b62d6e 100644
--- a/data/xslt/xml2dot.xsl
+++ b/data/xslt/xml2dot.xsl
@@ -201,6 +201,8 @@
   <xsl:if test="$point = 0">
     <xsl:text> .</xsl:text>
   </xsl:if>
+
+  <!-- RHS -->
   <xsl:for-each select="rhs/symbol|rhs/empty">
     <xsl:apply-templates select="."/>
     <xsl:if test="$point = position()">
@@ -214,7 +216,9 @@
   <xsl:value-of select="."/>
 </xsl:template>
 
-<xsl:template match="empty"/>
+<xsl:template match="empty">
+  <xsl:text> %empty</xsl:text>
+</xsl:template>
 
 <xsl:template match="lookaheads">
   <xsl:text>  [</xsl:text>
diff --git a/data/xslt/xml2text.xsl b/data/xslt/xml2text.xsl
index 2626f56..4d34be1 100644
--- a/data/xslt/xml2text.xsl
+++ b/data/xslt/xml2text.xsl
@@ -350,12 +350,7 @@
     <xsl:if test="position() = $point + 1">
       <xsl:text> .</xsl:text>
     </xsl:if>
-    <xsl:if test="$itemset = 'true' and name(.) != 'empty'">
-      <xsl:apply-templates select="."/>
-    </xsl:if>
-    <xsl:if test="$itemset != 'true'">
-      <xsl:apply-templates select="."/>
-    </xsl:if>
+    <xsl:apply-templates select="."/>
     <xsl:if test="position() = last() and position() = $point">
       <xsl:text> .</xsl:text>
     </xsl:if>
diff --git a/data/xslt/xml2xhtml.xsl b/data/xslt/xml2xhtml.xsl
index d2cfed4..c7c5688 100644
--- a/data/xslt/xml2xhtml.xsl
+++ b/data/xslt/xml2xhtml.xsl
@@ -532,12 +532,7 @@
       <xsl:text> </xsl:text>
       <span class="point">.</span>
     </xsl:if>
-    <xsl:if test="$itemset = 'true' and name(.) != 'empty'">
-      <xsl:apply-templates select="."/>
-    </xsl:if>
-    <xsl:if test="$itemset != 'true'">
-      <xsl:apply-templates select="."/>
-    </xsl:if>
+    <xsl:apply-templates select="."/>
     <xsl:if test="position() = last() and position() = $point">
       <xsl:text> </xsl:text>
       <span class="point">.</span>
@@ -563,7 +558,7 @@
 </xsl:template>
 
 <xsl:template match="empty">
-  <xsl:text> &#949;</xsl:text>
+  <xsl:text> %empty</xsl:text>
 </xsl:template>
 
 <xsl:template match="lookaheads">
diff --git a/data/yacc.c b/data/yacc.c
index 822656b..aed7f06 100644
--- a/data/yacc.c
+++ b/data/yacc.c
@@ -1108,11 +1108,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                 ]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes,
                 YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
   YYSIZE_T yysize = yysize0;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
+  const char *yyformat = YY_NULLPTR;
   /* Arguments of yyformat. */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Number of reported tokens (one for the "unexpected", one per
@@ -1187,7 +1187,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                   }
                 yyarg[yycount++] = yytname[yyx];
                 {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, 
yytname[yyx]);
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, 
yytname[yyx]);
                   if (! (yysize <= yysize1
                          && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
                     return 2;
@@ -1271,7 +1271,7 @@ static char yypstate_allocated = 0;]])b4_pull_if([
 
 b4_function_define([[yyparse]], [[int]], b4_parse_param)[
 {
-  return yypull_parse (YY_NULL]m4_ifset([b4_parse_param],
+  return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param],
                                   [[, ]b4_args(b4_parse_param)])[);
 }
 
@@ -1313,10 +1313,10 @@ b4_function_define([[yyparse]], [[int]], 
b4_parse_param)[
 {
   yypstate *yyps;]b4_pure_if([], [[
   if (yypstate_allocated)
-    return YY_NULL;]])[
+    return YY_NULLPTR;]])[
   yyps = (yypstate *) malloc (sizeof *yyps);
   if (!yyps)
-    return YY_NULL;
+    return YY_NULLPTR;
   yyps->yynew = 1;]b4_pure_if([], [[
   yypstate_allocated = 1;]])[
   return yyps;
diff --git a/doc/bison.texi b/doc/bison.texi
index 78d7d06..cd5e440 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -10065,18 +10065,16 @@ A category can be turned off by prefixing its name 
with @samp{no-}.  For
 instance, @option{-Wno-yacc} will hide the warnings about
 POSIX Yacc incompatibilities.
 
address@hidden address@hidden
address@hidden address@hidden
-Enable warnings falling in @var{category}, and treat them as errors.  If no
address@hidden is given, it defaults to making all enabled warnings into errors.
address@hidden -Werror
+Turn enabled warnings for every @var{category} into errors, unless they are
+explicitly disabled by @address@hidden
+
address@hidden address@hidden
+Enable warnings falling in @var{category}, and treat them as errors.
 
 @var{category} is the same as for @option{--warnings}, with the exception that
 it may not be prefixed with @samp{no-} (see above).
 
-Prefixed with @samp{no}, it deactivates the error treatment for this
address@hidden However, the warning itself won't be disabled, or enabled, by
-this option.
-
 Note that the precedence of the @samp{=} and @samp{,} operators is such that
 the following commands are @emph{not} equivalent, as the first will not treat
 S/R conflicts as errors.
@@ -10086,6 +10084,14 @@ $ bison -Werror=yacc,conflicts-sr input.y
 $ bison -Werror=yacc,error=conflicts-sr input.y
 @end example
 
address@hidden -Wno-error
+Do not turn enabled warnings for every @var{category} into errors, unless
+they are explicitly enabled by @address@hidden
+
address@hidden address@hidden
+Deactivate the error treatment for this @var{category}. However, the warning
+itself won't be disabled, or enabled, by this option.
+
 @item -f address@hidden
 @itemx address@hidden
 Activate miscellaneous @var{feature}. @var{feature} can be one of:
diff --git a/doc/local.mk b/doc/local.mk
index 1f7b3b2..4fe0859 100644
--- a/doc/local.mk
+++ b/doc/local.mk
@@ -118,7 +118,9 @@ $(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x 
$(top_srcdir)/configure
        fi
        $(AM_V_at)rm -f address@hidden
 
+if ENABLE_YACC
 nodist_man_MANS = doc/yacc.1
+endif
 
 ## ----------------------------- ##
 ## Graphviz examples generation. ##
diff --git a/examples/calc++/local.mk b/examples/calc++/local.mk
index d1d43a0..018d007 100644
--- a/examples/calc++/local.mk
+++ b/examples/calc++/local.mk
@@ -19,7 +19,7 @@
 
 # Don't depend on $(BISON) otherwise we would rebuild these files
 # in srcdir, including during distcheck, which is forbidden.
-examples/calc++/calc++-parser.stamp: $(BISON_IN)
+%D%/calc++-parser.stamp: $(BISON_IN)
 SUFFIXES += .yy .stamp
 .yy.stamp:
        $(AM_V_YACC)rm -f $@
@@ -27,14 +27,14 @@ SUFFIXES += .yy .stamp
        $(AM_V_at)$(YACCCOMPILE) -o $*.cc $<
        $(AM_V_at)mv -f address@hidden $@
 
-$(calc_sources_generated): examples/calc++/calc++-parser.stamp
-       @test -f $@ || rm -f examples/calc++/calc++-parser.stamp
-       @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) 
examples/calc++/calc++-parser.stamp
+$(calcxx_sources_generated): %D%/calc++-parser.stamp
+       @test -f $@ || rm -f %D%/calc++-parser.stamp
+       @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/calc++-parser.stamp
 CLEANFILES +=                                   \
-  $(calc_sources_generated)                     \
-  examples/calc++/calc++-parser.output          \
-  examples/calc++/calc++-parser.stamp           \
-  examples/calc++/calc++-scanner.cc
+  $(calcxx_sources_generated)                   \
+  %D%/calc++-parser.output                      \
+  %D%/calc++-parser.stamp                       \
+  %D%/calc++-scanner.cc
 
 
 ## -------------------- ##
@@ -42,35 +42,43 @@ CLEANFILES +=                                   \
 ## -------------------- ##
 
 # Avoid using BUILT_SOURCES which is too global.
-$(examples_calc___calc___OBJECTS): $(calc_sources_generated)
+$(%C%_calc___OBJECTS): $(calcxx_sources_generated)
 
-calc_sources_extracted =                        \
-  examples/calc++/calc++-driver.cc              \
-  examples/calc++/calc++-driver.hh              \
-  examples/calc++/calc++-scanner.ll             \
-  examples/calc++/calc++.cc
-calc_extracted =                                \
-  $(calc_sources_extracted)                     \
-  examples/calc++/calc++-parser.yy
-extracted += $(calc_extracted)
-calc_sources_generated =                        \
-  examples/calc++/calc++-parser.cc              \
-  examples/calc++/calc++-parser.hh              \
-  examples/calc++/location.hh                   \
-  examples/calc++/position.hh                   \
-  examples/calc++/stack.hh
-calc_sources =                                  \
-  $(calc_sources_extracted)                     \
-  $(calc_sources_generated)
+calcxx_sources_extracted =                      \
+  %D%/calc++-driver.cc                          \
+  %D%/calc++-driver.hh                          \
+  %D%/calc++-scanner.ll                         \
+  %D%/calc++.cc
+calcxx_extracted =                              \
+  $(calcxx_sources_extracted)                   \
+  %D%/calc++-parser.yy
+extracted += $(calcxx_extracted)
+calcxx_sources_generated =                      \
+  %D%/calc++-parser.cc                          \
+  %D%/calc++-parser.hh                          \
+  %D%/location.hh                               \
+  %D%/position.hh                               \
+  %D%/stack.hh
+calcxx_sources =                                \
+  $(calcxx_sources_extracted)                   \
+  $(calcxx_sources_generated)
 
-if BISON_CXX_WORKS
-check_PROGRAMS += examples/calc++/calc++
-nodist_examples_calc___calc___SOURCES =         \
-  $(calc_sources)
+if FLEX_CXX_WORKS
+check_PROGRAMS += %D%/calc++
+nodist_%C%_calc___SOURCES =                     \
+  $(calcxx_sources)
 
-examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
-examples_calc___calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS)
-dist_TESTS += examples/calc++/calc++.test
+%C%_calc___CPPFLAGS = -I$(top_builddir)/%D%
+%C%_calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS)
+dist_TESTS += %D%/calc++.test
 else
-EXTRA_DIST += examples/calc++/calc++.test
+EXTRA_DIST += %D%/calc++.test
 endif
+
+
+## ------------ ##
+## Installing.  ##
+## ------------ ##
+
+calcxxdir = $(docdir)/examples/calc++
+calcxx_DATA = $(calcxx_extracted)
diff --git a/examples/extexi b/examples/extexi
index 24a005e..d4ce653 100755
--- a/examples/extexi
+++ b/examples/extexi
@@ -19,7 +19,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# Usage: extexi input-file.texi ... -- [FILES to extract]
+# Usage: extexi [OPTION...] input-file.texi ... -- [FILES to extract]
 
 # Look for @example environments preceded with lines such as:
 #
@@ -35,6 +35,9 @@
 
 use strict;
 
+# Whether we generate synclines.
+my $synclines = 0;
+
 # normalize($block)
 # -----------------
 # Remove Texinfo mark up.
@@ -102,7 +105,7 @@ sub process ($)
             {
               # Bison supports synclines, but not Flex.
               $input .= sprintf ("#line %s \"$in\"\n", $. + 1)
-                if $file =~ /\.[chy]*$/;
+                if $synclines && $file =~ /\.[chy]*$/;
               next;
             }
           elsif (/address@hidden (small)?example$/)
@@ -136,14 +139,18 @@ my @input;
 my $seen_dash = 0;
 for my $arg (@ARGV)
 {
-  if ($arg eq '--')
+  if ($seen_dash)
+    {
+      use File::Basename;
+      $file_wanted{basename($arg)} = $arg;
+    }
+  elsif ($arg eq '--')
     {
       $seen_dash = 1;
     }
-  elsif ($seen_dash)
+  elsif ($arg eq '--synclines')
     {
-      use File::Basename;
-      $file_wanted{basename($arg)} = $arg;
+      $synclines = 1;
     }
   else
     {
diff --git a/examples/local.mk b/examples/local.mk
index c79c800..8274e00 100644
--- a/examples/local.mk
+++ b/examples/local.mk
@@ -13,8 +13,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-dist_noinst_SCRIPTS = examples/extexi examples/test
-TEST_LOG_COMPILER = $(top_srcdir)/examples/test
+dist_noinst_SCRIPTS = %D%/extexi %D%/test
+TEST_LOG_COMPILER = $(top_srcdir)/%D%/test
 
 AM_CXXFLAGS =                                                  \
   $(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
@@ -24,20 +24,23 @@ AM_CXXFLAGS =                                               
        \
 ## ------------ ##
 
 doc = $(top_srcdir)/doc/bison.texi
-extexi = $(top_srcdir)/examples/extexi
-extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(doc) --
+extexi = $(top_srcdir)/%D%/extexi
+if ENABLE_GCC_WARNINGS
+extexiFLAGS = --synclines
+endif
+extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(extexiFLAGS) $(doc) --
 extracted =
-CLEANFILES += $(extracted) examples/extracted.stamp
-examples/extracted.stamp: $(doc) $(extexi)
+CLEANFILES += $(extracted) %D%/extracted.stamp
+%D%/extracted.stamp: $(doc) $(extexi)
        $(AM_V_GEN)rm -f $@ address@hidden
        $(AM_V_at)touch address@hidden
        $(AM_V_at)$(extract) $(extracted)
        $(AM_V_at)mv address@hidden $@
 
-$(extracted): examples/extracted.stamp
-       @test -f $@ || rm -f examples/extracted.stamp
-       @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/extracted.stamp
+$(extracted): %D%/extracted.stamp
+       @test -f $@ || rm -f %D%/extracted.stamp
+       @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/extracted.stamp
 
-include examples/calc++/local.mk
-include examples/mfcalc/local.mk
-include examples/rpcalc/local.mk
+include %D%/calc++/local.mk
+include %D%/mfcalc/local.mk
+include %D%/rpcalc/local.mk
diff --git a/examples/mfcalc/local.mk b/examples/mfcalc/local.mk
index 10d6696..361a4a5 100644
--- a/examples/mfcalc/local.mk
+++ b/examples/mfcalc/local.mk
@@ -18,19 +18,22 @@
 ## -------------------- ##
 
 BUILT_SOURCES += $(mfcalc_sources)
-CLEANFILES +=  examples/mfcalc/mfcalc.[ch] examples/mfcalc/mfcalc.output
+CLEANFILES +=  %D%/mfcalc.[ch] %D%/mfcalc.output
 
-mfcalc_extracted =                             \
-  examples/mfcalc/calc.h                       \
-  examples/mfcalc/mfcalc.y
-mfcalc_sources =                               \
-  $(mfcalc_extracted)
+mfcalc_extracted = %D%/calc.h %D%/mfcalc.y
+mfcalc_sources = $(mfcalc_extracted)
 extracted += $(mfcalc_extracted)
 
-check_PROGRAMS += examples/mfcalc/mfcalc
-examples_mfcalc_mfcalc_LDADD = -lm
-nodist_examples_mfcalc_mfcalc_SOURCES =                \
-  $(mfcalc_sources)
+check_PROGRAMS += %D%/mfcalc
+%C%_mfcalc_LDADD = -lm
+nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
 
-examples_mfcalc_mfcalc_CPPFLAGS = -I$(top_builddir)/examples/mfcalc
-dist_TESTS += examples/mfcalc/mfcalc.test
+%C%_mfcalc_CPPFLAGS = -I$(top_builddir)/%D%
+dist_TESTS += %D%/mfcalc.test
+
+## ------------ ##
+## Installing.  ##
+## ------------ ##
+
+mfcalcdir = $(docdir)/examples/mfcalc
+mfcalc_DATA = $(mfcalc_extracted)
diff --git a/examples/rpcalc/.gitignore b/examples/rpcalc/.gitignore
index fbd9052..7e8a2f0 100644
--- a/examples/rpcalc/.gitignore
+++ b/examples/rpcalc/.gitignore
@@ -1,4 +1,5 @@
 /calc.h
+/rpcalc
 /rpcalc.c
 /rpcalc.h
 /rpcalc.output
diff --git a/examples/rpcalc/local.mk b/examples/rpcalc/local.mk
index 3ff2f98..125bb3b 100644
--- a/examples/rpcalc/local.mk
+++ b/examples/rpcalc/local.mk
@@ -18,18 +18,22 @@
 ## -------------------- ##
 
 BUILT_SOURCES += $(rpcalc_sources)
-CLEANFILES +=  examples/rpcalc/rpcalc.[ch] examples/rpcalc/rpcalc.output
+CLEANFILES +=  %D%/rpcalc.[ch] %D%/rpcalc.output
 
-rpcalc_extracted =                             \
-  examples/rpcalc/rpcalc.y
-rpcalc_sources =                               \
-  $(rpcalc_extracted)
+rpcalc_extracted = %D%/rpcalc.y
+rpcalc_sources = $(rpcalc_extracted)
 extracted += $(rpcalc_extracted)
 
-check_PROGRAMS += examples/rpcalc/rpcalc
-examples_rpcalc_rpcalc_LDADD = -lm
-nodist_examples_rpcalc_rpcalc_SOURCES =                \
-  $(rpcalc_sources)
+check_PROGRAMS += %D%/rpcalc
+%C%_rpcalc_LDADD = -lm
+nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
 
-examples_rpcalc_rpcalc_CPPFLAGS = -I$(top_builddir)/examples/rpcalc
-dist_TESTS += examples/rpcalc/rpcalc.test
+%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
+dist_TESTS += %D%/rpcalc.test
+
+## ------------ ##
+## Installing.  ##
+## ------------ ##
+
+rpcalcdir = $(docdir)/examples/rpcalc
+rpcalc_DATA = $(rpcalc_extracted)
diff --git a/gnulib b/gnulib
index 03e96cc..74540d4 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 03e96cc338b5237e15fce73e9423526969ee768a
+Subproject commit 74540d44dc16bfd3546e39ae2d7262f32a4147ab
diff --git a/lib/.gitignore b/lib/.gitignore
index e021ab0..0197e83 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -272,3 +272,5 @@
 /sig-handler.c
 /unistd.c
 /wctype-h.c
+/lstat.c
+/unlink.c
diff --git a/lib/local.mk b/lib/local.mk
index d5d2d0b..1069b50 100644
--- a/lib/local.mk
+++ b/lib/local.mk
@@ -51,6 +51,8 @@ lib_libbison_a_SOURCES +=                       \
   lib/get-errno.c
 
 # The Yacc compatibility library.
-lib_LIBRARIES = $(YACC_LIBRARY)
+if ENABLE_YACC
+lib_LIBRARIES = lib/liby.a
 EXTRA_LIBRARIES = lib/liby.a
 lib_liby_a_SOURCES = lib/main.c lib/yyerror.c
+endif
diff --git a/m4/.gitignore b/m4/.gitignore
index 5b7d363..465d4d6 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -180,3 +180,6 @@
 /obstack-printf.m4
 /extern-inline.m4
 /non-recursive-gnulib-prefix-hack.m4
+/absolute-header.m4
+/lstat.m4
+/unlink.m4
diff --git a/src/AnnotationList.c b/src/AnnotationList.c
index 9f0adb9..071a3f3 100644
--- a/src/AnnotationList.c
+++ b/src/AnnotationList.c
@@ -541,9 +541,13 @@ AnnotationList__compute_from_inadequacies (
               {
                 InadequacyList__prependTo (conflict_node,
                                            &inadequacy_lists[s->number]);
-                aver (AnnotationList__insertInto (
-                        annotation_node, &annotation_lists[s->number],
-                        s->nitems));
+                {
+                  bool b =
+                    AnnotationList__insertInto (annotation_node,
+                                                &annotation_lists[s->number],
+                                                s->nitems);
+                  aver (b);
+                }
                 /* This aver makes sure the
                    AnnotationList__computeDominantContribution check above
                    does discard annotations in the simplest case of a S/R
diff --git a/src/complain.c b/src/complain.c
index fdc4b54..e767490 100644
--- a/src/complain.c
+++ b/src/complain.c
@@ -35,14 +35,25 @@ err_status complaint_status = status_none;
 
 bool warnings_are_errors = false;
 
+/** Whether -Werror/-Wno-error was applied to a warning.  */
+typedef enum
+  {
+    errority_unset = 0,     /** No explict status.  */
+    errority_disabled = 1,  /** Explictly disabled with -Wno-error=foo.  */
+    errority_enabled = 2    /** Explictly enabled with -Werror=foo. */
+  } errority;
+
+/** For each warning type, its errority.  */
+static errority errority_flag[warnings_size];
+
 /** Diagnostics severity.  */
 typedef enum
   {
-    severity_disabled = 0,
-    severity_unset = 1,
-    severity_warning = 2,
-    severity_error = 3,
-    severity_fatal = 4
+    severity_disabled = 0, /**< Explicitly disabled via -Wno-foo.  */
+    severity_unset = 1,    /**< Unspecified status.  */
+    severity_warning = 2,  /**< A warning.  */
+    severity_error = 3,    /**< An error (continue, but die soon).  */
+    severity_fatal = 4     /**< Fatal error (die now).  */
   } severity;
 
 
@@ -103,32 +114,26 @@ warning_argmatch (char const *arg, size_t no, size_t err)
       no = !no;
     }
 
-  if (no)
-    {
-      size_t b;
-      for (b = 0; b < warnings_size; ++b)
-        if (value & 1 << b)
+  size_t b;
+  for (b = 0; b < warnings_size; ++b)
+    if (value & 1 << b)
+      {
+        if (err && no)
+          /* -Wno-error=foo.  */
+          errority_flag[b] = errority_disabled;
+        else if (err && !no)
           {
-            if (err)
-              {
-                /* -Wno-error=foo: if foo enabled as an error,
-                   make it a warning.  */
-                if (warnings_flag[b] == severity_error)
-                  warnings_flag[b] = severity_warning;
-              }
-            else
-              /* -Wno-foo.  */
-              warnings_flag[b] = severity_disabled;
+            /* -Werror=foo: enables -Wfoo. */
+            errority_flag[b] = errority_enabled;
+            warnings_flag[b] = severity_warning;
           }
-    }
-  else
-    {
-      size_t b;
-      for (b = 0; b < warnings_size; ++b)
-        if (value & 1 << b)
-          /* -Wfoo and -Werror=foo. */
-          warnings_flag[b] = err ? severity_error : severity_warning;
-    }
+        else if (no)
+          /* -Wno-foo.  */
+          warnings_flag[b] = severity_disabled;
+        else
+          /* -Wfoo. */
+          warnings_flag[b] = severity_warning;
+      }
 }
 
 /** Decode a comma-separated list of arguments from -W.
@@ -145,13 +150,13 @@ warnings_argmatch (char *args)
       if (STREQ (args, "error"))
         warnings_are_errors = true;
       else if (STREQ (args, "no-error"))
-        {
-          warnings_are_errors = false;
-          warning_argmatch ("no-error=everything", 3, 6);
-        }
+        warnings_are_errors = false;
       else
         {
+          /* The length of the possible 'no-' prefix: 3, or 0.  */
           size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
+          /* The length of the possible 'error=' (possibly after
+             'no-') prefix: 6, or 0. */
           size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
 
           warning_argmatch (args, no, err);
@@ -173,27 +178,46 @@ complain_init (void)
 
   size_t b;
   for (b = 0; b < warnings_size; ++b)
-    warnings_flag[b] = (1 << b & warnings_default
-                        ? severity_warning
-                        : severity_unset);
+    {
+      warnings_flag[b] = (1 << b & warnings_default
+                          ? severity_warning
+                          : severity_unset);
+      errority_flag[b] = errority_unset;
+    }
 }
 
+
+/* A diagnostic with FLAGS is about to be issued.  With what severity?
+   (severity_fatal, severity_error, severity_disabled, or
+   severity_warning.) */
+
 static severity
 warning_severity (warnings flags)
 {
   if (flags & fatal)
+    /* Diagnostics about fatal errors.  */
     return severity_fatal;
   else if (flags & complaint)
+    /* Diagnostics about errors.  */
     return severity_error;
   else
     {
+      /* Diagnostics about warnings.  */
       severity res = severity_disabled;
       size_t b;
       for (b = 0; b < warnings_size; ++b)
         if (flags & 1 << b)
-          res = res < warnings_flag[b] ? warnings_flag[b] : res;
-      if (res == severity_warning && warnings_are_errors)
-        res = severity_error;
+          {
+            res = res < warnings_flag[b] ? warnings_flag[b] : res;
+            /* If the diagnostic is enabled, and -Werror is enabled,
+               and -Wno-error=foo was not explicitly requested, this
+               is an error. */
+            if (res == severity_warning
+                && (errority_flag[b] == errority_enabled
+                    || (warnings_are_errors
+                        && errority_flag[b] != errority_disabled)))
+              res = severity_error;
+          }
       return res;
     }
 }
diff --git a/src/complain.h b/src/complain.h
index 0d81503..62dd8fa 100644
--- a/src/complain.h
+++ b/src/complain.h
@@ -128,14 +128,14 @@ void deprecated_directive (location const *loc,
 void duplicate_directive (char const *directive,
                           location first, location second);
 
-/** Warnings treated as errors shouldn't stop the execution as regular errors
-    should (because due to their nature, it is safe to go on). Thus, there are
-    three possible execution statuses.  */
+/** Warnings treated as errors shouldn't stop the execution as regular
+    errors should (because due to their nature, it is safe to go
+    on). Thus, there are three possible execution statuses.  */
 typedef enum
   {
-    status_none,
-    status_warning_as_error,
-    status_complaint
+    status_none,             /**< No diagnostic issued so far.  */
+    status_warning_as_error, /**< A warning was issued (but no error).  */
+    status_complaint         /**< An error was issued.  */
   } err_status;
 
 /** Whether an error was reported.  */
diff --git a/src/files.c b/src/files.c
index 76aa7fe..c50f774 100644
--- a/src/files.c
+++ b/src/files.c
@@ -51,8 +51,17 @@ char *spec_defines_file = NULL;  /* for --defines. */
 char *parser_file_name;
 
 /* All computed output file names.  */
-static char **file_names = NULL;
-static int file_names_count = 0;
+typedef struct generated_file
+{
+  /** File name.  */
+  char *name;
+  /** Whether is a generated source file (e.g., *.c, *.java...), as
+      opposed to the report file (e.g., *.output).  When late errors
+      are detected, generated source files are removed.  */
+  bool is_source;
+} generated_file;
+static generated_file *generated_files = NULL;
+static int generated_files_size = 0;
 
 uniqstr grammar_file = NULL;
 uniqstr current_file = NULL;
@@ -332,21 +341,21 @@ compute_output_file_names (void)
     {
       if (! spec_graph_file)
         spec_graph_file = concat2 (all_but_tab_ext, ".dot");
-      output_file_name_check (&spec_graph_file);
+      output_file_name_check (&spec_graph_file, false);
     }
 
   if (xml_flag)
     {
       if (! spec_xml_file)
         spec_xml_file = concat2 (all_but_tab_ext, ".xml");
-      output_file_name_check (&spec_xml_file);
+      output_file_name_check (&spec_xml_file, false);
     }
 
   if (report_flag)
     {
       if (!spec_verbose_file)
         spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
-      output_file_name_check (&spec_verbose_file);
+      output_file_name_check (&spec_verbose_file, false);
     }
 
   free (all_but_tab_ext);
@@ -355,7 +364,7 @@ compute_output_file_names (void)
 }
 
 void
-output_file_name_check (char **file_name)
+output_file_name_check (char **file_name, bool source)
 {
   bool conflict = false;
   if (STREQ (*file_name, grammar_file))
@@ -367,11 +376,11 @@ output_file_name_check (char **file_name)
   else
     {
       int i;
-      for (i = 0; i < file_names_count; i++)
-        if (STREQ (file_names[i], *file_name))
+      for (i = 0; i < generated_files_size; i++)
+        if (STREQ (generated_files[i].name, *file_name))
           {
             complain (NULL, Wother, _("conflicting outputs to file %s"),
-                      quote (*file_name));
+                      quote (generated_files[i].name));
             conflict = true;
           }
     }
@@ -382,13 +391,24 @@ output_file_name_check (char **file_name)
     }
   else
     {
-      file_names = xnrealloc (file_names, ++file_names_count,
-                              sizeof *file_names);
-      file_names[file_names_count-1] = xstrdup (*file_name);
+      generated_files = xnrealloc (generated_files, ++generated_files_size,
+                                   sizeof *generated_files);
+      generated_files[generated_files_size-1].name = xstrdup (*file_name);
+      generated_files[generated_files_size-1].is_source = source;
     }
 }
 
 void
+unlink_generated_sources (void)
+{
+  int i;
+  for (i = 0; i < generated_files_size; i++)
+    if (generated_files[i].is_source)
+      /* Ignore errors.  The file might not even exist.  */
+      unlink (generated_files[i].name);
+}
+
+void
 output_file_names_free (void)
 {
   free (all_but_ext);
@@ -400,8 +420,8 @@ output_file_names_free (void)
   free (dir_prefix);
   {
     int i;
-    for (i = 0; i < file_names_count; i++)
-      free (file_names[i]);
+    for (i = 0; i < generated_files_size; i++)
+      free (generated_files[i].name);
   }
-  free (file_names);
+  free (generated_files);
 }
diff --git a/src/files.h b/src/files.h
index ebe5037..9b85719 100644
--- a/src/files.h
+++ b/src/files.h
@@ -63,7 +63,15 @@ extern char *all_but_ext;
 
 void compute_output_file_names (void);
 void output_file_names_free (void);
-void output_file_name_check (char **file_name);
+
+/** Record that we generate file \a file_name.
+ *  \param source whether this is a source file (*c, *.java...)
+ *                as opposed to a report (*.output, *.dot...).
+ */
+void output_file_name_check (char **file_name, bool source);
+
+/** Remove all the generated source files. */
+void unlink_generated_sources (void);
 
 FILE *xfopen (const char *name, char const *mode);
 void xfclose (FILE *ptr);
diff --git a/src/lalr.c b/src/lalr.c
index d99f960..dc04eab 100644
--- a/src/lalr.c
+++ b/src/lalr.c
@@ -67,17 +67,13 @@ static goto_number **includes;
 static goto_list **lookback;
 
 
-
-
 void
 set_goto_map (void)
 {
   state_number s;
-  goto_number *temp_map;
+  goto_number *temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
 
   goto_map = xcalloc (nvars + 1, sizeof *goto_map);
-  temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
-
   ngotos = 0;
   for (s = 0; s < nstates; ++s)
     {
@@ -132,16 +128,13 @@ set_goto_map (void)
 goto_number
 map_goto (state_number s0, symbol_number sym)
 {
-  goto_number high;
-  goto_number low;
-  goto_number middle;
-  state_number s;
-
-  low = goto_map[sym - ntokens];
-  high = goto_map[sym - ntokens + 1] - 1;
+  goto_number low = goto_map[sym - ntokens];
+  goto_number high = goto_map[sym - ntokens + 1] - 1;
 
   for (;;)
     {
+      goto_number middle;
+      state_number s;
       aver (low <= high);
       middle = (low + high) / 2;
       s = from_state[middle];
@@ -412,7 +405,6 @@ static void
 lookahead_tokens_print (FILE *out)
 {
   state_number i;
-  int j, k;
   fprintf (out, "Lookahead tokens: BEGIN\n");
   for (i = 0; i < nstates; ++i)
     {
@@ -421,21 +413,25 @@ lookahead_tokens_print (FILE *out)
       int n_lookahead_tokens = 0;
 
       if (reds->lookahead_tokens)
-        for (k = 0; k < reds->num; ++k)
-          if (reds->lookahead_tokens[k])
-            ++n_lookahead_tokens;
+        {
+          int j;
+          for (j = 0; j < reds->num; ++j)
+            if (reds->lookahead_tokens[j])
+              ++n_lookahead_tokens;
+        }
 
       fprintf (out, "State %d: %d lookahead tokens\n",
                i, n_lookahead_tokens);
 
       if (reds->lookahead_tokens)
-        for (j = 0; j < reds->num; ++j)
-          BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
-          {
-            fprintf (out, "   on %d (%s) -> rule %d\n",
-                     k, symbols[k]->tag,
-                     reds->rules[j]->number);
-          };
+        {
+          int j, k;
+          for (j = 0; j < reds->num; ++j)
+            BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
+              fprintf (out, "   on %d (%s) -> rule %d\n",
+                       k, symbols[k]->tag,
+                       reds->rules[j]->number);
+        }
     }
   fprintf (out, "Lookahead tokens: END\n");
 }
diff --git a/src/local.mk b/src/local.mk
index 9e0848c..bbed7b7 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -111,7 +111,9 @@ BUILT_SOURCES +=                                \
 ## yacc.  ##
 ## ------ ##
 
-bin_SCRIPTS = $(YACC_SCRIPT)
+if ENABLE_YACC
+bin_SCRIPTS = src/yacc
+endif
 EXTRA_SCRIPTS = src/yacc
 MOSTLYCLEANFILES += src/yacc
 
diff --git a/src/location.c b/src/location.c
index 662b2a1..c873dcc 100644
--- a/src/location.c
+++ b/src/location.c
@@ -188,7 +188,7 @@ location_caret (location loc, FILE *out)
   /* Read the actual line.  Don't update the offset, so that we keep a pointer
      to the start of the line.  */
   {
-    char c = getc (caret_info.source);
+    int c = getc (caret_info.source);
     if (c != EOF)
       {
         /* Quote the file, indent by a single column.  */
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
index cc5d01d..71a79b4 100644
--- a/src/muscle-tab.c
+++ b/src/muscle-tab.c
@@ -299,8 +299,9 @@ muscle_location_grow (char const *key, location loc)
 
 #define COMMON_DECODE(Value)                                    \
   case '$':                                                     \
-    aver (*++(Value) == ']');                                   \
-    aver (*++(Value) == '[');                                   \
+    ++(Value); aver (*(Value) == '[');                          \
+    ++(Value); aver (*(Value) == ']');                          \
+    ++(Value); aver (*(Value) == '[');                          \
     obstack_sgrow (&muscle_obstack, "$");                       \
     break;                                                      \
   case '@':                                                     \
@@ -349,7 +350,7 @@ location_decode (char const *value)
   location loc;
   aver (value);
   aver (*value == '[');
-  aver (*++value == '[');
+  ++value; aver (*value == '[');
   while (*++value)
     switch (*value)
       {
@@ -360,16 +361,16 @@ location_decode (char const *value)
         case ']':
           {
             char *boundary_str;
-            aver (*++value == ']');
+            ++value; aver (*value == ']');
             boundary_str = obstack_finish0 (&muscle_obstack);
             switch (*++value)
               {
                 case ',':
                   boundary_set_from_string (&loc.start, boundary_str);
                   obstack_free (&muscle_obstack, boundary_str);
-                  aver (*++value == ' ');
-                  aver (*++value == '[');
-                  aver (*++value == '[');
+                  ++value; aver (*value == ' ');
+                  ++value; aver (*value == '[');
+                  ++value; aver (*value == '[');
                   break;
                 case '\0':
                   boundary_set_from_string (&loc.end, boundary_str);
diff --git a/src/output.c b/src/output.c
index 78b1ee1..a88e6cf 100644
--- a/src/output.c
+++ b/src/output.c
@@ -706,6 +706,11 @@ output (void)
   /* Process the selected skeleton file.  */
   output_skeleton ();
 
+  /* If late errors were generated, destroy the generated source
+     files. */
+  if (complaint_status)
+    unlink_generated_sources ();
+
   obstack_free (&format_obstack, NULL);
 }
 
diff --git a/src/parse-gram.c b/src/parse-gram.c
index b48ed6f..9e279f5 100644
--- a/src/parse-gram.c
+++ b/src/parse-gram.c
@@ -80,11 +80,11 @@
 
 #line 82 "src/parse-gram.c" /* yacc.c:339  */
 
-# ifndef YY_NULL
+# ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULL nullptr
+#   define YY_NULLPTR nullptr
 #  else
-#   define YY_NULL 0
+#   define YY_NULLPTR 0
 #  endif
 # endif
 
@@ -639,7 +639,7 @@ static const char *const yytname[] =
   "symbols.1", "generic_symlist", "generic_symlist_item", "tag",
   "symbol_def", "symbol_defs.1", "grammar", "rules_or_grammar_declaration",
   "rules", "address@hidden", "rhses.1", "rhs", "named_ref.opt", "variable", 
"value",
-  "id", "id_colon", "symbol", "string_as_id", "epilogue.opt", YY_NULL
+  "id", "id_colon", "symbol", "string_as_id", "epilogue.opt", YY_NULLPTR
 };
 #endif
 
@@ -1569,11 +1569,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                 yytype_int16 *yyesa, yytype_int16 **yyes,
                 YYSIZE_T *yyes_capacity, yytype_int16 *yyssp, int yytoken)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
   YYSIZE_T yysize = yysize0;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
+  const char *yyformat = YY_NULLPTR;
   /* Arguments of yyformat. */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Number of reported tokens (one for the "unexpected", one per
@@ -1628,7 +1628,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                   }
                 yyarg[yycount++] = yytname[yyx];
                 {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, 
yytname[yyx]);
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, 
yytname[yyx]);
                   if (! (yysize <= yysize1
                          && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
                     return 2;
diff --git a/src/print-xml.c b/src/print-xml.c
index 3ddaeba..e42b42a 100644
--- a/src/print-xml.c
+++ b/src/print-xml.c
@@ -65,40 +65,39 @@ print_core (FILE *out, int level, state *s)
   sitems = itemset;
   snritems = nitemset;
 
-  if (!snritems) {
-    xml_puts (out, level, "<itemset/>");
-    return;
-  }
+  if (!snritems)
+    {
+      xml_puts (out, level, "<itemset/>");
+      return;
+    }
 
   xml_puts (out, level, "<itemset>");
 
   for (i = 0; i < snritems; i++)
     {
       bool printed = false;
-      item_number *sp;
-      item_number *sp1;
-      rule_number r;
-
-      sp1 = sp = ritem + sitems[i];
+      item_number *sp1 = ritem + sitems[i];
+      item_number *sp = sp1;
+      rule *r;
 
-      while (*sp >= 0)
+      while (0 <= *sp)
         sp++;
 
-      r = item_number_as_rule_number (*sp);
-      sp = rules[r].rhs;
+      r = &rules[item_number_as_rule_number (*sp)];
+      sp = r->rhs;
 
       /* Display the lookahead tokens?  */
       if (item_number_is_rule_number (*sp1))
         {
           reductions *reds = s->reductions;
-          int red = state_reduction_find (s, &rules[r]);
+          int red = state_reduction_find (s, r);
           /* Print item with lookaheads if there are. */
           if (reds->lookahead_tokens && red != -1)
             {
               xml_printf (out, level + 1,
                           "<item rule-number=\"%d\" point=\"%d\">",
-                          rules[r].number, sp1 - sp);
-              state_rule_lookahead_tokens_print_xml (s, &rules[r],
+                          r->number, sp1 - sp);
+              state_rule_lookahead_tokens_print_xml (s, r,
                                                      out, level + 2);
               xml_puts (out, level + 1, "</item>");
               printed = true;
@@ -106,12 +105,10 @@ print_core (FILE *out, int level, state *s)
         }
 
       if (!printed)
-        {
-          xml_printf (out, level + 1,
-                      "<item rule-number=\"%d\" point=\"%d\"/>",
-                      rules[r].number,
-                      sp1 - sp);
-        }
+        xml_printf (out, level + 1,
+                    "<item rule-number=\"%d\" point=\"%d\"/>",
+                    r->number,
+                    sp1 - sp);
     }
   xml_puts (out, level, "</itemset>");
 }
@@ -136,10 +133,11 @@ print_transitions (state *s, FILE *out, int level)
       }
 
   /* Nothing to report. */
-  if (!n) {
-    xml_puts (out, level, "<transitions/>");
-    return;
-  }
+  if (!n)
+    {
+      xml_puts (out, level, "<transitions/>");
+      return;
+    }
 
   /* Report lookahead tokens and shifts.  */
   xml_puts (out, level, "<transitions>");
@@ -190,10 +188,11 @@ print_errs (FILE *out, int level, state *s)
       count = true;
 
   /* Nothing to report. */
-  if (!count) {
-    xml_puts (out, level, "<errors/>");
-    return;
-  }
+  if (!count)
+    {
+      xml_puts (out, level, "<errors/>");
+      return;
+    }
 
   /* Report lookahead tokens and errors.  */
   xml_puts (out, level, "<errors>");
@@ -287,10 +286,11 @@ print_reductions (FILE *out, int level, state *s)
       }
 
   /* Nothing to report. */
-  if (!report) {
-    xml_puts (out, level, "<reductions/>");
-    return;
-  }
+  if (!report)
+    {
+      xml_puts (out, level, "<reductions/>");
+      return;
+    }
 
   xml_puts (out, level, "<reductions>");
 
diff --git a/src/print.c b/src/print.c
index f8ed3da..03189c8 100644
--- a/src/print.c
+++ b/src/print.c
@@ -106,8 +106,11 @@ print_core (FILE *out, state *s)
       for (sp = rules[r].rhs; sp < sp1; sp++)
         fprintf (out, " %s", symbols[*sp]->tag);
       fputs (" .", out);
-      for (/* Nothing */; *sp >= 0; ++sp)
-        fprintf (out, " %s", symbols[*sp]->tag);
+      if (0 <= *rules[r].rhs)
+        for (/* Nothing */; 0 <= *sp; ++sp)
+          fprintf (out, " %s", symbols[*sp]->tag);
+      else
+        fprintf (out, " %%empty");
 
       /* Display the lookahead tokens?  */
       if (report_flag & report_lookahead_tokens
diff --git a/src/print_graph.c b/src/print_graph.c
index 09e26b3..b0c38a6 100644
--- a/src/print_graph.c
+++ b/src/print_graph.c
@@ -85,8 +85,11 @@ print_core (struct obstack *oout, state *s)
 
       obstack_1grow (oout, '.');
 
-      for (/* Nothing */; *sp >= 0; ++sp)
-        obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
+      if (0 <= *r->rhs)
+        for (/* Nothing */; *sp >= 0; ++sp)
+          obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
+      else
+        obstack_printf (oout, " %%empty");
 
       /* Experimental feature: display the lookahead tokens. */
       if (report_flag & report_lookahead_tokens
diff --git a/src/scan-code.l b/src/scan-code.l
index cced97b..0c11b40 100644
--- a/src/scan-code.l
+++ b/src/scan-code.l
@@ -342,8 +342,19 @@ show_sub_message (warnings warning,
     {
       static struct obstack msg_buf;
       const char *tail = explicit_bracketing ? "" : cp + strlen (var->id);
-      const char *id = var->hidden_by ? var->hidden_by->id : var->id;
-      location id_loc = var->hidden_by ? var->hidden_by->loc : var->loc;
+      const char *id;
+      location id_loc;
+
+      if (var->hidden_by)
+        {
+          id = var->hidden_by->id;
+          id_loc = var->hidden_by->loc;
+        }
+      else
+        {
+          id = var->id;
+          id_loc = var->loc;
+        }
 
       /* Create the explanation message. */
       obstack_init (&msg_buf);
@@ -573,9 +584,6 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
         return INVALID_REF;
       }
     }
-
-  /* Not reachable. */
-  return INVALID_REF;
 }
 
 /* Keeps track of the maximum number of semantic values to the left of
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 665e80d..555e695 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -266,7 +266,7 @@ eqopt    ([[:space:]]*=)?
   "%pure"[-_]"parser"               DEPRECATED("%pure-parser");
   "%token"[-_]"table"               DEPRECATED("%token-table");
 
-  "%"{id}|"%"{notletter}([[:graph:]])+ {
+  "%"{id} {
     complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
   }
 
diff --git a/src/scan-skel.l b/src/scan-skel.l
index f13ee81..129b889 100644
--- a/src/scan-skel.l
+++ b/src/scan-skel.l
@@ -244,8 +244,9 @@ at_output (int argc, char *argv[], char **out_namep, int 
*out_linenop)
       xfclose (yyout);
     }
   *out_namep = xstrdup (argv[1]);
-  output_file_name_check (out_namep);
-  yyout = xfopen (*out_namep, "w");
+  output_file_name_check (out_namep, true);
+  /* If there were errors, do not generate the output.  */
+  yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w");
   *out_linenop = 1;
 }
 
diff --git a/src/symtab.c b/src/symtab.c
index f6761c4..5a8b616 100644
--- a/src/symtab.c
+++ b/src/symtab.c
@@ -138,6 +138,42 @@ symbol_free (void *ptr)
   if (!sym->is_alias)
     sym_content_free (sym->content);
   free (sym);
+
+}
+
+/* If needed, swap first and second so that first has the earliest
+   location (according to location_cmp).
+
+   Many symbol features (e.g., user token numbers) are not assigned
+   during the parsing, but in a second step, via a traversal of the
+   symbol table sorted on tag.
+
+   However, error messages make more sense if we keep the first
+   declaration first.
+*/
+
+static
+void symbols_sort (symbol **first, symbol **second)
+{
+  if (0 < location_cmp ((*first)->location, (*second)->location))
+    {
+      symbol* tmp = *first;
+      *first = *second;
+      *second = tmp;
+    }
+}
+
+/* Likewise, for locations.  */
+
+static
+void locations_sort (location *first, location *second)
+{
+  if (0 < location_cmp (*first, *second))
+    {
+      location tmp = *first;
+      *first = *second;
+      *second = tmp;
+    }
 }
 
 char const *
@@ -250,6 +286,7 @@ symbol_redeclaration (symbol *s, const char *what, location 
first,
                       location second)
 {
   unsigned i = 0;
+  locations_sort (&first, &second);
   complain_indent (&second, complaint, &i,
                    _("%s redeclaration for %s"), what, s->tag);
   i += SUB_INDENT;
@@ -262,6 +299,7 @@ semantic_type_redeclaration (semantic_type *s, const char 
*what, location first,
                              location second)
 {
   unsigned i = 0;
+  locations_sort (&first, &second);
   complain_indent (&second, complaint, &i,
                    _("%s redeclaration for <%s>"), what, s->tag);
   i += SUB_INDENT;
@@ -570,17 +608,7 @@ static void
 user_token_number_redeclaration (int num, symbol *first, symbol *second)
 {
   unsigned i = 0;
-  /* User token numbers are not assigned during the parsing, but in a
-     second step, via a traversal of the symbol table sorted on tag.
-
-     However, error messages make more sense if we keep the first
-     declaration first.  */
-  if (location_cmp (first->location, second->location) > 0)
-    {
-      symbol* tmp = first;
-      first = second;
-      second = tmp;
-    }
+  symbols_sort (&first, &second);
   complain_indent (&second->location, complaint, &i,
                    _("user token number %d redeclaration for %s"),
                    num, second->tag);
diff --git a/src/uniqstr.c b/src/uniqstr.c
index 37345dc..b460ea7 100644
--- a/src/uniqstr.c
+++ b/src/uniqstr.c
@@ -77,8 +77,8 @@ uniqstr_vsprintf (char const *format, ...)
 void
 uniqstr_assert (char const *str)
 {
-  uniqstr *s = hash_lookup (uniqstrs_table, str);
-  if (!s || s != (uniqstr *)str)
+  uniqstr s = hash_lookup (uniqstrs_table, str);
+  if (!s || s != str)
     {
       error (0, 0,
              "not a uniqstr: %s", quotearg (str));
diff --git a/src/uniqstr.h b/src/uniqstr.h
index 006c10f..7ad52da 100644
--- a/src/uniqstr.h
+++ b/src/uniqstr.h
@@ -20,6 +20,8 @@
 #ifndef UNIQSTR_H_
 # define UNIQSTR_H_
 
+# include <stdio.h>
+
 /*-----------------------------------------.
 | Pointers to unique copies of C strings.  |
 `-----------------------------------------*/
@@ -33,7 +35,7 @@ uniqstr uniqstr_new (char const *str);
    strings, use UNIQSTR_CONCAT, which is a convenient wrapper around
    this function.  */
 uniqstr uniqstr_vsprintf (char const *format, ...)
-  __attribute__ ((__format__ (__printf__, 1, 2)));
+  _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2);
 
 /* Two uniqstr values have the same value iff they are the same.  */
 # define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2)))
diff --git a/tests/actions.at b/tests/actions.at
index 6c1ecbc..a9846d4 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -596,7 +596,7 @@ thing:
 ;
 %%
 /* Alias to ARGV[1]. */
-const char *source = YY_NULL;
+const char *source = YY_NULLPTR;
 
 ]AT_YYERROR_DEFINE[
 
diff --git a/tests/c++.at b/tests/c++.at
index e4c527c..5b3df02 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -243,7 +243,7 @@ typedef std::list<std::string> strings_type;
 // digraph for the left square bracket.
 %type <::std::list<std::string>> list result;
 
-%printer { yyo << $][$; }
+%printer { yyo << $$; }
   <int> <::std::string> <::std::list<std::string>>;
 %%
 
@@ -253,13 +253,13 @@ result:
 
 list:
   /* nothing */ { /* Generates an empty string list */ }
-| list item     { std::swap ($][$,$][1); $$.push_back ($][2); }
-| list error    { std::swap ($][$,$][1); }
+| list item     { std::swap ($$,$][1); $$.push_back ($][2); }
+| list error    { std::swap ($$,$][1); }
 ;
 
 item:
-  TEXT          { std::swap ($][$,$][1); }
-| NUMBER        { if ($][1 == 3) YYERROR; else $][$ = string_cast ($][1); }
+  TEXT          { std::swap ($$,$][1); }
+| NUMBER        { if ($][1 == 3) YYERROR; else $$ = string_cast ($][1); }
 ;
 %%
 ]AT_TOKEN_CTOR_IF([],
@@ -649,11 +649,14 @@ AT_CLEANUP
 ## Exception safety.  ##
 ## ------------------ ##
 
-# AT_TEST([BISON-DIRECTIVES])
-# ---------------------------
+# AT_TEST([BISON-DIRECTIVES = ''], [WITH-RECOVERY = "with"])
+# ----------------------------------------------------------
 # Check that no object is leaked when exceptions are thrown.
+# WITH-RECOVERY = "with" or "without".
 m4_pushdef([AT_TEST],
-[AT_SETUP([[Exception safety $1]])
+[AT_SETUP([[Exception safety $2 error recovery $1]])
+
+AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
 
 AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
 
@@ -667,43 +670,53 @@ $1
   #include <cassert>
   #include <cstdlib> // size_t and getenv.
   #include <iostream>
-  #include <list>
+  #include <set>
 
   bool debug = false;
 
-  /// A class that counts its number of instances.
+  /// A class that tracks its instances.
   struct Object
   {
     char val;
 
-    Object (char v)
-      : val (v)
+    Object ()
+      : val ('?')
     {
-      Object::instances.push_back(this);
       log (this, "Object::Object");
+      Object::instances.insert (this);
     }
 
-    Object ()
-      : val ('?')
+    Object (const Object& that)
+      : val (that.val)
     {
-      Object::instances.push_back(this);
       log (this, "Object::Object");
+      Object::instances.insert (this);
     }
 
-    Object& operator= (char v)
+    Object (char v)
+      : val (v)
     {
-      val = v;
-      return *this;
+      log (this, "Object::Object");
+      Object::instances.insert (this);
     }
 
     ~Object ()
     {
-      Object::instances.remove (this);
       log (this, "Object::~Object");
+      objects::const_iterator i = instances.find (this);
+      // Make sure this object is alive.
+      assert (i != instances.end ());
+      Object::instances.erase (i);
+    }
+
+    Object& operator= (char v)
+    {
+      val = v;
+      return *this;
     }
 
     // Static part.
-    typedef std::list<const Object*> objects;
+    typedef std::set<const Object*> objects;
     static objects instances;
 
     static bool
@@ -783,22 +796,23 @@ $1
 start: list {]AT_VARIANT_IF([], [ delete $][1]; )[};
 
 list:
-  item       { $][$ = $][1; }
+  item       { $$ = $][1; }
   // Right recursion to load the stack.
-| item list  { $][$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
+| item list  { $$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
 ;
 
 item:
-  'a'     { $$][ = $][1; }
-| 'e'     { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
+  'a'     { $$ = $][1; }
+| 'e'     { YYUSE ($$); YYUSE($][1); error ("syntax error"); }
 // Not just 'E', otherwise we reduce when 'E' is the lookahead, and
 // then the stack is emptied, defeating the point of the test.
-| 'E' 'a' { YYUSE($][1); $][$ = $][2; }
-| 'R'     { ]AT_VARIANT_IF([], [$][$ = YY_NULL; delete $][1]; )[YYERROR; }
-| 'p'     { $][$ = $][1; }
-| 's'     { $][$ = $][1; throw std::runtime_error ("reduction"); }
-| 'T'     { ]AT_VARIANT_IF([], [$][$ = YY_NULL; delete $][1]; )[YYABORT; }
-| error   { ]AT_VARIANT_IF([], [$][$ = YY_NULL; ])[yyerrok; }
+| 'E' 'a' { YYUSE($][1); $$ = $][2; }
+| 'R'     { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; }
+| 'p'     { $$ = $][1; }
+| 's'     { $$ = $][1; throw std::runtime_error ("reduction"); }
+| 'T'     { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYABORT; }
+]m4_if([$2], [with],
+[[| error   { $$ = ]AT_VARIANT_IF([], [new ])[Object ('R'); yyerrok; }]])[
 ;
 %%
 
@@ -818,7 +832,8 @@ yylex (yy::parser::semantic_type *lvalp)
   case 'l':
     throw std::runtime_error ("yylex");
   default:
-    lvalp]AT_VARIANT_IF([->build (res)], [->obj = new Object (res)])[;
+    lvalp->]AT_VARIANT_IF([build (Object (res))],
+                          [obj = new Object (res)])[;
     // Fall through.
   case 0:
     return res;
@@ -865,7 +880,7 @@ main (int argc, const char *argv[])
   {
     std::cerr << "unknown exception caught" << std::endl;
   }
-  Object::log (YY_NULL, "end");
+  Object::log (YY_NULLPTR, "end");
   assert (Object::empty());
   return res;
 }
@@ -900,16 +915,17 @@ AT_PARSER_CHECK([[./input aaaaE]], [[2]], [[]],
 
 AT_PARSER_CHECK([[./input aaaaT]], [[1]])
 
-# There is error-recovery, so exit success.
-AT_PARSER_CHECK([[./input aaaaR]], [[0]])
+AT_PARSER_CHECK([[./input aaaaR]], [m4_if([$2], [with], [0], [1])])
 
 AT_BISON_OPTION_POPDEFS
 
 AT_CLEANUP
 ])
 
-AT_TEST
-AT_TEST([%define api.value.type variant])
+AT_TEST([], [with])
+AT_TEST([], [without])
+AT_TEST([%define api.value.type variant], [with])
+AT_TEST([%define api.value.type variant], [without])
 
 m4_popdef([AT_TEST])
 
diff --git a/tests/conflicts.at b/tests/conflicts.at
index bbb3f89..1ba94bc 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1447,7 +1447,7 @@ State 0
     0 $accept: . start $end
     1 start: . resolved_conflict 'a' reported_conflicts 'a'
     2 resolved_conflict: . 'a' unreachable1
-    3                  | .  ['a']
+    3                  | . %empty  ['a']
 
     $default  reduce using rule 3 (resolved_conflict)
 
@@ -1483,7 +1483,7 @@ State 4
     1 start: resolved_conflict 'a' . reported_conflicts 'a'
     8 reported_conflicts: . 'a'
     9                   | . 'a'
-   10                   | .  ['a']
+   10                   | . %empty  ['a']
 
     'a'  shift, and go to state 5
 
@@ -1576,11 +1576,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 
0$/,/^State 1$/p']], 0,
     6      | . empty_c1 'c'
     7      | . empty_c2 'c'
     8      | . empty_c3 'c'
-    9 empty_a: .  ['a']
-   10 empty_b: .  []
-   11 empty_c1: .  []
-   12 empty_c2: .  []
-   13 empty_c3: .  ['c']
+    9 empty_a: . %empty  ['a']
+   10 empty_b: . %empty  []
+   11 empty_c1: . %empty  []
+   12 empty_c2: . %empty  []
+   13 empty_c3: . %empty  ['c']
 
     'b'  shift, and go to state 1
 
@@ -1652,11 +1652,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 
0$/,/^State 1$/p']], 0,
     6      | . empty_c1 'c'
     7      | . empty_c2 'c'
     8      | . empty_c3 'c'
-    9 empty_a: .  []
-   10 empty_b: .  []
-   11 empty_c1: .  []
-   12 empty_c2: .  ['c']
-   13 empty_c3: .  ['c']
+    9 empty_a: . %empty  []
+   10 empty_b: . %empty  []
+   11 empty_c1: . %empty  []
+   12 empty_c2: . %empty  ['c']
+   13 empty_c3: . %empty  ['c']
 
     'a'  error (nonassociative)
     'b'  error (nonassociative)
diff --git a/tests/cxx-type.at b/tests/cxx-type.at
index 2c37c17..196ac0b 100644
--- a/tests/cxx-type.at
+++ b/tests/cxx-type.at
@@ -94,19 +94,19 @@ prog :
 
 stmt : expr ';'  $2     { $$ = ]$[1; }
      | decl      $3
-     | error ';'        { $$ = new_nterm ("<error>", YY_NULL, YY_NULL, 
YY_NULL); }
+     | error ';'        { $$ = new_nterm ("<error>", YY_NULLPTR, YY_NULLPTR, 
YY_NULLPTR); }
      | '@'              { YYACCEPT; }
      ;
 
 expr : ID
      | TYPENAME '(' expr ')'
-                        { $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, 
YY_NULL); }
-     | expr '+' expr    { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULL); }
-     | expr '=' expr    { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULL); }
+                        { $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, 
YY_NULLPTR); }
+     | expr '+' expr    { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); 
}
+     | expr '=' expr    { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); 
}
      ;
 
 decl : TYPENAME declarator ';'
-                        { $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, 
YY_NULL); }
+                        { $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, 
YY_NULLPTR); }
      | TYPENAME declarator '=' expr ';'
                         { $$ = new_nterm ("<init-declare>(%s,%s,%s)", ]$[1,
                                           ]$[2, ]$[4); }
@@ -195,7 +195,7 @@ main (int argc, char **argv)
               {
                 colNum += 1;
                 tok = c;
-                yylval = YY_NULL;
+                yylval = YY_NULLPTR;
               }]AT_LOCATION_IF([[
             yylloc.last_column = colNum-1;]])[
             return tok;
@@ -287,7 +287,7 @@ m4_bmatch([$2], [stmtMerge],
 [[static YYSTYPE
 stmtMerge (YYSTYPE x0, YYSTYPE x1)
 {
-  return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULL);
+  return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULLPTR);
 }
 ]])
 )
diff --git a/tests/glr-regression.at b/tests/glr-regression.at
index 711ab7e..b1444bb 100644
--- a/tests/glr-regression.at
+++ b/tests/glr-regression.at
@@ -67,7 +67,7 @@ static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
   return 0;
 }
 
-const char *input = YY_NULL;
+const char *input = YY_NULLPTR;
 
 int
 main (int argc, const char* argv[])
@@ -304,7 +304,7 @@ MergeRule (int x0, int x1)
 }
 ]AT_YYERROR_DEFINE[
 
-FILE *input = YY_NULL;
+FILE *input = YY_NULLPTR;
 
 int P[] = { P1, P2 };
 int O[] = { O1, O2 };
@@ -1749,3 +1749,33 @@ Cleanup: popping token 'a' ()
 ])
 
 AT_CLEANUP
+
+
+## ----------------------------------------------------------------- ##
+## Predicates.                                                       ##
+##                                                                   ##
+## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
+## ----------------------------------------------------------------- ##
+
+AT_SETUP([Predicates])
+
+# FIXME: We need genuine test cases with uses of %?.
+
+AT_DATA_GRAMMAR([input.y],
+[[%glr-parser
+%expect-rr 1
+%%
+// Exercise "%?{...}" and "%? {...}".
+widget:
+  %? {new_syntax} "widget" id new_args  { $$ = f($3, $4); }
+| %?{!new_syntax} "widget" id old_args  { $$ = f($3, $4); }
+;
+id:;
+new_args:;
+old_args:;
+%%
+]])
+
+AT_BISON_CHECK([[input.y]])
+
+AT_CLEANUP
diff --git a/tests/headers.at b/tests/headers.at
index 0ad7ef3..f32e2a1 100644
--- a/tests/headers.at
+++ b/tests/headers.at
@@ -223,9 +223,13 @@ AT_CHECK([[$PERL -n -0777 -e '
   s{/\*.*?\*/}{}gs;
   s{//.*}{}g;
   s{\b(YYChar
-      |YYPUSH_MORE(_DEFINED)?
+      |YYPUSH_MORE(?:_DEFINED)?
+      |YYUSE
+      |YY_ATTRIBUTE(?:_PURE|_UNUSED)?
+      |YY_IGNORE_MAYBE_UNINITIALIZED_(?:BEGIN|END)
+      |YY_INITIAL_VALUE
       |YY_\w+_INCLUDED
-      |YY_NULL
+      |YY_NULLPTR
       |(defined|if)\ YYDEBUG
       )\b}{}gx;
   while (/^(.*YY.*)$/gm)
diff --git a/tests/input.at b/tests/input.at
index 1548f14..205342b 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -654,50 +654,118 @@ AT_CLEANUP
 
 AT_SETUP([Incompatible Aliases])
 
-AT_DATA([input.y],
-[[%token foo "foo"
-
-%type <bar>       foo
-%printer {bar}    foo
-%destructor {bar} foo
-%left             foo
+m4_pushdef([AT_TEST],
+[AT_DATA([input.y], [$1])
+AT_BISON_CHECK([-fcaret input.y], [1], [], [$2])
+])
 
-%type <baz>       "foo"
-%printer {baz}    "foo"
-%destructor {baz} "foo"
-%left             "foo"
+# Use the string-alias first to check the order between "first
+# declaration" and second.
 
+AT_TEST([[%token foo "foo"
+%type <bar> "foo"
+%type <baz> foo
 %%
 exp: foo;
-]])
-
-AT_BISON_CHECK([-fcaret input.y], [1], [],
-[[input.y:8.7-11: error: %type redeclaration for "foo"
- %type <baz>       "foo"
+]],
+[[input.y:3.7-11: error: %type redeclaration for foo
+ %type <baz> foo
        ^^^^^
-input.y:3.7-11:     previous declaration
- %type <bar>       foo
+input.y:2.7-11:     previous declaration
+ %type <bar> "foo"
        ^^^^^
-input.y:9.10-14: error: %printer redeclaration for "foo"
- %printer {baz}    "foo"
+]])
+
+AT_TEST([[%token foo "foo"
+%printer {bar} "foo"
+%printer {baz} foo
+%%
+exp: foo;
+]],
+[[input.y:3.10-14: error: %printer redeclaration for foo
+ %printer {baz} foo
           ^^^^^
-input.y:4.10-14:     previous declaration
- %printer {bar}    foo
+input.y:2.10-14:     previous declaration
+ %printer {bar} "foo"
           ^^^^^
-input.y:10.13-17: error: %destructor redeclaration for "foo"
- %destructor {baz} "foo"
+]])
+
+AT_TEST([[%token foo "foo"
+%destructor {bar} "foo"
+%destructor {baz} foo
+%%
+exp: foo;
+]],
+[[input.y:3.13-17: error: %destructor redeclaration for foo
+ %destructor {baz} foo
              ^^^^^
-input.y:5.13-17:      previous declaration
- %destructor {bar} foo
+input.y:2.13-17:     previous declaration
+ %destructor {bar} "foo"
              ^^^^^
-input.y:11.1-5: error: %left redeclaration for "foo"
- %left             "foo"
+]])
+
+AT_TEST([[%token foo "foo"
+%left "foo"
+%left foo
+%%
+exp: foo;
+]],
+[[input.y:3.1-5: error: %left redeclaration for foo
+ %left foo
  ^^^^^
-input.y:6.1-5:      previous declaration
- %left             foo
+input.y:2.1-5:     previous declaration
+ %left "foo"
  ^^^^^
 ]])
 
+# This time, declare the alias after its use.
+
+# Precedence/associativity.
+## FIXME: AT_TEST([[%left "foo"
+## FIXME: %left foo
+## FIXME: %token foo "foo"
+## FIXME: %%
+## FIXME: exp: foo;
+## FIXME: ]],
+## FIXME: [[input.y:2.1-5: error: %left redeclaration for foo
+## FIXME:  %left foo
+## FIXME:  ^^^^^
+## FIXME: input.y:1.1-5:     previous declaration
+## FIXME:  %left "foo"
+## FIXME:  ^^^^^
+## FIXME: ]])
+
+## FIXME: # Printer.
+## FIXME: AT_TEST([[%printer {} "foo"
+## FIXME: %printer {} foo
+## FIXME: %token foo "foo"
+## FIXME: %%
+## FIXME: exp: foo;
+## FIXME: ]],
+## FIXME: [[input.y:2.10-11: error: %printer redeclaration for foo
+## FIXME:  %printer {} foo
+## FIXME:           ^^
+## FIXME: input.y:1.10-11:     previous declaration
+## FIXME:  %printer {} "foo"
+## FIXME:           ^^
+## FIXME: ]])
+
+## FIXME: # Destructor.
+## FIXME: AT_TEST([[%destructor {} "foo"
+## FIXME: %destructor {} foo
+## FIXME: %token foo "foo"
+## FIXME: %%
+## FIXME: exp: foo;
+## FIXME: ]],
+## FIXME: [[input.y:2.13-14: error: %destructor redeclaration for foo
+## FIXME:  %destructor {} foo
+## FIXME:              ^^
+## FIXME: input.y:1.13-14:     previous declaration
+## FIXME:  %destructor {} "foo"
+## FIXME:              ^^
+## FIXME: ]])
+
+m4_popdef([AT_TEST])
 AT_CLEANUP
 
 
@@ -956,15 +1024,9 @@ without_period: "WITHOUT.PERIOD";
 AT_BISON_OPTION_POPDEFS
 
 # POSIX Yacc accept periods, but not dashes.
-AT_BISON_CHECK([--yacc -Wno-error input.y], [], [],
-[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: 
WITH-DASH [-Wyacc]
-input.y:20.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash 
[-Wyacc]
-]])
-
-# So warn about them.
-AT_BISON_CHECK([-Wyacc input.y], [], [],
-[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: 
WITH-DASH [-Wyacc]
-input.y:20.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash 
[-Wyacc]
+AT_BISON_CHECK([--yacc input.y], [1], [],
+[[input.y:9.8-16: error: POSIX Yacc forbids dashes in symbol names: WITH-DASH 
[-Werror=yacc]
+input.y:20.8-16: error: POSIX Yacc forbids dashes in symbol names: with-dash 
[-Werror=yacc]
 ]])
 
 # Dashes are fine for GNU Bison.
@@ -1768,11 +1830,11 @@ AT_BISON_CHECK([[-Dparse.lac.memory-trace=full 
input.y]],
 
 AT_CLEANUP
 
-## --------------------------------------------- ##
-## -Werror is not affected by -Wnone and -Wall.  ##
-## --------------------------------------------- ##
+## ---------------------- ##
+## -Werror combinations.  ##
+## ---------------------- ##
 
-AT_SETUP([[-Werror is not affected by -Wnone and -Wall]])
+AT_SETUP([[-Werror combinations]])
 
 AT_DATA([[input.y]],
 [[%%
@@ -1798,6 +1860,18 @@ AT_BISON_CHECK([[-Werror,no-all,other input.y]], [[1]], 
[[]],
 [[input.y:2.15: error: stray '$' [-Werror=other]
 ]])
 
+# Check that -Wno-error keeps warnings enabled, but non fatal.
+AT_BISON_CHECK([[-Werror -Wno-error=other input.y]], [[0]], [[]],
+[[input.y:2.15: warning: stray '$' [-Wother]
+]])
+
+AT_BISON_CHECK([[-Wno-error=other -Werror input.y]], [[0]], [[]],
+[[input.y:2.15: warning: stray '$' [-Wother]
+]])
+
+AT_BISON_CHECK([[-Werror=other -Wno-other input.y]], [[0]], [[]],
+[[]])
+
 AT_CLEANUP
 
 
diff --git a/tests/local.at b/tests/local.at
index 7948faa..72c0d52 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -635,9 +635,12 @@ m4_define([AT_BISON_CHECK_],
 # ----------------------------------------------------------
 # Check that warnings (if some are expected) are correctly
 # turned into errors with -Werror, etc.
+#
+# When -Wno-error is used, the rules are really different, don't try.
 m4_define([AT_BISON_CHECK_WARNINGS],
 [m4_if(m4_bregexp([$4], [: warning: ]), [-1], [],
-      [m4_null_if([$2], [AT_BISON_CHECK_WARNINGS_($@)])])])
+       m4_bregexp([$1], [-Wno-error=]), [-1],
+                  [m4_null_if([$2], [AT_BISON_CHECK_WARNINGS_($@)])])])
 
 m4_define([AT_BISON_CHECK_WARNINGS_],
 [[# Defining POSIXLY_CORRECT causes bison to complain if options are
@@ -872,6 +875,49 @@ AT_PARSER_CHECK([./c-and-cxx])
 ])
 
 
+# AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
+# ------------------------------------
+# Check that we can expect exceptions to be handled properly.
+# GCC 4.3 and 4.4 fail https://trac.macports.org/ticket/40853.
+m4_define([AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR],
+[AT_DATA_SOURCE([exception.cc],
+[[#include <iostream>
+#include <stdexcept>
+
+void foo()
+{
+  try
+    {
+      throw std::runtime_error("foo");
+    }
+  catch (...)
+    {
+      std::cerr << "Inner caught" << std::endl;
+      throw;
+    }
+}
+
+int main()
+{
+  try
+    {
+      foo();
+    }
+  catch (...)
+    {
+      std::cerr << "Outer caught" << std::endl;
+      return 0;
+    }
+  return 1;
+}
+]])
+AT_COMPILE_CXX([exception])
+# The "empty" quadrigraph is to protect from cfg.mk's
+# sc_at_parser_check.
+AT_CHECK([@&address@hidden/exception || exit 77], [0], [], [ignore])
+])
+
+
 ## ---------------------------- ##
 ## Running a generated parser.  ##
 ## ---------------------------- ##
diff --git a/tests/local.mk b/tests/local.mk
index 5f7fa45..394a92e 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -85,7 +85,7 @@ $(TESTSUITE): $(TESTSUITE_AT)
 # Move into tests/ so that testsuite.dir etc. be created there.
 RUN_TESTSUITE = $(TESTSUITE) -C tests $(TESTSUITEFLAGS)
 check_SCRIPTS = $(BISON) tests/atconfig tests/atlocal
-RUN_TESTSUITE_deps = $(TESTSUITE) $(check_SCRIPTS)
+RUN_TESTSUITE_deps = all $(TESTSUITE) $(check_SCRIPTS)
 
 clean-local: clean-local-tests
 clean-local-tests:
@@ -126,3 +126,6 @@ maintainer-push-check:
 maintainer-xml-check:
        $(MAKE) $(AM_MAKEFLAGS) maintainer-check                \
          TESTSUITEFLAGS='BISON_TEST_XML=1 $(TESTSUITEFLAGS)'
+
+.PHONY: maintainer-release-check
+maintainer-release-check: maintainer-check maintainer-push-check 
maintainer-xml-check
diff --git a/tests/output.at b/tests/output.at
index 6c98ef7..be3078f 100644
--- a/tests/output.at
+++ b/tests/output.at
@@ -17,12 +17,23 @@
 
 AT_BANNER([[Output file names.]])
 
+# AT_CHECK_FILES(EXPECTED-FILES, [IGNORED-FILES])
+# -----------------------------------------------
+# Check that the current directory contains FILE... (sorted).
+m4_define([AT_CHECK_FILES],
+[AT_CHECK([[find . -type f |
+           $PERL -ne '
+      s,\./,,; chomp;
+      push @file, $_ unless m{^($2|testsuite.log)$};
+      END { print join (" ", sort @file), "\n" }']],
+          [], [$1
+])])
 
-# AT_CHECK_OUTPUT(INPUT-FILE, [DIRECTIVES], [FLAGS], EXPECTED-FILES, [SHELLIO],
+# AT_CHECK_OUTPUT(INPUT-FILE, [DIRECTIVES], [FLAGS], EXPECTED-FILES, [STATUS],
 #                 [ADDITIONAL-TESTS], [PRE-TESTS])
 # -----------------------------------------------------------------------------
 m4_define([AT_CHECK_OUTPUT],
-[AT_SETUP([[Output files: ]$2 $3 $5])[
+[AT_SETUP([[Output files: ]$2 $3])[
 ]$7[
 for file in ]$1 $4[; do
   case $file in
@@ -32,18 +43,12 @@ done
 ]AT_DATA([$1],
 [$2[
 %%
-foo: {};
+foo: %empty {};
 ]])[
 
-]AT_BISON_CHECK([$3 $1 $5], 0)[
+]AT_BISON_CHECK([$3 $1], [$5], [], [ignore])[
 # Ignore the files non-generated files
-]AT_CHECK([[find . -type f |
-           $PERL -ne '
-      s,\./,,; chomp;
-      push @file, $_ unless m{^($1|testsuite.log)$};
-      END { print join (" ", sort @file), "\n" }']],
-          [], [$4
-])[
+]AT_CHECK_FILES([$4], [$1])[
 ]$6[
 ]AT_CLEANUP[
 ]])
@@ -54,9 +59,9 @@ AT_CHECK_OUTPUT([foo.y], [], [-dv],
 # Some versions of Valgrind (at least valgrind-3.6.0.SVN-Debian) report
 # "fgrep: write error: Bad file descriptor" when stdout is closed, so we
 # skip this test group during maintainer-check-valgrind.
-AT_CHECK_OUTPUT([foo.y], [], [-dv],
+AT_CHECK_OUTPUT([foo.y], [], [-dv >&-],
                 [foo.output foo.tab.c foo.tab.h],
-                [>&-], [],
+                [], [],
                 [AT_CHECK([[case "$PREBISON" in *valgrind*) exit 77;; esac]])])
 
 AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c],
@@ -114,6 +119,20 @@ AT_CHECK_OUTPUT([foo.yy], [],
                 [-o foo.c++ --graph=foo.gph],
                 [foo.c++ foo.gph])
 
+# Do not generate code when there are early errors (even warnings as
+# errors).
+AT_CHECK_OUTPUT([foo.y], [%type <foo> useless],
+                [--defines --graph --xml --report=all -Wall -Werror],
+                [foo.dot foo.output foo.xml],
+                [1])
+
+# Do not generate code when there are late errors (even warnings as
+# errors).
+AT_CHECK_OUTPUT([foo.y], [%define useless],
+                [--defines --graph --xml --report=all -Wall -Werror],
+                [foo.dot foo.output foo.xml],
+                [1])
+
 
 ## ------------ ##
 ## C++ output.  ##
@@ -290,7 +309,7 @@ a: ;
 b: 'b';
 ]],
 [[
-  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . a '?' b\l  2 a: 
.\l"]
+  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . a '?' b\l  2 a: . 
%empty\l"]
   0 -> 1 [style=dashed label="exp"]
   0 -> 2 [style=dashed label="a"]
   0 -> "0R2" [style=solid]
@@ -332,7 +351,7 @@ empty_b: %prec 'b';
 empty_c: %prec 'c';
 ]],
 [[
-  0 [label="State 0\n\l  0 $accept: . start $end\l  1 start: . 'a'\l  2      | 
. empty_a 'a'\l  3      | . 'b'\l  4      | . empty_b 'b'\l  5      | . 'c'\l  
6      | . empty_c 'c'\l  7 empty_a: .  ['a']\l  8 empty_b: .  ['b']\l  9 
empty_c: .  ['c']\l"]
+  0 [label="State 0\n\l  0 $accept: . start $end\l  1 start: . 'a'\l  2      | 
. empty_a 'a'\l  3      | . 'b'\l  4      | . empty_b 'b'\l  5      | . 'c'\l  
6      | . empty_c 'c'\l  7 empty_a: . %empty  ['a']\l  8 empty_b: . %empty  
['b']\l  9 empty_c: . %empty  ['c']\l"]
   0 -> 1 [style=solid label="'a'"]
   0 -> 2 [style=solid label="'b'"]
   0 -> 3 [style=solid label="'c'"]
@@ -399,7 +418,7 @@ empty_b: %prec 'b';
 empty_c: %prec 'c';
 ]],
 [[
-  0 [label="State 0\n\l  0 $accept: . start $end\l  1 start: . 'a'\l  2      | 
. empty_a 'a'\l  3      | . 'b'\l  4      | . empty_b 'b'\l  5      | . 'c'\l  
6      | . empty_c 'c'\l  7 empty_a: .  ['a']\l  8 empty_b: .  []\l  9 empty_c: 
.  []\l"]
+  0 [label="State 0\n\l  0 $accept: . start $end\l  1 start: . 'a'\l  2      | 
. empty_a 'a'\l  3      | . 'b'\l  4      | . empty_b 'b'\l  5      | . 'c'\l  
6      | . empty_c 'c'\l  7 empty_a: . %empty  ['a']\l  8 empty_b: . %empty  
[]\l  9 empty_c: . %empty  []\l"]
   0 -> 1 [style=solid label="'b'"]
   0 -> 2 [style=solid label="'c'"]
   0 -> 3 [style=dashed label="start"]
@@ -447,7 +466,7 @@ a: ;
 b: ;
 ]],
 [[
-  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . a\l  2    | . b\l  
3 a: .  [$end]\l  4 b: .  [$end]\l"]
+  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . a\l  2    | . b\l  
3 a: . %empty  [$end]\l  4 b: . %empty  [$end]\l"]
   0 -> 1 [style=dashed label="exp"]
   0 -> 2 [style=dashed label="a"]
   0 -> 3 [style=dashed label="b"]
@@ -480,7 +499,7 @@ b: ;
 c: ;
 ]],
 [[
-  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . a ';'\l  2    | . a 
';'\l  3    | . a '.'\l  4    | . b '?'\l  5    | . b '!'\l  6    | . c '?'\l  
7    | . c ';'\l  8 a: .  [';', '.']\l  9 b: .  ['?', '!']\l 10 c: .  [';', 
'?']\l"]
+  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . a ';'\l  2    | . a 
';'\l  3    | . a '.'\l  4    | . b '?'\l  5    | . b '!'\l  6    | . c '?'\l  
7    | . c ';'\l  8 a: . %empty  [';', '.']\l  9 b: . %empty  ['?', '!']\l 10 
c: . %empty  [';', '?']\l"]
   0 -> 1 [style=dashed label="exp"]
   0 -> 2 [style=dashed label="a"]
   0 -> 3 [style=dashed label="b"]
@@ -595,7 +614,7 @@ imm: '0';
  "11R7d" [label="R7", fillcolor=5, shape=diamond, style=filled]
   11 -> "11R7" [style=solid]
  "11R7" [label="R7", fillcolor=3, shape=diamond, style=filled]
-  12 [label="State 12\n\l  4 ifexp: \"if\" exp \"then\" exp . elseexp\l  5 
elseexp: . \"else\" exp\l  6        | .  [$end, \"then\", \"else\", '+']\l  7 
opexp: exp . '+' exp\l"]
+  12 [label="State 12\n\l  4 ifexp: \"if\" exp \"then\" exp . elseexp\l  5 
elseexp: . \"else\" exp\l  6        | . %empty  [$end, \"then\", \"else\", 
'+']\l  7 opexp: exp . '+' exp\l"]
   12 -> 13 [style=solid label="\"else\""]
   12 -> 9 [style=solid label="'+'"]
   12 -> 14 [style=dashed label="elseexp"]
diff --git a/tests/push.at b/tests/push.at
index 7dde295..d39ca56 100644
--- a/tests/push.at
+++ b/tests/push.at
@@ -57,12 +57,12 @@ main (void)
   /* yypstate_delete used to leak ps->yyss if the stack was reallocated but the
      parse did not return on success, syntax error, or memory exhaustion.  */
   ps = yypstate_new ();
-  assert (yypush_parse (ps, 'a', YY_NULL) == YYPUSH_MORE);
+  assert (yypush_parse (ps, 'a', YY_NULLPTR) == YYPUSH_MORE);
   yypstate_delete (ps);
 
   ps = yypstate_new ();
-  assert (yypush_parse (ps, 'a', YY_NULL) == YYPUSH_MORE);
-  assert (yypush_parse (ps, 'b', YY_NULL) == YYPUSH_MORE);
+  assert (yypush_parse (ps, 'a', YY_NULLPTR) == YYPUSH_MORE);
+  assert (yypush_parse (ps, 'b', YY_NULLPTR) == YYPUSH_MORE);
   yypstate_delete (ps);
 
   return 0;
@@ -111,11 +111,11 @@ main (void)
     {
       yypstate *ps = yypstate_new ();
       assert (ps);
-      assert (yypstate_new () == YY_NULL);
+      assert (yypstate_new () == YY_NULLPTR);
       ]m4_if([$1], [[both]], [[assert (yyparse () == 2)]])[;
       yychar = 0;
       assert (yypush_parse (ps) == 0);
-      assert (yypstate_new () == YY_NULL);
+      assert (yypstate_new () == YY_NULLPTR);
       ]m4_if([$1], [[both]], [[assert (yyparse () == 2)]])[;
       yypstate_delete (ps);
     }
diff --git a/tests/reduce.at b/tests/reduce.at
index 7e4977a..9da9f49 100644
--- a/tests/reduce.at
+++ b/tests/reduce.at
@@ -1057,7 +1057,7 @@ State 12
 
     4 A: 'a' 'a' . B
     5 B: . 'a'
-    6  | .  ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
+    6  | . %empty  ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[
 
     ]AT_COND_CASE([[canonical LR]], [['a']],
                   [[$default]])[  reduce using rule 6 (B)
@@ -1087,7 +1087,7 @@ State 15
 
     4 A: 'a' 'a' . B
     5 B: . 'a'
-    6  | .  [$end]
+    6  | . %empty  [$end]
     7 c: 'a' 'a' . 'b'
 
     'a'  shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]],
@@ -1150,7 +1150,7 @@ State 22]])[
 
     4 A: 'a' 'a' . B
     5 B: . 'a'
-    6  | .  ['b']
+    6  | . %empty  ['b']
 
     'a'  shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]],
                                               [[16]])[
@@ -1575,8 +1575,8 @@ State 3
     1 start: a . b
     2      | a . b 'a'
     3      | a . c 'b'
-    5 b: .  [$end, 'a']
-    6 c: .  ['b']]AT_COND_CASE([[most]], [[
+    5 b: . %empty  [$end, 'a']
+    6 c: . %empty  ['b']]AT_COND_CASE([[most]], [[
 
     'b'       reduce using rule 6 (c)
     $default  reduce using rule 5 (b)]], [[
diff --git a/tests/regression.at b/tests/regression.at
index b9ca94c..223dc06 100644
--- a/tests/regression.at
+++ b/tests/regression.at
@@ -770,7 +770,7 @@ static const yytype_uint8 yyrline[] =
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
-  "\"else\"", "$accept", "statement", "struct_stat", "if", "else", YY_NULL
+  "\"else\"", "$accept", "statement", "struct_stat", "if", "else", YY_NULLPTR
 };
 static const yytype_uint16 yytoknum[] =
 {




reply via email to

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