Update build-tools to ab/8374076 am: 6419c3ee35 am: aa12a3f25f am: 397aa728a9

Original change: https://android-review.googlesource.com/c/platform/prebuilts/build-tools/+/2046951

Change-Id: I218d9bdd890532600ff38924eb2952e9d256ce25
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/common/bison/NOTICE b/common/bison/NOTICE
index 94a9ed0..f288702 100644
--- a/common/bison/NOTICE
+++ b/common/bison/NOTICE
@@ -1,7 +1,7 @@
                     GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -645,7 +645,7 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 Also add information on how to contact you by electronic and paper mail.
 
@@ -664,11 +664,11 @@
   You should also get your employer (if you work as a programmer) or school,
 if any, to sign a "copyright disclaimer" for the program, if necessary.
 For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
 
   The GNU General Public License does not permit incorporating your program
 into proprietary programs.  If your program is a subroutine library, you
 may consider it more useful to permit linking proprietary applications with
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/common/bison/README.md b/common/bison/README.md
index 94e9891..09886ea 100644
--- a/common/bison/README.md
+++ b/common/bison/README.md
@@ -1,6 +1,6 @@
 This directory contains data needed by Bison.
 
-# Directory content
+# Directory Content
 ## Skeletons
 Bison skeletons: the general shapes of the different parser kinds, that are
 specialized for specific grammars by the bison program.
@@ -48,7 +48,7 @@
 - xml2xhtml.xsl
   Conversion into XHTML.
 
-# Implementation note about the skeletons
+# Implementation Notes About the Skeletons
 
 "Skeleton" in Bison parlance means "backend": a skeleton is fed by the bison
 executable with LR tables, facts about the symbols, etc. and they generate
@@ -73,36 +73,63 @@
 your language.  Overall, be sure to follow the same patterns as the existing
 skeletons.
 
+## Vocabulary
+
+We use "formal arguments", or "formals" for short, to denote the declared
+parameters of a function (e.g., `int argc, const char **argv`).  Yes, this
+is somewhat contradictory with `param` in the `%param` directives.
+
+We use "effective arguments", or "args" for short, to denote the values
+passed in function calls (e.g., `argc, argv`).
+
 ## Symbols
 
 ### `b4_symbol(NUM, FIELD)`
 In order to unify the handling of the various aspects of symbols (tag, type
 name, whether terminal, etc.), bison.exe defines one macro per (token,
 field), where field can `has_id`, `id`, etc.: see
-`prepare_symbols_definitions()` in `src/output.c`.
+`prepare_symbol_definitions()` in `src/output.c`.
 
-The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
+NUM can be:
+- `empty` to denote the "empty" pseudo-symbol when it exists,
+- `eof`, `error`, or `undef`
+- a symbol number.
 
-- `has_id`: 0 or 1.
+FIELD can be:
 
-  Whether the symbol has an id.
+- `has_id`: 0 or 1
+  Whether the symbol has an `id`.
 
-- `id`: string
-  If has_id, the id (prefixed by api.token.prefix if defined), otherwise
-  defined as empty.  Guaranteed to be usable as a C identifier.
+- `id`: string (e.g., `exp`, `NUM`, or `TOK_NUM` with api.token.prefix)
+  If `has_id`, the name of the token kind (prefixed by api.token.prefix if
+  defined), otherwise empty.  Guaranteed to be usable as a C identifier.
+  This is used to define the token kind (i.e., the enum used by the return
+  value of yylex).  Should be named `token_kind`.
 
-- `tag`: string.
-  A representation of the symbol.  Can be 'foo', 'foo.id', '"foo"' etc.
+- `tag`: string
+  A human readable representation of the symbol.  Can be `'foo'`,
+  `'foo.id'`, `'"foo"'` etc.
 
-- `user_number`: integer
+- `code`: integer
+  The token code associated to the token kind `id`.
   The external number as used by yylex.  Can be ASCII code when a character,
-  some number chosen by bison, or some user number in the case of
-  %token FOO <NUM>.  Corresponds to yychar in yacc.c.
+  some number chosen by bison, or some user number in the case of `%token
+  FOO <NUM>`.  Corresponds to `yychar` in `yacc.c`.
 
 - `is_token`: 0 or 1
   Whether this is a terminal symbol.
 
+- `kind_base`: string (e.g., `YYSYMBOL_exp`, `YYSYMBOL_NUM`)
+  The base of the symbol kind, i.e., the enumerator of this symbol (token or
+  nonterminal) which is mapped to its `number`.
+
+- `kind`: string
+  Same as `kind_base`, but possibly with a prefix in some languages.  E.g.,
+  EOF's `kind_base` and `kind` are `YYSYMBOL_YYEOF` in C, but are
+  `S_YYEMPTY` and `symbol_kind::S_YYEMPTY` in C++.
+
 - `number`: integer
+  The code associated to the `kind`.
   The internal number (computed from the external number by yytranslate).
   Corresponds to yytoken in yacc.c.  This is the same number that serves as
   key in b4_symbol(NUM, FIELD).
@@ -129,11 +156,17 @@
   When api.value.type=union, the generated name for the union member.
   yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
 
-- `type`
+- `type`: string
   If it has a semantic value, its type tag, or, if variant are used,
   its type.
   In the case of api.value.type=union, type is the real type (e.g. int).
 
+- `slot`: string
+  If it has a semantic value, the name of the union member (i.e., bounces to
+  either `type_tag` or `type`).  It would be better to fix our mess and
+  always use `type` for the true type of the member, and `type_tag` for the
+  name of the union member.
+
 - `has_printer`: 0, 1
 - `printer`: string
 - `printer_file`: string
@@ -166,7 +199,7 @@
 Expansion of `$<TYPE>POS`, where the current rule has `RULE-LENGTH` symbols
 on RHS.
 
------
+<!--
 
 Local Variables:
 mode: markdown
@@ -174,7 +207,7 @@
 ispell-dictionary: "american"
 End:
 
-Copyright (C) 2002, 2008-2015, 2018-2019 Free Software Foundation, Inc.
+Copyright (C) 2002, 2008-2015, 2018-2021 Free Software Foundation, Inc.
 
 This file is part of GNU Bison.
 
@@ -189,4 +222,6 @@
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+-->
diff --git a/common/bison/bison-default.css b/common/bison/bison-default.css
index 68df166..aadaba1 100644
--- a/common/bison/bison-default.css
+++ b/common/bison/bison-default.css
@@ -1,5 +1,5 @@
 /* Default styling rules for Bison when doing terminal output.
-   Copyright (C) 2019 Free Software Foundation, Inc.
+   Copyright (C) 2019-2021 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -29,3 +29,33 @@
 
 /* "Sections" in traces (--trace).  */
 .trace0    { color: green; }
+
+/* Syntax error messages.  */
+.expected   { color: green; }
+.unexpected { color: red; }
+
+
+/* Counterexamples.  */
+
+/* Cex: point in rule.  */
+.cex-dot { color: red; }
+
+/* Cex: coloring various rules.  */
+.cex-0   { color: yellow; }
+.cex-1   { color: green; }
+.cex-2   { color: blue; }
+.cex-3   { color: purple; }
+.cex-4   { color: violet; }
+.cex-5   { color: orange; }
+.cex-6   { color: brown; }
+.cex-7   { color: mauve; }
+.cex-8   { color: #013220; } /* Dark green. */
+.cex-9   { color: #e75480; } /* Dark pink. */
+.cex-10  { color: cyan; }
+.cex-11  { color: orange; }
+
+/* Cex: derivation rewriting steps.  */
+.cex-step { font-style: italic; }
+
+/* Cex: leaves of a derivation.  */
+.cex-leaf { font-weight: 600; }
diff --git a/common/bison/local.mk b/common/bison/local.mk
index f82aee7..c51d287 100644
--- a/common/bison/local.mk
+++ b/common/bison/local.mk
@@ -1,4 +1,4 @@
-## Copyright (C) 2002, 2005-2015, 2018-2019 Free Software Foundation,
+## Copyright (C) 2002, 2005-2015, 2018-2021 Free Software Foundation,
 ## Inc.
 
 ## This program is free software: you can redistribute it and/or modify
@@ -12,7 +12,7 @@
 ## GNU General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
-## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+## along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 dist_pkgdata_DATA =                             \
   data/README.md                                \
@@ -28,18 +28,19 @@
   data/skeletons/c.m4                           \
   data/skeletons/glr.c                          \
   data/skeletons/glr.cc                         \
+  data/skeletons/glr2.cc                        \
   data/skeletons/java-skel.m4                   \
   data/skeletons/java.m4                        \
   data/skeletons/lalr1.cc                       \
   data/skeletons/lalr1.java                     \
   data/skeletons/location.cc                    \
   data/skeletons/stack.hh                       \
+  data/skeletons/traceon.m4                     \
   data/skeletons/variant.hh                     \
   data/skeletons/yacc.c
 
 # Experimental support for the D language.
 dist_skeletons_DATA +=                          \
-  data/skeletons/README-D.txt                   \
   data/skeletons/d-skel.m4                      \
   data/skeletons/d.m4                           \
   data/skeletons/lalr1.d
diff --git a/common/bison/m4sugar/foreach.m4 b/common/bison/m4sugar/foreach.m4
index 7093d0f..2052d44 100644
--- a/common/bison/m4sugar/foreach.m4
+++ b/common/bison/m4sugar/foreach.m4
@@ -4,7 +4,7 @@
 # Speeds up GNU M4 1.4.x by avoiding quadratic $@ recursion, but penalizes
 # GNU M4 1.6 by requiring more memory and macro expansions.
 #
-# Copyright (C) 2008-2017 Free Software Foundation, Inc.
+# Copyright (C) 2008-2017, 2020 Free Software Foundation, Inc.
 
 # This file is part of Autoconf.  This program is free
 # software; you can redistribute it and/or modify it under the
diff --git a/common/bison/m4sugar/m4sugar.m4 b/common/bison/m4sugar/m4sugar.m4
index bbd6958..b42fc1a 100644
--- a/common/bison/m4sugar/m4sugar.m4
+++ b/common/bison/m4sugar/m4sugar.m4
@@ -3,7 +3,7 @@
 # Base M4 layer.
 # Requires GNU M4.
 #
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017, 2020 Free Software Foundation, Inc.
 
 # This file is part of Autoconf.  This program is free
 # software; you can redistribute it and/or modify it under the
@@ -2412,6 +2412,27 @@
 [m4_strip(m4_flatten([$1]))])
 
 
+# m4_validate_w(STRING)
+# ---------------------
+# Expands into m4_normalize(m4_expand([STRING])), but if that is not
+# the same as just m4_normalize([STRING]), issue a warning.
+#
+# This is used in several Autoconf macros that take a
+# whitespace-separated list of symbols as an argument.  Ideally that
+# list would not be expanded before use, but several packages used
+# `dnl' to put comments inside those lists, so they must be expanded
+# for compatibility's sake.
+m4_define([m4_validate_w],
+[_m4_validate_w(m4_normalize([$1]), m4_normalize(m4_expand([$1])))])
+
+m4_define([_m4_validate_w],
+[m4_if([$1], [$2], [],
+  [m4_warn([obsolete], [whitespace-separated list contains macros;
+in a future version of Autoconf they will not be expanded]dnl
+m4_if(m4_bregexp([$1], [\bdn[l]\b]), -1, [], [
+note: `dn@&t@l' is a macro]))])dnl
+[$2]])
+
 
 # m4_join(SEP, ARG1, ARG2...)
 # ---------------------------
diff --git a/common/bison/skeletons/README-D.txt b/common/bison/skeletons/README-D.txt
deleted file mode 100644
index 214e309..0000000
--- a/common/bison/skeletons/README-D.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-Some usage notes for the D Parser:
-
-- it is a port of the Java parser, so interface is very similar.
-
-- the lexer class needs to implement the interface 'Lexer' (similar to
-  java). It typically (depending on options) looks like this:
-
-public interface Lexer
-{
-  /**
-   * Method to retrieve the beginning position of the last scanned token.
-   * @return the position at which the last scanned token starts.  */
-  @property YYPosition startPos ();
-
-  /**
-   * Method to retrieve the ending position of the last scanned token.
-   * @return the first position beyond the last scanned token.  */
-  @property YYPosition endPos ();
-
-  /**
-   * Method to retrieve the semantic value of the last scanned token.
-   * @return the semantic value of the last scanned token.  */
-  @property YYSemanticType semanticVal ();
-
-  /**
-   * Entry point for the scanner.  Returns the token identifier corresponding
-   * to the next token and prepares to return the semantic value
-   * and beginning/ending positions of the token.
-   * @return the token identifier corresponding to the next token. */
-  YYTokenType yylex ();
-
-  /**
-   * Entry point for error reporting.  Emits an error
-   * referring to the given location in a user-defined way.
-   *
-   * @param loc The location of the element to which the
-   *                error message is related
-   * @param s The string for the error message.  */
-   void yyerror (YYLocation loc, string s);
-}
-
-- semantic types are handled by D usions (same as for C/C++ parsers)
-
-- the following (non-standard) %defines are supported:
-
-  %define package "<package_name>"
-  %define api.parser.class "my_class_name>"
-  %define position_type "my_position_type"
-  %define location_type "my_location_type"
-
-- the following declarations basically work like in C/C++:
-
-  %locations
-  %error-verbose
-  %parse-param
-  %initial-action
-  %code
-  %union
-
-- %destructor is not yet supported
diff --git a/common/bison/skeletons/bison.m4 b/common/bison/skeletons/bison.m4
index 7ca8497..b7bf5c5 100644
--- a/common/bison/skeletons/bison.m4
+++ b/common/bison/skeletons/bison.m4
@@ -2,7 +2,7 @@
 
 # Language-independent M4 Macros for Bison.
 
-# Copyright (C) 2002, 2004-2015, 2018-2019 Free Software Foundation,
+# Copyright (C) 2002, 2004-2015, 2018-2021 Free Software Foundation,
 # Inc.
 
 # This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,30 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+
+
+# m4_gsub(STRING, RE1, SUBST1, RE2, SUBST2, ...)
+# ----------------------------------------------
+# m4 equivalent of
+#
+#   $_ = STRING;
+#   s/RE1/SUBST1/g;
+#   s/RE2/SUBST2/g;
+#   ...
+#
+# Really similar to m4_bpatsubsts, but behaves properly with quotes.
+# See m4.at's "Generating Comments".  Super inelegant, but so far, I
+# did not find any better solution.
+m4_define([b4_gsub],
+[m4_bpatsubst(m4_bpatsubst(m4_bpatsubst([[[[$1]]]],
+                                        [$2], [$3]),
+                           [$4], [$5]),
+              [$6], [$7])])
+
+# m4_shift2 and m4_shift3 are provided by m4sugar.
+m4_define([m4_shift4], [m4_shift(m4_shift(m4_shift(m4_shift($@))))])
 
 
 ## ---------------- ##
@@ -26,7 +49,7 @@
 # b4_generated_by
 # ---------------
 m4_define([b4_generated_by],
-[b4_comment([A Bison parser, made by GNU Bison b4_version.])
+[b4_comment([A Bison parser, made by GNU Bison b4_version_string.])
 ])
 
 # b4_copyright(TITLE, [YEARS])
@@ -51,7 +74,7 @@
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.])
+along with this program.  If not, see <https://www.gnu.org/licenses/>.])
 
 b4_comment([As a special exception, you may create a larger work that contains
 part or all of the Bison parser skeleton and distribute that work
@@ -72,8 +95,9 @@
 # -------------
 # Issue a warning about private implementation details.
 m4_define([b4_disclaimer],
-[b4_comment([Undocumented macros, especially those whose name start with YY_,
-are private implementation details.  Do not rely on them.])
+[b4_comment([DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+especially those whose name start with YY_ or yy_.  They are
+private implementation details that can be changed or removed.])
 ])
 
 
@@ -161,7 +185,7 @@
 [b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
 [m4_if([$#], [4], [],
        [m4_foreach([b4_arg],
-                   m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
+                   m4_dquote(m4_shift4($@)),
                    [[@,]b4_arg])])[@)]])])
 
 # b4_warn(FORMAT, [ARG1], [ARG2], ...)
@@ -237,6 +261,13 @@
 [b4_error([[fatal]], $@)dnl
 m4_exit(1)])
 
+# b4_canary(MSG)
+# --------------
+# Issue a warning on stderr and in the output.  Used in the test suite
+# to catch spurious m4 evaluations.
+m4_define([b4_canary],
+[m4_errprintn([dead canary: $1])DEAD CANARY($1)])
+
 
 ## ------------ ##
 ## Data Types.  ##
@@ -308,14 +339,14 @@
 $1([check], [b4_check])
 
 $1([stos], [b4_stos],
-   [[YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-symbol of state STATE-NUM.]])
+   [[YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+state STATE-NUM.]])
 
 $1([r1], [b4_r1],
-   [[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]])
+   [[YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.]])
 
 $1([r2], [b4_r2],
-   [[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]])
+   [[YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.]])
 ])
 
 
@@ -367,8 +398,9 @@
 # b4_FLAG_if(IF-TRUE, IF-FALSE)
 # -----------------------------
 # Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
-b4_define_flag_if([defines])            # Whether headers are requested.
 b4_define_flag_if([glr])                # Whether a GLR parser is requested.
+b4_define_flag_if([has_translations])   # Whether some tokens are internationalized.
+b4_define_flag_if([header])             # Whether a header is requested.
 b4_define_flag_if([nondeterministic])   # Whether conflicts should be handled.
 b4_define_flag_if([token_table])        # Whether yytoken_table is demanded.
 b4_define_flag_if([yacc])               # Whether POSIX Yacc is emulated.
@@ -379,43 +411,100 @@
 m4_define([b4_glr_cc_if],
           [m4_if(b4_skeleton, ["glr.cc"], $@)])
 
+# b4_glr2_cc_if([IF-TRUE], [IF-FALSE])
+# ------------------------------------
+m4_define([b4_glr2_cc_if],
+          [m4_if(b4_skeleton, ["glr2.cc"], $@)])
 
 ## --------- ##
 ## Symbols.  ##
 ## --------- ##
 
-# For a description of the Symbol handling, see README.
+# For a description of the Symbol handling, see README.md.
 #
 # The following macros provide access to symbol related values.
 
 # __b4_symbol(NUM, FIELD)
 # -----------------------
-# Recover a FIELD about symbol #NUM.  Thanks to m4_indir, fails if
-# undefined.
+# Fetch FIELD of symbol #NUM.  Fail if undefined.
 m4_define([__b4_symbol],
 [m4_indir([b4_symbol($1, $2)])])
 
 
 # _b4_symbol(NUM, FIELD)
 # ----------------------
-# Recover a FIELD about symbol #NUM (or "orig NUM").  Fails if
-# undefined.
+# Fetch FIELD of symbol #NUM (or "orig NUM", see README.md).
+# Fail if undefined.
 m4_define([_b4_symbol],
 [m4_ifdef([b4_symbol($1, number)],
           [__b4_symbol(m4_indir([b4_symbol($1, number)]), $2)],
           [__b4_symbol([$1], [$2])])])
 
 
+# b4_symbol_token_kind(NUM)
+# -------------------------
+# The token kind of this symbol.
+m4_define([b4_symbol_token_kind],
+[b4_percent_define_get([api.token.prefix])dnl
+_b4_symbol([$1], [id])])
+
+
+# b4_symbol_kind_base(NUM)
+# ------------------------
+# Build the name of the kind of this symbol.  It must always exist,
+# otherwise some symbols might not be represented in the enum, which
+# might be compiled into too small a type to contain all the symbol
+# numbers.
+m4_define([b4_symbol_prefix], [b4_percent_define_get([api.symbol.prefix])])
+m4_define([b4_symbol_kind_base],
+[b4_percent_define_get([api.symbol.prefix])dnl
+m4_case([$1],
+  [-2],                             [[YYEMPTY]],
+  [0],                              [[YYEOF]],
+  [1],                              [[YYerror]],
+  [2],                              [[YYUNDEF]],
+  [m4_case(b4_symbol([$1], [tag]),
+      [$accept],                    [[YYACCEPT]],
+      [b4_symbol_if([$1], [has_id], _b4_symbol([$1], [id]),
+                                    [m4_bpatsubst([$1-][]_b4_symbol([$1], [tag]), [[^a-zA-Z_0-9]+], [_])])])])])
+
+
+# b4_symbol_kind(NUM)
+# -------------------
+# Same as b4_symbol_kind, but possibly with a prefix in some
+# languages.  E.g., EOF's kind_base and kind are YYSYMBOL_YYEOF in C,
+# but are S_YYEMPTY and symbol_kind::S_YYEMPTY in C++.
+m4_copy([b4_symbol_kind_base], [b4_symbol_kind])
+
+
+# b4_symbol_slot(NUM)
+# -------------------
+# The name of union member that contains the value of these symbols.
+# Currently, we are messy, this should actually be type_tag, but type_tag
+# has several meanings.
+m4_define([b4_symbol_slot],
+[m4_case(b4_percent_define_get([[api.value.type]]),
+         [union],   [b4_symbol([$1], [type_tag])],
+         [variant], [b4_symbol([$1], [type_tag])],
+         [b4_symbol([$1], [type])])])
+
 
 # b4_symbol(NUM, FIELD)
 # ---------------------
-# Recover a FIELD about symbol #NUM (or "orig NUM").  Fails if
-# undefined.  If FIELD = id, prepend the token prefix.
+# Fetch FIELD of symbol #NUM (or "orig NUM", or "empty").  Fail if undefined.
+#
+# If FIELD = id, prepend the token prefix.
 m4_define([b4_symbol],
-[m4_case([$2],
-         [id],    [m4_do([b4_percent_define_get([api.token.prefix])],
-                         [_b4_symbol([$1], [id])])],
-         [_b4_symbol($@)])])
+[m4_if([$1], [empty], [b4_symbol([-2], [$2])],
+       [$1], [eof],   [b4_symbol([0], [$2])],
+       [$1], [error], [b4_symbol([1], [$2])],
+       [$1], [undef], [b4_symbol([2], [$2])],
+       [m4_case([$2],
+                [id],        [b4_symbol_token_kind([$1])],
+                [kind_base], [b4_symbol_kind_base([$1])],
+                [kind],      [b4_symbol_kind([$1])],
+                [slot],      [b4_symbol_slot([$1])],
+                [_b4_symbol($@)])])])
 
 
 # b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
@@ -437,9 +526,9 @@
 ])
 
 
-# b4_symbol_action(SYMBOL-NUM, KIND)
-# ----------------------------------
-# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# b4_symbol_action(SYMBOL-NUM, ACTION)
+# ------------------------------------
+# Run the action ACTION ("destructor" or "printer") for SYMBOL-NUM.
 m4_define([b4_symbol_action],
 [b4_symbol_if([$1], [has_$2],
 [b4_dollar_pushdef([(*yyvaluep)],
@@ -463,21 +552,21 @@
 m4_define([b4_symbol_printer],    [b4_symbol_action([$1], [printer])])
 
 
-# b4_symbol_actions(KIND, [TYPE = yytype])
-# ----------------------------------------
-# Emit the symbol actions for KIND ("printer" or "destructor").
-# Dispatch on TYPE.
+# b4_symbol_actions(ACTION, [KIND = yykind])
+# ------------------------------------------
+# Emit the symbol actions for ACTION ("destructor" or "printer").
+# Dispatch on KIND.
 m4_define([b4_symbol_actions],
 [m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl
 m4_ifval(m4_defn([b4_actions_]),
-[switch (m4_default([$2], [yytype]))
+[switch (m4_default([$2], [yykind]))
     {
 m4_defn([b4_actions_])[]dnl
       default:
         break;
     }dnl
 ],
-[YYUSE (m4_default([$2], [yytype]));])dnl
+[b4_use(m4_default([$2], [yykind]));])dnl
 m4_popdef([b4_actions_])dnl
 ])
 
@@ -487,7 +576,7 @@
 # easier to use with m4_map, but then, use []dnl to suppress the last
 # one.
 m4_define([_b4_symbol_case],
-[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])])
+[case b4_symbol([$1], [kind]): b4_symbol_tag_comment([$1])])
 ])
 
 
@@ -507,13 +596,14 @@
 
 # b4_token_visible_if(NUM, IF-TRUE, IF-FALSE)
 # -------------------------------------------
-# Whether NUM denotes a token that has an exported definition (i.e.,
-# shows in enum yytokentype).
+# Whether NUM denotes a token kind that has an exported definition
+# (i.e., shows in enum yytokentype).
 m4_define([b4_token_visible_if],
 [b4_symbol_if([$1], [is_token],
               [b4_symbol_if([$1], [has_id], [$2], [$3])],
               [$3])])
 
+
 # b4_token_has_definition(NUM)
 # ----------------------------
 # 1 if NUM is visible, nothing otherwise.
@@ -530,13 +620,27 @@
 
 # b4_token_format(FORMAT, NUM)
 # ----------------------------
+# If token NUM has a visible ID, format FORMAT with ID, USER_NUMBER.
 m4_define([b4_token_format],
 [b4_token_visible_if([$2],
-[m4_quote(m4_format([$1],
-                     [b4_symbol([$2], [id])],
-                     [b4_symbol([$2], b4_api_token_raw_if([[number]], [[user_number]]))]))])])
+[m4_format([[$1]],
+           b4_symbol([$2], [id]),
+           b4_symbol([$2], b4_api_token_raw_if([[number]], [[code]])))])])
 
 
+# b4_last_enum_token
+# ------------------
+# The code of the last token visible token.
+m4_define([_b4_last_enum_token],
+[b4_token_visible_if([$1],
+   [m4_define([b4_last_enum_token], [$1])])])
+b4_symbol_foreach([_b4_last_enum_token])
+
+# b4_last_symbol
+# --------------
+# The code of the last symbol.
+m4_define([b4_last_symbol], m4_eval(b4_tokens_number + b4_nterms_number - 1))
+
 ## ------- ##
 ## Types.  ##
 ## ------- ##
@@ -558,11 +662,11 @@
 
 ])])
 
-# b4_type_foreach(MACRO)
-# ----------------------
+# b4_type_foreach(MACRO, [SEP])
+# -----------------------------
 # Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set.
 m4_define([b4_type_foreach],
-          [m4_map([$1], m4_defn([b4_type_names]))])
+          [m4_map_sep([$1], [$2], m4_defn([b4_type_names]))])
 
 
 
@@ -603,7 +707,7 @@
 # This generates dependencies on the Bison skeletons hence lots of
 # useless 'git diff'.  This location is useless for the regular
 # user (who does not care about the skeletons) and is actually not
-# useful for Bison developpers too (I, Akim, never used this to locate
+# useful for Bison developers too (I, Akim, never used this to locate
 # the code in skeletons that generated output).  So disable it
 # completely.  If someone thinks this was actually useful, a %define
 # variable should be provided to control the level of verbosity of
@@ -683,7 +787,7 @@
 [m4_pushdef([b4_occurrence], b4_occurrence)dnl
 m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
 m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
-m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
+m4_pushdef([b4_end], m4_shift2(b4_occurrence))dnl
 m4_ifndef($3[(]m4_quote(b4_user_name)[)],
           [b4_complain_at([b4_start], [b4_end],
                           [[%s '%s' is not used]],
@@ -878,15 +982,18 @@
 # For example:
 #
 #   b4_percent_define_default([[foo]], [[default value]])
+m4_define([_b4_percent_define_define],
+[m4_define([b4_percent_define(]$1[)], [$2])dnl
+m4_define([b4_percent_define_kind(]$1[)],
+          [m4_default([$3], [keyword])])dnl
+m4_define([b4_percent_define_loc(]$1[)],
+          [[[[<skeleton default value>:-1.-1]],
+            [[<skeleton default value>:-1.-1]]]])dnl
+m4_define([b4_percent_define_syncline(]$1[)], [[]])])
+
 m4_define([b4_percent_define_default],
 [_b4_percent_define_ifdef([$1], [],
-           [m4_define([b4_percent_define(]$1[)], [$2])dnl
-            m4_define([b4_percent_define_kind(]$1[)],
-                      [m4_default([$3], [keyword])])dnl
-            m4_define([b4_percent_define_loc(]$1[)],
-                      [[[[<skeleton default value>:-1.-1]],
-                        [[<skeleton default value>:-1.-1]]]])dnl
-            m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
+                          [_b4_percent_define_define($@)])])
 
 
 # b4_percent_define_if_define(NAME, [VARIABLE = NAME])
@@ -896,11 +1003,12 @@
 # to '_'.
 m4_define([_b4_percent_define_if_define],
 [m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
-           [b4_percent_define_flag_if(m4_default([$2], [$1]),
-                                      [$3], [$4])])])
+           [b4_percent_define_default([m4_default([$2], [$1])], [[false]])dnl
+b4_percent_define_flag_if(m4_default([$2], [$1]),
+                                     [$3], [$4])])])
+
 m4_define([b4_percent_define_if_define],
-[b4_percent_define_default([m4_default([$2], [$1])], [[false]])
-_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
+[_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
 
 
 # b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
@@ -1006,6 +1114,7 @@
 b4_percent_define_if_define([locations])     # Whether locations are tracked.
 b4_percent_define_if_define([parse.assert])
 b4_percent_define_if_define([parse.trace])
+b4_percent_define_if_define([posix])
 
 
 # b4_bison_locations_if([IF-TRUE])
@@ -1016,31 +1125,37 @@
 [b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [], [$1])])])
 
 
-# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT])
+
+# %define parse.error "(custom|detailed|simple|verbose)"
 # ------------------------------------------------------
-# Map %define parse.error "(simple|verbose)" to b4_error_verbose_if and
-# b4_error_verbose_flag.
 b4_percent_define_default([[parse.error]], [[simple]])
 b4_percent_define_check_values([[[[parse.error]],
-                                 [[simple]], [[verbose]]]])
-m4_define([b4_error_verbose_flag],
-          [m4_case(b4_percent_define_get([[parse.error]]),
-                   [simple],  [[0]],
-                   [verbose], [[1]])])
-b4_define_flag_if([error_verbose])
+                                 [[custom]], [[detailed]], [[simple]], [[verbose]]]])
 
-# yytoken_table is needed to support verbose errors.
-b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
+# b4_parse_error_case(CASE1, THEN1, CASE2, THEN2, ..., ELSE)
+# ----------------------------------------------------------
+m4_define([b4_parse_error_case],
+[m4_case(b4_percent_define_get([[parse.error]]), $@)])
+
+# b4_parse_error_bmatch(PATTERN1, THEN1, PATTERN2, THEN2, ..., ELSE)
+# ------------------------------------------------------------------
+m4_define([b4_parse_error_bmatch],
+[m4_bmatch(b4_percent_define_get([[parse.error]]), $@)])
 
 
+
+# b4_union_if([IF-UNION-ARE-USED], [IF-NOT])
 # b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
 # ----------------------------------------------
-b4_percent_define_if_define([variant])
+# Depend on whether api.value.type is union, or variant.
+m4_define([b4_union_flag],   [[0]])
 m4_define([b4_variant_flag], [[0]])
 b4_percent_define_ifdef([[api.value.type]],
    [m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
-            [m4_case(b4_percent_define_get([[api.value.type]]), [variant],
-                    [m4_define([b4_variant_flag], [[1]])])])])
+            [m4_case(b4_percent_define_get([[api.value.type]]),
+                     [union],   [m4_define([b4_union_flag],   [[1]])],
+                     [variant], [m4_define([b4_variant_flag], [[1]])])])])
+b4_define_flag_if([union])
 b4_define_flag_if([variant])
 
 
@@ -1116,3 +1231,11 @@
 
 # api.value.union.name.
 b4_percent_define_check_kind([api.value.union.name], [keyword])
+
+# parse.error (custom|detailed) >< token-table.
+b4_token_table_if(
+[b4_parse_error_bmatch([custom\|detailed],
+[b4_complain_at(b4_percent_define_get_loc([parse.error]),
+                [['%s' and '%s' cannot be used together]],
+                [%token-table],
+                [%define parse.error (custom|detailed)])])])
diff --git a/common/bison/skeletons/c++-skel.m4 b/common/bison/skeletons/c++-skel.m4
index 1c3721c..f22002b 100644
--- a/common/bison/skeletons/c++-skel.m4
+++ b/common/bison/skeletons/c++-skel.m4
@@ -2,7 +2,7 @@
 
 # C++ skeleton dispatching for Bison.
 
-# Copyright (C) 2006-2007, 2009-2015, 2018-2019 Free Software
+# Copyright (C) 2006-2007, 2009-2015, 2018-2021 Free Software
 # Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 b4_glr_if(             [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])])
 b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])])
diff --git a/common/bison/skeletons/c++.m4 b/common/bison/skeletons/c++.m4
index 3e2e4df..2ae8423 100644
--- a/common/bison/skeletons/c++.m4
+++ b/common/bison/skeletons/c++.m4
@@ -2,7 +2,7 @@
 
 # C++ skeleton for Bison
 
-# Copyright (C) 2002-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,13 +15,15 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # Sanity checks, before defaults installed by c.m4.
 b4_percent_define_ifdef([[api.value.union.name]],
   [b4_complain_at(b4_percent_define_get_loc([[api.value.union.name]]),
                   [named %union is invalid in C++])])
 
+b4_percent_define_default([[api.symbol.prefix]], [[S_]])
+
 m4_include(b4_skeletonsdir/[c.m4])
 
 b4_percent_define_check_kind([api.namespace], [code], [deprecated])
@@ -103,11 +105,10 @@
 #
 # b4_percent_define_default([[api.location.type]], [[location]])
 
-b4_percent_define_default([[filename_type]], [[std::string]])
+b4_percent_define_default([[api.filename.type]], [[const std::string]])
 # Make it a warning for those who used betas of Bison 3.0.
 b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
 
-b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
 b4_percent_define_default([[define_location_comparison]],
                           [m4_if(b4_percent_define_get([[filename_type]]),
                                  [std::string], [[true]], [[false]])])
@@ -160,20 +161,42 @@
              [::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])])
 
 
+## ------------- ##
+## Token kinds.  ##
+## ------------- ##
+
+
 # b4_token_enums
 # --------------
-# Output the definition of the tokens as enums.
+# Output the definition of the token kinds.
 m4_define([b4_token_enums],
-[[enum yytokentype
+[[enum token_kind_type
       {
-        ]m4_join([,
-        ],
-                 b4_symbol_map([b4_token_enum]))[
-      };]dnl
+        ]b4_symbol([-2], [id])[ = -2,
+]b4_symbol_foreach([b4_token_enum])dnl
+[      };]dnl
 ])
 
 
 
+## -------------- ##
+## Symbol kinds.  ##
+## -------------- ##
+
+# b4_declare_symbol_enum
+# ----------------------
+# The definition of the symbol internal numbers as an enum.
+# Defining YYEMPTY here is important: it forces the compiler
+# to use a signed type, which matters for yytoken.
+m4_define([b4_declare_symbol_enum],
+[[enum symbol_kind_type
+      {
+        YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
+        ]b4_symbol(empty, kind_base)[ = -2,
+]b4_symbol_foreach([      b4_symbol_enum])dnl
+[      };]])
+
+
 
 ## ----------------- ##
 ## Semantic Values.  ##
@@ -183,16 +206,16 @@
 
 # b4_value_type_declare
 # ---------------------
-# Declare semantic_type.
+# Declare value_type.
 m4_define([b4_value_type_declare],
 [b4_value_type_setup[]dnl
 [    /// Symbol semantic values.
 ]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
 [code],
-[[    typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
+[[    typedef ]b4_percent_define_get([[api.value.type]])[ value_type;]],
 [m4_bmatch(b4_percent_define_get([[api.value.type]]),
 [union\|union-directive],
-[[    union semantic_type
+[[    union value_type
     {
 ]b4_user_union_members[
     };]])])dnl
@@ -204,11 +227,19 @@
 # Define the public types: token, semantic value, location, and so forth.
 # Depending on %define token_lex, may be output in the header or source file.
 m4_define([b4_public_types_declare],
-[[#ifndef ]b4_api_PREFIX[STYPE
-]b4_value_type_declare[
+[b4_glr2_cc_if(
+[b4_value_type_declare],
+[[#ifdef ]b4_api_PREFIX[STYPE
+# ifdef __GNUC__
+#  pragma GCC message "bison: do not #define ]b4_api_PREFIX[STYPE in C++, use %define api.value.type"
+# endif
+    typedef ]b4_api_PREFIX[STYPE value_type;
 #else
-    typedef ]b4_api_PREFIX[STYPE semantic_type;
-#endif]b4_locations_if([
+]b4_value_type_declare[
+#endif
+    /// Backward compatibility (Bison 3.8).
+    typedef value_type semantic_type;
+]])[]b4_locations_if([
     /// Symbol locations.
     typedef b4_percent_define_get([[api.location.type]],
                                   [[location]]) location_type;])[
@@ -231,23 +262,31 @@
       location_type location;])[
     };
 
-    /// Tokens.
+    /// Token kinds.
     struct token
     {
-      ]b4_token_enums[
+      ]b4_token_enums[]b4_glr2_cc_if([], [[
+      /// Backward compatibility alias (Bison 3.6).
+      typedef token_kind_type yytokentype;]])[
     };
 
-    /// (External) token type, as returned by yylex.
-    typedef token::yytokentype token_type;
+    /// Token kind, as returned by yylex.
+    typedef token::token_kind_type token_kind_type;]b4_glr2_cc_if([], [[
 
-    /// Symbol type: an internal symbol number.
-    typedef int symbol_number_type;
+    /// Backward compatibility alias (Bison 3.6).
+    typedef token_kind_type token_type;]])[
 
-    /// The symbol type number to denote an empty symbol.
-    enum { empty_symbol = -2 };
+    /// Symbol kinds.
+    struct symbol_kind
+    {
+      ]b4_declare_symbol_enum[
+    };
 
-    /// Internal symbol number for tokens (subsumed by symbol_number_type).
-    typedef ]b4_int_type_for([b4_translate])[ token_number_type;
+    /// (Internal) symbol kind.
+    typedef symbol_kind::symbol_kind_type symbol_kind_type;
+
+    /// The number of tokens.
+    static const symbol_kind_type YYNTOKENS = symbol_kind::YYNTOKENS;
 ]])
 
 
@@ -258,8 +297,8 @@
 m4_define([b4_symbol_type_define],
 [[    /// A complete symbol.
     ///
-    /// Expects its Base type to provide access to the symbol type
-    /// via type_get ().
+    /// Expects its Base type to provide access to the symbol kind
+    /// via kind ().
     ///
     /// Provide access to semantic value]b4_locations_if([ and location])[.
     template <typename Base>
@@ -269,28 +308,36 @@
       typedef Base super_type;
 
       /// Default constructor.
-      basic_symbol ()
+      basic_symbol () YY_NOEXCEPT
         : value ()]b4_locations_if([
         , location ()])[
       {}
 
 #if 201103L <= YY_CPLUSPLUS
       /// Move constructor.
-      basic_symbol (basic_symbol&& that);
+      basic_symbol (basic_symbol&& that)
+        : Base (std::move (that))
+        , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([
+        , location (std::move (that.location))])[
+      {]b4_variant_if([
+        b4_symbol_variant([this->kind ()], [value], [move],
+                          [std::move (that.value)])
+      ])[}
 #endif
 
       /// Copy constructor.
       basic_symbol (const basic_symbol& that);]b4_variant_if([[
 
-      /// Constructor for valueless symbols, and symbols from each type.
-]b4_type_foreach([b4_basic_symbol_constructor_define])], [[
+      /// Constructors for typed symbols.
+]b4_type_foreach([b4_basic_symbol_constructor_define], [
+])], [[
       /// Constructor for valueless symbols.
       basic_symbol (typename Base::kind_type t]b4_locations_if([,
                     YY_MOVE_REF (location_type) l])[);
 
       /// Constructor for symbols with semantic value.
       basic_symbol (typename Base::kind_type t,
-                    YY_RVREF (semantic_type) v]b4_locations_if([,
+                    YY_RVREF (value_type) v]b4_locations_if([,
                     YY_RVREF (location_type) l])[);
 ]])[
       /// Destroy the symbol.
@@ -299,25 +346,75 @@
         clear ();
       }
 
+]b4_glr2_cc_if([[
+      /// Copy assignment.
+      basic_symbol& operator= (const basic_symbol& that)
+      {
+        Base::operator= (that);]b4_variant_if([[
+        ]b4_symbol_variant([this->kind ()], [value], [copy],
+                           [that.value])], [[
+        value = that.value]])[;]b4_locations_if([[
+        location = that.location;]])[
+        return *this;
+      }
+
+      /// Move assignment.
+      basic_symbol& operator= (basic_symbol&& that)
+      {
+        Base::operator= (std::move (that));]b4_variant_if([[
+        ]b4_symbol_variant([this->kind ()], [value], [move],
+                           [std::move (that.value)])], [[
+        value = std::move (that.value)]])[;]b4_locations_if([[
+        location = std::move (that.location);]])[
+        return *this;
+      }
+]])[
+
       /// Destroy contents, and record that is empty.
-      void clear ()
+      void clear () YY_NOEXCEPT
       {]b4_variant_if([[
         // User destructor.
-        symbol_number_type yytype = this->type_get ();
+        symbol_kind_type yykind = this->kind ();
         basic_symbol<Base>& yysym = *this;
         (void) yysym;
-        switch (yytype)
+        switch (yykind)
         {
 ]b4_symbol_foreach([b4_symbol_destructor])dnl
 [       default:
           break;
         }
 
-        // Type destructor.
-]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
+        // Value type destructor.
+]b4_symbol_variant([[yykind]], [[value]], [[template destroy]])])[
         Base::clear ();
       }
 
+]b4_parse_error_bmatch(
+[custom\|detailed],
+[[      /// The user-facing name of this symbol.
+      const char *name () const YY_NOEXCEPT
+      {
+        return ]b4_parser_class[::symbol_name (this->kind ());
+      }]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+      /// The user-facing name of this symbol.
+      const char *name () const YY_NOEXCEPT
+      {
+        return ]b4_parser_class[::symbol_name (this->kind ());
+      }
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[      /// The user-facing name of this symbol.
+      std::string name () const YY_NOEXCEPT
+      {
+        return ]b4_parser_class[::symbol_name (this->kind ());
+      }]])[]b4_glr2_cc_if([], [[
+
+      /// Backward compatibility (Bison 3.6).
+      symbol_kind_type type_get () const YY_NOEXCEPT;]])[
+
       /// Whether empty.
       bool empty () const YY_NOEXCEPT;
 
@@ -325,7 +422,7 @@
       void move (basic_symbol& s);
 
       /// The semantic value.
-      semantic_type value;]b4_locations_if([
+      value_type value;]b4_locations_if([
 
       /// The location.
       location_type location;])[
@@ -338,52 +435,65 @@
     };
 
     /// Type access provider for token (enum) based symbols.
-    struct by_type
+    struct by_kind
     {
+      /// The symbol kind as needed by the constructor.
+      typedef token_kind_type kind_type;
+
       /// Default constructor.
-      by_type ();
+      by_kind () YY_NOEXCEPT;
 
 #if 201103L <= YY_CPLUSPLUS
       /// Move constructor.
-      by_type (by_type&& that);
+      by_kind (by_kind&& that) YY_NOEXCEPT;
 #endif
 
       /// Copy constructor.
-      by_type (const by_type& that);
-
-      /// The symbol type as needed by the constructor.
-      typedef token_type kind_type;
+      by_kind (const by_kind& that) YY_NOEXCEPT;
 
       /// Constructor from (external) token numbers.
-      by_type (kind_type t);
+      by_kind (kind_type t) YY_NOEXCEPT;
+
+]b4_glr2_cc_if([[
+      /// Copy assignment.
+      by_kind& operator= (const by_kind& that);
+
+      /// Move assignment.
+      by_kind& operator= (by_kind&& that);
+]])[
 
       /// Record that this symbol is empty.
-      void clear ();
+      void clear () YY_NOEXCEPT;
 
-      /// Steal the symbol type from \a that.
-      void move (by_type& that);
+      /// Steal the symbol kind from \a that.
+      void move (by_kind& that);
 
       /// The (internal) type number (corresponding to \a type).
       /// \a empty when empty.
-      symbol_number_type type_get () const YY_NOEXCEPT;
+      symbol_kind_type kind () const YY_NOEXCEPT;]b4_glr2_cc_if([], [[
 
-      /// The symbol type.
-      /// \a empty_symbol when empty.
-      /// An int, not token_number_type, to be able to store empty_symbol.
-      int type;
-    };
+      /// Backward compatibility (Bison 3.6).
+      symbol_kind_type type_get () const YY_NOEXCEPT;]])[
+
+      /// The symbol kind.
+      /// \a ]b4_symbol_prefix[YYEMPTY when empty.
+      symbol_kind_type kind_;
+    };]b4_glr2_cc_if([], [[
+
+    /// Backward compatibility for a private implementation detail (Bison 3.6).
+    typedef by_kind by_type;]])[
 
     /// "External" symbols: returned by the scanner.
-    struct symbol_type : basic_symbol<by_type>
+    struct symbol_type : basic_symbol<by_kind>
     {]b4_variant_if([[
       /// Superclass.
-      typedef basic_symbol<by_type> super_type;
+      typedef basic_symbol<by_kind> super_type;
 
       /// Empty symbol.
-      symbol_type () {}
+      symbol_type () YY_NOEXCEPT {}
 
       /// Constructor for valueless symbols, and symbols from each type.
-]b4_type_foreach([_b4_token_constructor_define])dnl
+]b4_type_foreach([_b4_symbol_constructor_define])dnl
     ])[};
 ]])
 
@@ -393,25 +503,13 @@
 # Provide the implementation needed by the public types.
 m4_define([b4_public_types_define],
 [[  // basic_symbol.
-#if 201103L <= YY_CPLUSPLUS
-  template <typename Base>
-  ]b4_parser_class[::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
-    : Base (std::move (that))
-    , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([
-    , location (std::move (that.location))])[
-  {]b4_variant_if([
-    b4_symbol_variant([this->type_get ()], [value], [move],
-                      [std::move (that.value)])
-  ])[}
-#endif
-
   template <typename Base>
   ]b4_parser_class[::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
     : Base (that)
     , value (]b4_variant_if([], [that.value]))b4_locations_if([
     , location (that.location)])[
   {]b4_variant_if([
-    b4_symbol_variant([this->type_get ()], [value], [copy],
+    b4_symbol_variant([this->kind ()], [value], [copy],
                       [YY_MOVE (that.value)])
   ])[}
 
@@ -429,20 +527,29 @@
   template <typename Base>
   ]b4_parser_class[::basic_symbol<Base>::basic_symbol (]b4_join(
           [typename Base::kind_type t],
-          [YY_RVREF (semantic_type) v],
+          [YY_RVREF (value_type) v],
           b4_locations_if([YY_RVREF (location_type) l]))[)
     : Base (t)
     , value (]b4_variant_if([], [YY_MOVE (v)])[)]b4_locations_if([
     , location (YY_MOVE (l))])[
   {]b4_variant_if([[
     (void) v;
-    ]b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[
+    ]b4_symbol_variant([this->kind ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[
+
+]b4_glr2_cc_if([], [[
+  template <typename Base>
+  ]b4_parser_class[::symbol_kind_type
+  ]b4_parser_class[::basic_symbol<Base>::type_get () const YY_NOEXCEPT
+  {
+    return this->kind ();
+  }
+]])[
 
   template <typename Base>
   bool
   ]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
   {
-    return Base::type_get () == empty_symbol;
+    return this->kind () == ]b4_symbol(empty, kind)[;
   }
 
   template <typename Base>
@@ -450,57 +557,82 @@
   ]b4_parser_class[::basic_symbol<Base>::move (basic_symbol& s)
   {
     super_type::move (s);
-    ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move],
+    ]b4_variant_if([b4_symbol_variant([this->kind ()], [value], [move],
                                       [YY_MOVE (s.value)])],
                    [value = YY_MOVE (s.value);])[]b4_locations_if([
     location = YY_MOVE (s.location);])[
   }
 
-  // by_type.
-  ]b4_inline([$1])b4_parser_class[::by_type::by_type ()
-    : type (empty_symbol)
+  // by_kind.
+  ]b4_inline([$1])b4_parser_class[::by_kind::by_kind () YY_NOEXCEPT
+    : kind_ (]b4_symbol(empty, kind)[)
   {}
 
 #if 201103L <= YY_CPLUSPLUS
-  ]b4_inline([$1])b4_parser_class[::by_type::by_type (by_type&& that)
-    : type (that.type)
+  ]b4_inline([$1])b4_parser_class[::by_kind::by_kind (by_kind&& that) YY_NOEXCEPT
+    : kind_ (that.kind_)
   {
     that.clear ();
   }
 #endif
 
-  ]b4_inline([$1])b4_parser_class[::by_type::by_type (const by_type& that)
-    : type (that.type)
+  ]b4_inline([$1])b4_parser_class[::by_kind::by_kind (const by_kind& that) YY_NOEXCEPT
+    : kind_ (that.kind_)
   {}
 
-  ]b4_inline([$1])b4_parser_class[::by_type::by_type (token_type t)
-    : type (yytranslate_ (t))
+  ]b4_inline([$1])b4_parser_class[::by_kind::by_kind (token_kind_type t) YY_NOEXCEPT
+    : kind_ (yytranslate_ (t))
   {}
 
+]b4_glr2_cc_if([[
+  ]b4_inline([$1])]b4_parser_class[::by_kind&
+  b4_parser_class[::by_kind::by_kind::operator= (const by_kind& that)
+  {
+    kind_ = that.kind_;
+    return *this;
+  }
+
+  ]b4_inline([$1])]b4_parser_class[::by_kind&
+  b4_parser_class[::by_kind::by_kind::operator= (by_kind&& that)
+  {
+    kind_ = that.kind_;
+    that.clear ();
+    return *this;
+  }
+]])[
+
   ]b4_inline([$1])[void
-  ]b4_parser_class[::by_type::clear ()
+  ]b4_parser_class[::by_kind::clear () YY_NOEXCEPT
   {
-    type = empty_symbol;
+    kind_ = ]b4_symbol(empty, kind)[;
   }
 
   ]b4_inline([$1])[void
-  ]b4_parser_class[::by_type::move (by_type& that)
+  ]b4_parser_class[::by_kind::move (by_kind& that)
   {
-    type = that.type;
+    kind_ = that.kind_;
     that.clear ();
   }
 
-  ]b4_inline([$1])[int
-  ]b4_parser_class[::by_type::type_get () const YY_NOEXCEPT
+  ]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
+  ]b4_parser_class[::by_kind::kind () const YY_NOEXCEPT
   {
-    return type;
+    return kind_;
   }
+
+]b4_glr2_cc_if([], [[
+  ]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
+  ]b4_parser_class[::by_kind::type_get () const YY_NOEXCEPT
+  {
+    return this->kind ();
+  }
+]])[
 ]])
 
 
 # b4_token_constructor_define
 # ----------------------------
-# Define symbol constructors for all the value types.
+# Define make_FOO for all the token kinds.
 # Use at class-level.  Redefined in variant.hh.
 m4_define([b4_token_constructor_define], [])
 
@@ -510,27 +642,28 @@
 # Define yytranslate_.  Sometimes used in the header file ($1=hh),
 # sometimes in the cc file.
 m4_define([b4_yytranslate_define],
-[  b4_inline([$1])b4_parser_class[::token_number_type
-  ]b4_parser_class[::yytranslate_ (int t)
+[  b4_inline([$1])b4_parser_class[::symbol_kind_type
+  ]b4_parser_class[::yytranslate_ (int t) YY_NOEXCEPT
   {
 ]b4_api_token_raw_if(
-[[    return static_cast<token_number_type> (t);]],
+[[    return static_cast<symbol_kind_type> (t);]],
 [[    // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
     // TOKEN-NUM as returned by yylex.
     static
-    const token_number_type
+    const ]b4_int_type_for([b4_translate])[
     translate_table[] =
     {
   ]b4_translate[
     };
-    const int user_token_number_max_ = ]b4_user_token_number_max[;
+    // Last valid token kind.
+    const int code_max = ]b4_code_max[;
 
     if (t <= 0)
-      return yyeof_;
-    else if (t <= user_token_number_max_)
-      return translate_table[t];
+      return symbol_kind::]b4_symbol_prefix[YYEOF;
+    else if (t <= code_max)
+      return static_cast <symbol_kind_type> (translate_table[t]);
     else
-      return yy_undef_token_;]])[
+      return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
   }
 ]])
 
diff --git a/common/bison/skeletons/c-like.m4 b/common/bison/skeletons/c-like.m4
index 8d891b6..a9bbc2e 100644
--- a/common/bison/skeletons/c-like.m4
+++ b/common/bison/skeletons/c-like.m4
@@ -2,7 +2,7 @@
 
 # Common code for C-like languages (C, C++, Java, etc.)
 
-# Copyright (C) 2012-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2012-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,17 +15,23 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
 
 # _b4_comment(TEXT, OPEN, CONTINUE, END)
 # --------------------------------------
 # Put TEXT in comment.  Avoid trailing spaces: don't indent empty lines.
 # Avoid adding indentation to the first line, as the indentation comes
 # from OPEN.  That's why we don't patsubst([$1], [^\(.\)], [   \1]).
+# Turn "*/" in TEXT into "* /" so that we don't unexpectedly close
+# the comments before its end.
 #
 # Prefix all the output lines with PREFIX.
 m4_define([_b4_comment],
-[$2[]m4_bpatsubst(m4_expand([[$1]]), [
+[$2[]b4_gsub(m4_expand([$1]),
+            [[*]/], [*\\/],
+            [/[*]], [/\\*],
+            [
 \(.\)], [
 $3\1])$4])
 
diff --git a/common/bison/skeletons/c-skel.m4 b/common/bison/skeletons/c-skel.m4
index 2a21cfc..ac6ddd6 100644
--- a/common/bison/skeletons/c-skel.m4
+++ b/common/bison/skeletons/c-skel.m4
@@ -2,7 +2,7 @@
 
 # C skeleton dispatching for Bison.
 
-# Copyright (C) 2006-2007, 2009-2015, 2018-2019 Free Software
+# Copyright (C) 2006-2007, 2009-2015, 2018-2021 Free Software
 # Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 b4_glr_if(             [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])])
 b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])])
diff --git a/common/bison/skeletons/c.m4 b/common/bison/skeletons/c.m4
index 4b2c094..2425b07 100644
--- a/common/bison/skeletons/c.m4
+++ b/common/bison/skeletons/c.m4
@@ -2,7 +2,7 @@
 
 # C M4 Macros for Bison.
 
-# Copyright (C) 2002, 2004-2015, 2018-2019 Free Software Foundation,
+# Copyright (C) 2002, 2004-2015, 2018-2021 Free Software Foundation,
 # Inc.
 
 # This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_include(b4_skeletonsdir/[c-like.m4])
 
@@ -58,11 +58,11 @@
 # b4_pull_flag if they use the values of the %define variables api.pure or
 # api.push-pull.
 m4_define([b4_identification],
-[[/* Identify Bison output.  */
-#define YYBISON 1
+[[/* Identify Bison output, and Bison version.  */
+#define YYBISON ]b4_version[
 
-/* Bison version.  */
-#define YYBISON_VERSION "]b4_version["
+/* Bison version string.  */
+#define YYBISON_VERSION "]b4_version_string["
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME ]b4_skeleton[]m4_ifdef([b4_pure_flag], [[
@@ -101,32 +101,45 @@
 b4_percent_define_default([[api.value.union.name]],
                           [b4_api_PREFIX[][STYPE]])
 
+b4_percent_define_default([[api.symbol.prefix]], [[YYSYMBOL_]])
 
 ## ------------------------ ##
 ## Pure/impure interfaces.  ##
 ## ------------------------ ##
 
-# b4_lex_formals
-# --------------
+# b4_yylex_formals
+# ----------------
 # All the yylex formal arguments.
 # b4_lex_param arrives quoted twice, but we want to keep only one level.
-m4_define([b4_lex_formals],
-[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl
-b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl
+m4_define([b4_yylex_formals],
+[b4_pure_if([[[b4_api_PREFIX[STYPE *yylvalp]], [[&yylval]]][]dnl
+b4_locations_if([, [b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])])dnl
 m4_ifdef([b4_lex_param], [, ]b4_lex_param)])
 
 
-# b4_lex
-# ------
+# b4_yylex
+# --------
 # Call yylex.
-m4_define([b4_lex],
-[b4_function_call([yylex], [int], b4_lex_formals)])
+m4_define([b4_yylex],
+[b4_function_call([yylex], [int], b4_yylex_formals)])
 
 
 # b4_user_args
 # ------------
 m4_define([b4_user_args],
-[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])])
+[m4_ifset([b4_parse_param], [, b4_user_args_no_comma])])
+
+# b4_user_args_no_comma
+# ---------------------
+m4_define([b4_user_args_no_comma],
+[m4_ifset([b4_parse_param], [b4_args(b4_parse_param)])])
+
+
+# b4_user_formals
+# ---------------
+# The possible parse-params formal arguments preceded by a comma.
+m4_define([b4_user_formals],
+[m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])])
 
 
 # b4_parse_param
@@ -150,13 +163,20 @@
 m4_popdef([$1])dnl
 ])])
 
+
+# b4_use(EXPR)
+# ------------
+# Pacify the compiler about some maybe unused value.
+m4_define([b4_use],
+[YY_USE ($1)])
+
 # b4_parse_param_use([VAL], [LOC])
 # --------------------------------
-# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
+# 'YY_USE' VAL, LOC if locations are enabled, and all the parse-params.
 m4_define([b4_parse_param_use],
-[m4_ifvaln([$1], [  YYUSE ([$1]);])dnl
-b4_locations_if([m4_ifvaln([$2], [  YYUSE ([$2]);])])dnl
-b4_parse_param_for([Decl], [Formal], [  YYUSE (Formal);
+[m4_ifvaln([$1], [  b4_use([$1]);])dnl
+b4_locations_if([m4_ifvaln([$2], [  b4_use([$2]);])])dnl
+b4_parse_param_for([Decl], [Formal], [  b4_use(Formal);
 ])dnl
 ])
 
@@ -197,7 +217,11 @@
 # Define private types suitable for holding small integers in C99 or later.
 m4_define([b4_c99_int_type_define],
 [m4_copy_force([b4_c99_int_type], [b4_int_type])dnl
-[/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+[#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
    <limits.h> and (if available) <stdint.h> are included
    so that the code can choose integer types of a good width.  */
 
@@ -230,6 +254,18 @@
 typedef short yytype_int16;
 #endif
 
+/* Work around bug in HP-UX 11.23, which defines these macros
+   incorrectly for preprocessor constants.  This workaround can likely
+   be removed in 2023, as HPE has promised support for HP-UX 11.23
+   (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+   <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>.  */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
 #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
 typedef __UINT_LEAST8_TYPE__ yytype_uint8;
 #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
@@ -253,6 +289,50 @@
 #endif]])
 
 
+# b4_sizes_types_define
+# ---------------------
+# Define YYPTRDIFF_T/YYPTRDIFF_MAXIMUM, YYSIZE_T/YYSIZE_MAXIMUM,
+# and YYSIZEOF.
+m4_define([b4_sizes_types_define],
+[[#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+#  define YYPTRDIFF_T __PTRDIFF_TYPE__
+#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+#  ifndef ptrdiff_t
+#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  endif
+#  define YYPTRDIFF_T ptrdiff_t
+#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+#  define YYPTRDIFF_T long
+#  define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM                                  \
+  YY_CAST (YYPTRDIFF_T,                                 \
+           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
+            ? YYPTRDIFF_MAXIMUM                         \
+            : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+]])
+
+
 # b4_int_type_for(NAME)
 # ---------------------
 # Return a narrow int type able to handle numbers ranging from
@@ -299,17 +379,27 @@
 #endif
 
 ]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11.  */
-]dnl This is an exact copy of lib/_Noreturn.h.
+]dnl This is close to lib/_Noreturn.h, except that we do enable
+dnl the use of [[noreturn]], because _Noreturn is used in places
+dnl where [[noreturn]] works in C++.  We need this in particular
+dnl because of glr.cc which compiles code from glr.c in C++.
+dnl And the C++ compiler chokes on _Noreturn.  Also, we do not
+dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
 [#ifndef _Noreturn
 # if (defined __cplusplus \
       && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
           || (defined _MSC_VER && 1900 <= _MSC_VER)))
 #  define _Noreturn [[noreturn]]
 # elif ((!defined __cplusplus || defined __clang__) \
-        && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0)  \
-            || 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
+        && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
+            || (!defined __STRICT_ANSI__ \
+                && (4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
+                    || (defined __apple_build_version__ \
+                        ? 6000000 <= __apple_build_version__ \
+                        : 3 < __clang_major__ + (5 <= __clang_minor__))))))
    /* _Noreturn works as-is.  */
-# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
+# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \
+        || 0x5110 <= __SUNPRO_C)
 #  define _Noreturn __attribute__ ((__noreturn__))
 # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
 #  define _Noreturn __declspec (noreturn)
@@ -320,17 +410,23 @@
 
 ]])[/* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
+# define YY_USE(E) ((void) (E))
 #else
-# define YYUSE(E) /* empty */
+# define YY_USE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                            \
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
+    _Pragma ("GCC diagnostic push")                                     \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
     _Pragma ("GCC diagnostic push")                                     \
     _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
     _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
 # define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
     _Pragma ("GCC diagnostic pop")
 #else
@@ -410,7 +506,7 @@
 # -------------------------------------------------------------
 # Define "yy<TABLE-NAME>" whose contents is CONTENT.
 m4_define([b4_integral_parser_table_define],
-[m4_ifvaln([$3], [b4_comment([$3], [  ])])dnl
+[m4_ifvaln([$3], [b4_comment([$3])])dnl
 static const b4_int_type_for([$2]) yy$1[[]] =
 {
   $2
@@ -418,9 +514,22 @@
 ])
 
 
-## ------------------------- ##
-## Assigning token numbers.  ##
-## ------------------------- ##
+## ------------- ##
+## Token kinds.  ##
+## ------------- ##
+
+# Because C enums are not scoped, because tokens are exposed in the
+# header, and because these tokens are common to all the parsers, we
+# need to make sure their names don't collide: use the api.prefix.
+# YYEOF is special, since the user may give it a different name.
+m4_define([b4_symbol(-2, id)],  [b4_api_PREFIX[][EMPTY]])
+m4_define([b4_symbol(-2, tag)], [[No symbol.]])
+
+m4_if(b4_symbol(eof, id), [YYEOF],
+     [m4_define([b4_symbol(0, id)],  [b4_api_PREFIX[][EOF]])])
+m4_define([b4_symbol(1, id)],  [b4_api_PREFIX[][error]])
+m4_define([b4_symbol(2, id)],  [b4_api_PREFIX[][UNDEF]])
+
 
 # b4_token_define(TOKEN-NUM)
 # --------------------------
@@ -432,44 +541,92 @@
 # ----------------
 # Output the definition of the tokens.
 m4_define([b4_token_defines],
-[b4_any_token_visible_if([/* Tokens.  */
-m4_join([
+[[/* Token kinds.  */
+#define ]b4_symbol(empty, [id])[ -2
+]m4_join([
 ], b4_symbol_map([b4_token_define]))
-])])
+])
 
 
 # b4_token_enum(TOKEN-NUM)
 # ------------------------
 # Output the definition of this token as an enum.
 m4_define([b4_token_enum],
-[b4_token_format([%s = %s], [$1])])
+[b4_token_visible_if([$1],
+    [m4_format([    %-30s %s],
+               m4_format([[%s = %s%s%s]],
+                         b4_symbol([$1], [id]),
+                         b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])),
+                         m4_if([$1], b4_last_enum_token, [], [[,]])),
+               [b4_symbol_tag_comment([$1])])])])
 
 
 # b4_token_enums
 # --------------
-# Output the definition of the tokens (if there are) as enums.
+# The definition of the token kinds.
 m4_define([b4_token_enums],
-[b4_any_token_visible_if([[/* Token type.  */
+[b4_any_token_visible_if([[/* Token kinds.  */
 #ifndef ]b4_api_PREFIX[TOKENTYPE
 # define ]b4_api_PREFIX[TOKENTYPE
   enum ]b4_api_prefix[tokentype
   {
-    ]m4_join([,
-    ],
-             b4_symbol_map([b4_token_enum]))[
-  };
+    ]b4_symbol(empty, [id])[ = -2,
+]b4_symbol_foreach([b4_token_enum])dnl
+[  };
+  typedef enum ]b4_api_prefix[tokentype ]b4_api_prefix[token_kind_t;
 #endif
 ]])])
 
 
 # b4_token_enums_defines
 # ----------------------
-# Output the definition of the tokens (if there are any) as enums and,
+# The definition of the tokens (if there are any) as enums and,
 # if POSIX Yacc is enabled, as #defines.
 m4_define([b4_token_enums_defines],
 [b4_token_enums[]b4_yacc_if([b4_token_defines])])
 
 
+# b4_symbol_translate(STRING)
+# ---------------------------
+# Used by "bison" in the array of symbol names to mark those that
+# require translation.
+m4_define([b4_symbol_translate],
+[[N_($1)]])
+
+
+
+## -------------- ##
+## Symbol kinds.  ##
+## -------------- ##
+
+# b4_symbol_enum(SYMBOL-NUM)
+# --------------------------
+# Output the definition of this symbol as an enum.
+m4_define([b4_symbol_enum],
+[m4_format([  %-40s %s],
+           m4_format([[%s = %s%s%s]],
+                     b4_symbol([$1], [kind_base]),
+                     [$1],
+                     m4_if([$1], b4_last_symbol, [], [[,]])),
+           [b4_symbol_tag_comment([$1])])])
+
+
+# b4_declare_symbol_enum
+# ----------------------
+# The definition of the symbol internal numbers as an enum.
+# Defining YYEMPTY here is important: it forces the compiler
+# to use a signed type, which matters for yytoken.
+m4_define([b4_declare_symbol_enum],
+[[/* Symbol kind.  */
+enum yysymbol_kind_t
+{
+  ]b4_symbol(empty, [kind_base])[ = -2,
+]b4_symbol_foreach([b4_symbol_enum])dnl
+[};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+]])])
+
+
 ## ----------------- ##
 ## Semantic Values.  ##
 ## ----------------- ##
@@ -493,15 +650,6 @@
 ## ---------------------- ##
 
 
-# b4_function_define(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
-# -----------------------------------------------------------
-# Declare the function NAME in C.
-m4_define([b4_function_define],
-[$2
-$1 (b4_formals(m4_shift2($@)))[]dnl
-])
-
-
 # b4_formals([DECL1, NAME1], ...)
 # -------------------------------
 # The formal arguments of a C function definition.
@@ -514,12 +662,6 @@
 [$1])
 
 
-
-## ----------------------- ##
-## Declaring C functions.  ##
-## ----------------------- ##
-
-
 # b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 # ------------------------------------------------------------
 # Declare the function NAME.
@@ -529,7 +671,6 @@
 
 
 
-
 ## --------------------- ##
 ## Calling C functions.  ##
 ## --------------------- ##
@@ -566,10 +707,10 @@
 ## User actions.  ##
 ## -------------- ##
 
-# b4_case(LABEL, STATEMENTS)
-# --------------------------
+# b4_case(LABEL, STATEMENTS, [COMMENTS])
+# --------------------------------------
 m4_define([b4_case],
-[  case $1:
+[  case $1:m4_ifval([$3], [ b4_comment([$3])])
 $2
 b4_syncline([@oline@], [@ofile@])dnl
     break;])
@@ -593,18 +734,15 @@
 | Release the memory associated to this symbol.  |
 `-----------------------------------------------*/
 
-]b4_function_define([yydestruct],
-    [static void],
-    [[const char *yymsg],    [yymsg]],
-    [[int yytype],           [yytype]],
-    [[YYSTYPE *yyvaluep],    [yyvaluep]][]dnl
-b4_locations_if(            [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
-m4_ifset([b4_parse_param], [, b4_parse_param]))[
+static void
+yydestruct (const char *yymsg,
+            yysymbol_kind_t yykind, YYSTYPE *yyvaluep]b4_locations_if(dnl
+[[, YYLTYPE *yylocationp]])[]b4_user_formals[)
 {
 ]b4_parse_param_use([yyvaluep], [yylocationp])dnl
 [  if (!yymsg)
     yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+  YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
 
   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   ]b4_symbol_actions([destructor])[
@@ -622,25 +760,15 @@
 | Print this symbol's value on YYO.  |
 `-----------------------------------*/
 
-]b4_function_define([yy_symbol_value_print],
-    [static void],
-               [[FILE *yyo],                            [yyo]],
-               [[int yytype],                           [yytype]],
-               [[YYSTYPE const * const yyvaluep],       [yyvaluep]][]dnl
-b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
-m4_ifset([b4_parse_param], [, b4_parse_param]))[
+static void
+yy_symbol_value_print (FILE *yyo,
+                       yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep]b4_locations_if(dnl
+[[, YYLTYPE const * const yylocationp]])[]b4_user_formals[)
 {
   FILE *yyoutput = yyo;
 ]b4_parse_param_use([yyoutput], [yylocationp])dnl
 [  if (!yyvaluep)
     return;]
-dnl glr.c does not feature yytoknum.
-m4_if(b4_skeleton, ["yacc.c"],
-[[# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
-# endif
-]])dnl
 b4_percent_code_get([[pre-printer]])dnl
   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   b4_symbol_actions([printer])
@@ -653,21 +781,18 @@
 | Print this symbol on YYO.  |
 `---------------------------*/
 
-]b4_function_define([yy_symbol_print],
-    [static void],
-               [[FILE *yyo],                            [yyo]],
-               [[int yytype],                           [yytype]],
-               [[YYSTYPE const * const yyvaluep],       [yyvaluep]][]dnl
-b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
-m4_ifset([b4_parse_param], [, b4_parse_param]))[
+static void
+yy_symbol_print (FILE *yyo,
+                 yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep]b4_locations_if(dnl
+[[, YYLTYPE const * const yylocationp]])[]b4_user_formals[)
 {
   YYFPRINTF (yyo, "%s %s (",
-             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+             yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
 
-]b4_locations_if([  YY_LOCATION_PRINT (yyo, *yylocationp);
+]b4_locations_if([  YYLOCATION_PRINT (yyo, yylocationp);
   YYFPRINTF (yyo, ": ");
 ])dnl
-[  yy_symbol_value_print (yyo, yytype, yyvaluep]dnl
+[  yy_symbol_value_print (yyo, yykind, yyvaluep]dnl
 b4_locations_if([, yylocationp])[]b4_user_args[);
   YYFPRINTF (yyo, ")");
 }]dnl
@@ -693,11 +818,11 @@
 [m4_define([b4_symbol($1, type_tag)],
            [b4_symbol_if([$1], [has_id],
                          [b4_symbol([$1], [id])],
-                         [yytype_[]b4_symbol([$1], [number])])])dnl
+                         [yykind_[]b4_symbol([$1], [number])])])dnl
 m4_append([b4_union_members],
-m4_expand([
-  b4_symbol_tag_comment([$1])dnl
-  b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
+m4_expand([m4_format([  %-40s %s],
+                     m4_expand([b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]),
+                     [b4_symbol_tag_comment([$1])])]))
 ])
 
 
@@ -851,7 +976,7 @@
 
 # b4_declare_yylstype
 # -------------------
-# Declarations that might either go into the header (if --defines) or
+# Declarations that might either go into the header (if --header) or
 # in the parser body.  Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
 m4_define([b4_declare_yylstype],
 [b4_value_type_define[]b4_locations_if([
@@ -921,25 +1046,30 @@
 #endif
 ]])
 
-# b4_yy_location_print_define
-# ---------------------------
-# Define YY_LOCATION_PRINT.
-m4_define([b4_yy_location_print_define],
+# b4_yylocation_print_define
+# --------------------------
+# Define YYLOCATION_PRINT.
+m4_define([b4_yylocation_print_define],
 [b4_locations_if([[
-/* YY_LOCATION_PRINT -- Print the location on the stream.
+/* YYLOCATION_PRINT -- Print the location on the stream.
    This macro was not mandated originally: define only if we know
    we won't break user code: when these are the locations we know.  */
 
-#ifndef YY_LOCATION_PRINT
-# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
+# ifndef YYLOCATION_PRINT
+
+#  if defined YY_LOCATION_PRINT
+
+   /* Temporary convenience wrapper in case some people defined the
+      undocumented and private YY_LOCATION_PRINT macros.  */
+#   define YYLOCATION_PRINT(File, Loc)  YY_LOCATION_PRINT(File, *(Loc))
+
+#  elif defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
 
 /* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
 
 YY_ATTRIBUTE_UNUSED
-]b4_function_define([yy_location_print_],
-    [static int],
-               [[FILE *yyo],                    [yyo]],
-               [[YYLTYPE const * const yylocp], [yylocp]])[
+static int
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
 {
   int res = 0;
   int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
@@ -961,19 +1091,23 @@
         res += YYFPRINTF (yyo, "-%d", end_col);
     }
   return res;
- }
+}
 
-#  define YY_LOCATION_PRINT(File, Loc)          \
-  yy_location_print_ (File, &(Loc))
+#   define YYLOCATION_PRINT  yy_location_print_
 
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif]],
-[[/* This macro is provided for backward compatibility. */
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif]])
+    /* Temporary convenience wrapper in case some people defined the
+       undocumented and private YY_LOCATION_PRINT macros.  */
+#   define YY_LOCATION_PRINT(File, Loc)  YYLOCATION_PRINT(File, &(Loc))
+
+#  else
+
+#   define YYLOCATION_PRINT(File, Loc) ((void) 0)
+    /* Temporary convenience wrapper in case some people defined the
+       undocumented and private YY_LOCATION_PRINT macros.  */
+#   define YY_LOCATION_PRINT  YYLOCATION_PRINT
+
+#  endif
+# endif /* !defined YYLOCATION_PRINT */]])
 ])
 
 # b4_yyloc_default
diff --git a/common/bison/skeletons/d-skel.m4 b/common/bison/skeletons/d-skel.m4
index 1705d84..2a38f02 100644
--- a/common/bison/skeletons/d-skel.m4
+++ b/common/bison/skeletons/d-skel.m4
@@ -2,7 +2,7 @@
 
 # D skeleton dispatching for Bison.
 
-# Copyright (C) 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 b4_glr_if(             [b4_complain([%%glr-parser not supported for D])])
 b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for D])])
diff --git a/common/bison/skeletons/d.m4 b/common/bison/skeletons/d.m4
index 2d29127..c0632e4 100644
--- a/common/bison/skeletons/d.m4
+++ b/common/bison/skeletons/d.m4
@@ -2,7 +2,7 @@
 
 # D language support for Bison
 
-# Copyright (C) 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,27 +15,36 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 
-# _b4_comment(TEXT, OPEN, CONTINUE, END)
-# --------------------------------------
-# Put TEXT in comment.  Avoid trailing spaces: don't indent empty lines.
-# Avoid adding indentation to the first line, as the indentation comes
-# from OPEN.  That's why we don't patsubst([$1], [^\(.\)], [   \1]).
-#
-# Prefix all the output lines with PREFIX.
-m4_define([_b4_comment],
-[$2[]m4_bpatsubst(m4_expand([[$1]]), [
-\(.\)], [
-$3\1])$4])
+m4_include(b4_skeletonsdir/[c-like.m4])
 
 
-# b4_comment(TEXT, [PREFIX])
-# --------------------------
-# Put TEXT in comment.  Prefix all the output lines with PREFIX.
-m4_define([b4_comment],
-[_b4_comment([$1], [$2/* ], [$2   ], [  */])])
+# b4_symbol_action(SYMBOL-NUM, ACTION)
+# ------------------------------------
+# Run the action ACTION ("destructor" or "printer") for SYMBOL-NUM.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[b4_dollar_pushdef([yyval],
+                   [$1],
+                   [],
+                   [yyloc])dnl
+    _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
+b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])dnl
+        break;
+
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_use(EXPR)
+# ------------
+# Pacify the compiler about some maybe unused value.
+m4_define([b4_use],
+[])
 
 
 # b4_sync_start(LINE, FILE)
@@ -58,6 +67,23 @@
           [m4_ifval(m4_quote(b4_percent_define_get([$1])),
                 [$2[]b4_percent_define_get([$1])[]$3], [$4])])
 
+# b4_percent_define_if_get2(ARG1, ARG2, DEF, NOT)
+# -----------------------------------------------
+# Expand to the value of DEF if ARG1 or ARG2 are %define'ed,
+# otherwise NOT.
+m4_define([b4_percent_define_if_get2],
+          [m4_ifval(m4_quote(b4_percent_define_get([$1])),
+                [$3], [m4_ifval(m4_quote(b4_percent_define_get([$2])),
+                      [$3], [$4])])])
+
+# b4_percent_define_class_before_interface(CLASS, INTERFACE)
+# ----------------------------------------------------------
+# Expand to a ', ' if both a class and an interface have been %define'ed
+m4_define([b4_percent_define_class_before_interface],
+          [m4_ifval(m4_quote(b4_percent_define_get([$1])),
+                [m4_ifval(m4_quote(b4_percent_define_get([$2])),
+                      [, ])])])
+
 
 # b4_flag_value(BOOLEAN-FLAG)
 # ---------------------------
@@ -78,8 +104,10 @@
 b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl
 b4_percent_define_flag_if([api.parser.final],    [final ])dnl
 [class ]b4_parser_class[]dnl
-b4_percent_define_get3([api.parser.extends], [ extends ])dnl
-b4_percent_define_get3([api.parser.implements], [ implements ])])
+b4_percent_define_if_get2([api.parser.extends], [api.parser.implements], [ : ])dnl
+b4_percent_define_get([api.parser.extends])dnl
+b4_percent_define_class_before_interface([api.parser.extends], [api.parser.implements])dnl
+b4_percent_define_get([api.parser.implements])])
 
 
 # b4_lexer_if(TRUE, FALSE)
@@ -103,12 +131,12 @@
 # b4_identification
 # -----------------
 m4_define([b4_identification],
-[/** Version number for the Bison executable that generated this parser.  */
-  public static immutable string yy_bison_version = "b4_version";
+[[/** Version number for the Bison executable that generated this parser.  */
+  public static immutable string yy_bison_version = "]b4_version_string[";
 
   /** Name of the skeleton that generated this parser.  */
-  public static immutable string yy_bison_skeleton = b4_skeleton;
-])
+  public static immutable string yy_bison_skeleton = ]b4_skeleton[;
+]])
 
 
 ## ------------ ##
@@ -148,9 +176,12 @@
 ])
 
 
-## ------------------------- ##
-## Assigning token numbers.  ##
-## ------------------------- ##
+## ------------- ##
+## Token kinds.  ##
+## ------------- ##
+
+m4_define([b4_symbol(-2, id)],  [[YYEMPTY]])
+b4_percent_define_default([[api.token.raw]], [[true]])
 
 # b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
 # ---------------------------------------
@@ -159,22 +190,121 @@
 [b4_token_format([  %s = %s,
 ], [$1])])
 
-# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
-# -----------------------------------------------------
+# b4_token_enums
+# --------------
 # Output the definition of the tokens as enums.
 m4_define([b4_token_enums],
-[/* Tokens.  */
-public enum YYTokenType {
-
-  /** Token returned by the scanner to signal the end of its input.  */
-  EOF = 0,
-b4_symbol_foreach([b4_token_enum])
+[/* Token kinds.  */
+public enum TokenKind {
+  ]b4_symbol(empty, id)[ = -2,
+b4_symbol_foreach([b4_token_enum])dnl
 }
 ])
 
-# b4-case(ID, CODE)
-# -----------------
-m4_define([b4_case], [    case $1:
+# b4_symbol_translate(STRING)
+# ---------------------------
+# Used by "bison" in the array of symbol names to mark those that
+# require translation.
+m4_define([b4_symbol_translate],
+[[_($1)]])
+
+
+# _b4_token_constructor_define(SYMBOL-NUM)
+# ----------------------------------------
+# Define Symbol.FOO for SYMBOL-NUM.
+m4_define([_b4_token_constructor_define],
+[b4_token_visible_if([$1],
+[[
+    static auto ]b4_symbol([$1], [id])[(]b4_symbol_if([$1], [has_type],
+[b4_union_if([b4_symbol([$1], [type]],
+[[typeof(YYSemanticType.]b4_symbol([$1], [type])[]])) [val]])dnl
+[]b4_locations_if([b4_symbol_if([$1], [has_type], [[, ]])[Location l]])[)
+    {
+      return Symbol(TokenKind.]b4_symbol([$1], [id])[]b4_symbol_if([$1], [has_type],
+      [[, val]])[]b4_locations_if([[, l]])[);
+    }]])])
+
+# b4_token_constructor_define
+# ---------------------------
+# Define Symbol.FOO for each token kind FOO.
+m4_define([b4_token_constructor_define],
+[[
+    /* Implementation of token constructors for each symbol type visible to
+     * the user. The code generates static methods that have the same names
+     * as the TokenKinds.
+     */]b4_symbol_foreach([_b4_token_constructor_define])dnl
+])
+
+## -------------- ##
+## Symbol kinds.  ##
+## -------------- ##
+
+# b4_symbol_kind(NUM)
+# -------------------
+m4_define([b4_symbol_kind],
+[SymbolKind.b4_symbol_kind_base($@)])
+
+
+# b4_symbol_enum(SYMBOL-NUM)
+# --------------------------
+# Output the definition of this symbol as an enum.
+m4_define([b4_symbol_enum],
+[m4_format([    %-30s %s],
+           m4_format([[%s = %s,]],
+                     b4_symbol([$1], [kind_base]),
+                     [$1]),
+           [b4_symbol_tag_comment([$1])])])
+
+
+# b4_declare_symbol_enum
+# ----------------------
+# The definition of the symbol internal numbers as an enum.
+# Defining YYEMPTY here is important: it forces the compiler
+# to use a signed type, which matters for yytoken.
+m4_define([b4_declare_symbol_enum],
+[[  /* Symbol kinds.  */
+  struct SymbolKind
+  {
+    enum
+    {
+    ]b4_symbol(empty, kind_base)[ = -2,  /* No symbol.  */
+]b4_symbol_foreach([b4_symbol_enum])dnl
+[    }
+
+    private int yycode_;
+    alias yycode_ this;
+
+    this(int code)
+    {
+      yycode_ = code;
+    }
+
+    /* Return YYSTR after stripping away unnecessary quotes and
+     backslashes, so that it's suitable for yyerror.  The heuristic is
+     that double-quoting is unnecessary unless the string contains an
+     apostrophe, a comma, or backslash (other than backslash-backslash).
+     YYSTR is taken from yytname.  */
+    final void toString(W)(W sink) const
+    if (isOutputRange!(W, char))
+    {
+      immutable string[] yy_sname = @{
+  ]b4_symbol_names[
+      @};]b4_has_translations_if([[
+      /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+        internationalizable.  */
+      immutable ]b4_int_type_for([b4_translatable])[[] yytranslatable = @{
+  ]b4_translatable[
+      @};]])[
+
+      put(sink, yy_sname[yycode_]);
+    }
+  }
+]])
+
+
+# b4_case(ID, CODE, [COMMENTS])
+# -----------------------------
+m4_define([b4_case], [    case $1:m4_ifval([$3], [ b4_comment([$3])])
 $2
       break;])
 
@@ -199,6 +329,109 @@
 m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition]))
 
 
+## ---------------- ##
+## api.value.type.  ##
+## ---------------- ##
+
+
+# ---------------------- #
+# api.value.type=union.  #
+# ---------------------- #
+
+# b4_symbol_type_register(SYMBOL-NUM)
+# -----------------------------------
+# Symbol SYMBOL-NUM has a type (for union) instead of a type-tag.
+# Extend the definition of %union's body (b4_union_members) with a
+# field of that type, and extend the symbol's "type" field to point to
+# the field name, instead of the type name.
+m4_define([b4_symbol_type_register],
+[m4_define([b4_symbol($1, type_tag)],
+           [b4_symbol_if([$1], [has_id],
+                         [b4_symbol([$1], [id])],
+                         [yykind_[]b4_symbol([$1], [number])])])dnl
+m4_append([b4_union_members],
+m4_expand([m4_format([  %-40s %s],
+                     m4_expand([b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]),
+                     [b4_symbol_tag_comment([$1])])]))
+])
+
+
+# b4_type_define_tag(SYMBOL1-NUM, ...)
+# ------------------------------------
+# For the batch of symbols SYMBOL1-NUM... (which all have the same
+# type), enhance the %union definition for each of them, and set
+# there "type" field to the field tag name, instead of the type name.
+m4_define([b4_type_define_tag],
+[b4_symbol_if([$1], [has_type],
+              [m4_map([b4_symbol_type_register], [$@])])
+])
+
+
+# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE])
+# ----------------------------------------------
+# Same of b4_symbol_value, but when api.value.type=union.
+m4_define([b4_symbol_value_union],
+[m4_ifval([$3],
+          [(*($3*)(&$1))],
+          [m4_ifval([$2],
+                    [b4_symbol_if([$2], [has_type],
+                                  [($1.b4_symbol([$2], [type_tag]))],
+                                  [$1])],
+                    [$1])])])
+
+
+# b4_value_type_setup_union
+# -------------------------
+# Setup support for api.value.type=union.  Symbols are defined with a
+# type instead of a union member name: build the corresponding union,
+# and give the symbols their tag.
+m4_define([b4_value_type_setup_union],
+[m4_define([b4_union_members])
+b4_type_foreach([b4_type_define_tag])
+m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
+])
+
+
+# _b4_value_type_setup_keyword
+# ----------------------------
+# api.value.type is defined with a keyword/string syntax.  Check if
+# that is properly defined, and prepare its use.
+m4_define([_b4_value_type_setup_keyword],
+[b4_percent_define_check_values([[[[api.value.type]],
+                                  [[none]],
+                                  [[union]],
+                                  [[union-directive]],
+                                  [[yystype]]]])dnl
+m4_case(b4_percent_define_get([[api.value.type]]),
+        [union],   [b4_value_type_setup_union])])
+
+
+# b4_value_type_setup
+# -------------------
+# Check if api.value.type is properly defined, and possibly prepare
+# its use.
+b4_define_silent([b4_value_type_setup],
+[
+# Define default value.
+b4_percent_define_ifdef([[api.value.type]], [],
+[# %union => api.value.type=union-directive
+m4_ifdef([b4_union_members],
+[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
+m4_define([b4_percent_define(api.value.type)], [union-directive])],
+[# no tag seen => api.value.type={int}
+m4_if(b4_tag_seen_flag, 0,
+[m4_define([b4_percent_define_kind(api.value.type)], [code])
+m4_define([b4_percent_define(api.value.type)], [int])],
+[# otherwise api.value.type=yystype
+m4_define([b4_percent_define_kind(api.value.type)], [keyword])
+m4_define([b4_percent_define(api.value.type)], [yystype])])])])
+
+# Set up.
+m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+   [keyword], [_b4_value_type_setup_keyword])
+])
+
+
 ## ----------------- ##
 ## Semantic Values.  ##
 ## ----------------- ##
@@ -245,7 +478,7 @@
 # Expansion of @POS, where the current rule has RULE-LENGTH symbols
 # on RHS.
 m4_define([b4_rhs_location],
-[yystack.locationAt ([$1], [$2])])
+[yystack.locationAt (b4_subtract($@))])
 
 
 # b4_lex_param
@@ -330,3 +563,66 @@
 ], [$@])])
 m4_define([b4_var_decl],
           [    protected $1;])
+
+
+# b4_public_types_declare
+# -----------------------
+# Define the public types: token, semantic value, location, and so forth.
+# Depending on %define token_lex, may be output in the header or source file.
+m4_define([b4_public_types_declare],
+[[
+alias Symbol = ]b4_parser_class[.Symbol;
+alias Value = ]b4_yystype[;]b4_locations_if([[
+alias Location = ]b4_location_type[;
+alias Position = ]b4_position_type[;]b4_push_if([[
+alias PUSH_MORE = ]b4_parser_class[.YYPUSH_MORE;
+alias ABORT = ]b4_parser_class[.YYABORT;
+alias ACCEPT = ]b4_parser_class[.YYACCEPT;]])[]])[
+]])
+
+
+# b4_basic_symbol_constructor_define
+# ----------------------------------
+# Create Symbol struct constructors for all the visible types.
+m4_define([b4_basic_symbol_constructor_define],
+[b4_token_visible_if([$1],
+[[    this(TokenKind token]b4_symbol_if([$1], [has_type],
+[[, ]b4_union_if([], [[typeof(YYSemanticType.]])b4_symbol([$1], [type])dnl
+[]b4_union_if([], [[) ]])[ val]])[]b4_locations_if([[, Location loc]])[)
+    {
+      kind = yytranslate_(token);]b4_union_if([b4_symbol_if([$1], [has_type], [[
+      static foreach (member; __traits(allMembers, YYSemanticType))
+      {
+        static if (is(typeof(mixin("value_." ~ member)) == ]b4_symbol([$1], [type])[))
+        {
+          mixin("value_." ~ member ~ " = val;");
+        }
+      }]])], [b4_symbol_if([$1], [has_type], [[
+      value_.]b4_symbol([$1], [type])[ = val;]])])[]b4_locations_if([
+      location_ = loc;])[
+    }
+]])])
+
+
+# b4_symbol_type_define
+# ---------------------
+# Define symbol_type, the external type for symbols used for symbol
+# constructors.
+m4_define([b4_symbol_type_define],
+[[
+  /**
+    * A complete symbol
+    */
+  struct Symbol
+  {
+    private SymbolKind kind;
+    private Value value_;]b4_locations_if([[
+    private Location location_;]])[
+
+]b4_type_foreach([b4_basic_symbol_constructor_define])[
+    SymbolKind token() { return kind; }
+    Value value() { return value_; }]b4_locations_if([[
+    Location location() { return location_; }]])[
+]b4_token_ctor_if([b4_token_constructor_define])[
+  }
+]])
diff --git a/common/bison/skeletons/glr.c b/common/bison/skeletons/glr.c
index 945ff0a..fab3733 100644
--- a/common/bison/skeletons/glr.c
+++ b/common/bison/skeletons/glr.c
@@ -1,8 +1,8 @@
-                                                                    -*- C -*-
+#                                                             -*- C -*-
 
 # GLR skeleton for Bison
 
-# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 
 # If we are loaded by glr.cc, do not override c++.m4 definitions by
@@ -32,7 +32,9 @@
 m4_define_default([b4_stack_depth_max], [10000])
 m4_define_default([b4_stack_depth_init],  [200])
 
-
+# Included header.
+b4_percent_define_default([[api.header.include]],
+                          [["@basename(]b4_spec_header_file[@)"]])
 
 ## ------------------------ ##
 ## Pure/impure interfaces.  ##
@@ -46,16 +48,6 @@
  m4_define([b4_pure_flag],
            [b4_percent_define_flag_if([[api.pure]], [[1]], [[0]])])])
 
-# b4_user_formals
-# ---------------
-# The possible parse-params formal arguments preceded by a comma.
-#
-# This is not shared with yacc.c in c.m4 because  GLR relies on ISO C
-# formal argument declarations.
-m4_define([b4_user_formals],
-[m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])])
-
-
 # b4_yyerror_args
 # ---------------
 # Optional effective arguments passed to yyerror: user args plus yylloc, and
@@ -132,7 +124,7 @@
 # --------------------------------------------------
 # Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
 m4_define([b4_rhs_value],
-[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3], [$4])])
+[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yyval], [$3], [$4])])
 
 
 
@@ -155,13 +147,22 @@
 [(b4_rhs_data([$1], [$2]).yyloc)])
 
 
+# b4_call_merger(MERGER-NUM, MERGER-NAME, SYMBOL-SUM)
+# ---------------------------------------------------
+m4_define([b4_call_merger],
+[b4_case([$1],
+         [    b4_symbol_if([$3], [has_type],
+                           [yy0->b4_symbol($3, slot) = $2 (*yy0, *yy1);],
+                           [*yy0 = $2 (*yy0, *yy1);])])])
+
+
 ## -------------- ##
 ## Declarations.  ##
 ## -------------- ##
 
 # b4_shared_declarations
 # ----------------------
-# Declaration that might either go into the header (if --defines)
+# Declaration that might either go into the header (if --header)
 # or open coded in the parser body.  glr.cc has its own definition.
 m4_if(b4_skeleton, ["glr.c"],
 [m4_define([b4_shared_declarations],
@@ -169,7 +170,7 @@
 ]b4_percent_code_get([[requires]])[
 ]b4_token_enums[
 ]b4_declare_yylstype[
-]b4_function_declare(b4_prefix[parse], [int], b4_parse_param)[
+int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
 ]b4_percent_code_get([[provides]])[]dnl
 ])
 ])
@@ -187,7 +188,7 @@
 # members of this union.
 #
 # To avoid this issue, just generate the header before the
-# implementation file.  But we should also make them more independant.
+# implementation file.  But we should also make them more independent.
 
 # ----------------- #
 # The header file.  #
@@ -195,13 +196,13 @@
 
 # glr.cc produces its own header.
 b4_glr_cc_if([],
-[b4_defines_if(
+[b4_header_if(
 [b4_output_begin([b4_spec_header_file])
 b4_copyright([Skeleton interface for Bison GLR parsers in C],
-             [2002-2015, 2018-2019])[
-]b4_cpp_guard_open([b4_spec_header_file])[
+             [2002-2015, 2018-2021])[
+]b4_cpp_guard_open([b4_spec_mapped_header_file])[
 ]b4_shared_declarations[
-]b4_cpp_guard_close([b4_spec_header_file])[
+]b4_cpp_guard_close([b4_spec_mapped_header_file])[
 ]b4_output_end[
 ]])])
 
@@ -212,7 +213,7 @@
 
 b4_output_begin([b4_parser_file_name])
 b4_copyright([Skeleton implementation for Bison GLR parsers in C],
-             [2002-2015, 2018-2019])[
+             [2002-2015, 2018-2021])[
 /* C GLR parser skeleton written by Paul Hilfinger.  */
 
 ]b4_disclaimer[
@@ -225,7 +226,7 @@
 #define YYLTYPE ]b4_api_PREFIX[LTYPE]])])[
 ]m4_if(b4_prefix, [yy], [],
 [[/* Substitute the variable and function names.  */
-#define yyparse ]b4_prefix[parse
+#define ]b4_glr_cc_if([yy_parse_impl], [yyparse])[ ]b4_prefix[]b4_glr_cc_if([_parse_impl], [parse])[
 #define yylex   ]b4_prefix[lex
 #define yyerror ]b4_prefix[error
 #define yydebug ]b4_prefix[debug]]b4_pure_if([], [[
@@ -238,16 +239,11 @@
 ]b4_cast_define[
 ]b4_null_define[
 
-]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
-               [b4_shared_declarations])[
+]b4_header_if([[#include ]b4_percent_define_get([[api.header.include]])],
+              [b4_shared_declarations])[
 
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
-#endif
+]b4_glr_cc_if([b4_glr_cc_setup],
+              [b4_declare_symbol_enum])[
 
 /* Default (constant) value used for initialization for null
    right-hand sides.  Unlike the standard yacc.c template, here we set
@@ -266,6 +262,7 @@
 #include <string.h>
 
 ]b4_c99_int_type_define[
+]b4_sizes_types_define[
 
 #ifndef YY_
 # if defined YYENABLE_NLS && YYENABLE_NLS
@@ -278,6 +275,11 @@
 #  define YY_(Msgid) Msgid
 # endif
 #endif
+]b4_has_translations_if([
+#ifndef N_
+# define N_(Msgid) Msgid
+#endif
+])[
 
 #ifndef YYFREE
 # define YYFREE free
@@ -289,9 +291,6 @@
 # define YYREALLOC realloc
 #endif
 
-#define YYSIZEMAX \
-  (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
-
 #ifdef __cplusplus
   typedef bool yybool;
 # define yytrue true
@@ -345,21 +344,17 @@
    accessed by $0, $-1, etc., in any rule.  */
 #define YYMAXLEFT ]b4_max_left_semantic_context[
 
-/* YYMAXUTOK -- Last valid token number (for yychar).  */
-#define YYMAXUTOK   ]b4_user_token_number_max[]b4_glr_cc_if([[
-/* YYFAULTYTOK -- Token number (for yychar) that denotes a
-   syntax_error thrown from the scanner.  */
-#define YYFAULTYTOK (YYMAXUTOK + 1)]])[
-/* YYUNDEFTOK -- Symbol number (for yytoken) that denotes an unknown
-   token.  */
-#define YYUNDEFTOK  ]b4_undef_token_number[
+/* YYMAXUTOK -- Last valid token kind.  */
+#define YYMAXUTOK   ]b4_code_max[
 
 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
    as returned by yylex, with out-of-bounds checking.  */
 ]b4_api_token_raw_if(dnl
-[[#define YYTRANSLATE(YYX) (YYX)]],
-[[#define YYTRANSLATE(YYX)                         \
-  (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+[[#define YYTRANSLATE(YYX) YY_CAST (yysymbol_kind_t, YYX)]],
+[[#define YYTRANSLATE(YYX)                                \
+  (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
+   ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
+   : ]b4_symbol_prefix[YYUNDEF)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
    as returned by yylex.  */
@@ -376,15 +371,6 @@
 };
 #endif
 
-#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  ]b4_tname[
-};
-#endif
-
 #define YYPACT_NINF (]b4_pact_ninf[)
 #define YYTABLE_NINF (]b4_table_ninf[)
 
@@ -428,9 +414,6 @@
   ]b4_conflicting_rules[
 };
 
-/* Error token number */
-#define YYTERROR 1
-
 ]b4_locations_if([[
 ]b4_yylloc_default_define[
 # define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
@@ -457,10 +440,9 @@
 int yynerrs;
 int yychar;])[
 
-static const int YYEOF = 0;
-static const int YYEMPTY = -2;
+enum { YYENOMEM = -2 };
 
-typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
+typedef enum { yyok, yyaccept, yyabort, yyerr, yynomem } YYRESULTTAG;
 
 #define YYCHK(YYE)                              \
   do {                                          \
@@ -469,62 +451,6 @@
       return yychk_flag;                        \
   } while (0)
 
-#if ]b4_api_PREFIX[DEBUG
-
-# ifndef YYFPRINTF
-#  define YYFPRINTF fprintf
-# endif
-
-# define YY_FPRINTF                             \
-  YY_IGNORE_USELESS_CAST_BEGIN YY_FPRINTF_
-
-# define YY_FPRINTF_(Args)                      \
-  do {                                          \
-    YYFPRINTF Args;                             \
-    YY_IGNORE_USELESS_CAST_END                  \
-  } while (0)
-
-# define YY_DPRINTF                             \
-  YY_IGNORE_USELESS_CAST_BEGIN YY_DPRINTF_
-
-# define YY_DPRINTF_(Args)                      \
-  do {                                          \
-    if (yydebug)                                \
-      YYFPRINTF Args;                           \
-    YY_IGNORE_USELESS_CAST_END                  \
-  } while (0)
-
-]b4_yy_location_print_define[
-
-]b4_yy_symbol_print_define[
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                  \
-  do {                                                                  \
-    if (yydebug)                                                        \
-      {                                                                 \
-        YY_FPRINTF ((stderr, "%s ", Title));                            \
-        yy_symbol_print (stderr, Type, Value]b4_locuser_args([Location])[);        \
-        YY_FPRINTF ((stderr, "\n"));                                    \
-      }                                                                 \
-  } while (0)
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-
-struct yyGLRStack;
-static void yypstack (struct yyGLRStack* yystackp, ptrdiff_t yyk)
-  YY_ATTRIBUTE_UNUSED;
-static void yypdumpstack (struct yyGLRStack* yystackp)
-  YY_ATTRIBUTE_UNUSED;
-
-#else /* !]b4_api_PREFIX[DEBUG */
-
-# define YY_DPRINTF(Args) do {} while (yyfalse)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-
-#endif /* !]b4_api_PREFIX[DEBUG */
-
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
 #ifndef YYINITDEPTH
 # define YYINITDEPTH ]b4_stack_depth_init[
@@ -566,91 +492,12 @@
   } while (0)
 #endif
 
-
-#if YYERROR_VERBOSE
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static ptrdiff_t
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      ptrdiff_t yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-        switch (*++yyp)
-          {
-          case '\'':
-          case ',':
-            goto do_not_strip_quotes;
-
-          case '\\':
-            if (*++yyp != '\\')
-              goto do_not_strip_quotes;
-            else
-              goto append;
-
-          append:
-          default:
-            if (yyres)
-              yyres[yyn] = *yyp;
-            yyn++;
-            break;
-
-          case '"':
-            if (yyres)
-              yyres[yyn] = '\0';
-            return yyn;
-          }
-    do_not_strip_quotes: ;
-    }
-
-  if (yyres)
-    return yystpcpy (yyres, yystr) - yyres;
-  else
-    return YY_CAST (ptrdiff_t, strlen (yystr));
-}
-# endif
-
-#endif /* !YYERROR_VERBOSE */
-
 /** State numbers. */
-typedef int yyStateNum;
+typedef int yy_state_t;
 
 /** Rule numbers. */
 typedef int yyRuleNum;
 
-/** Grammar symbol. */
-typedef int yySymbol;
-
 /** Item references. */
 typedef short yyItemNum;
 
@@ -660,42 +507,45 @@
 typedef union yyGLRStackItem yyGLRStackItem;
 typedef struct yyGLRStack yyGLRStack;
 
-struct yyGLRState {
+struct yyGLRState
+{
   /** Type tag: always true.  */
   yybool yyisState;
-  /** Type tag for yysemantics.  If true, yysval applies, otherwise
+  /** Type tag for yysemantics.  If true, yyval applies, otherwise
    *  yyfirstVal applies.  */
   yybool yyresolved;
   /** Number of corresponding LALR(1) machine state.  */
-  yyStateNum yylrState;
+  yy_state_t yylrState;
   /** Preceding state in this stack */
   yyGLRState* yypred;
   /** Source position of the last token produced by my symbol */
-  ptrdiff_t yyposn;
+  YYPTRDIFF_T yyposn;
   union {
     /** First in a chain of alternative reductions producing the
      *  nonterminal corresponding to this state, threaded through
      *  yynext.  */
     yySemanticOption* yyfirstVal;
     /** Semantic value for this state.  */
-    YYSTYPE yysval;
+    YYSTYPE yyval;
   } yysemantics;]b4_locations_if([[
   /** Source location for this state.  */
   YYLTYPE yyloc;]])[
 };
 
-struct yyGLRStateSet {
+struct yyGLRStateSet
+{
   yyGLRState** yystates;
   /** During nondeterministic operation, yylookaheadNeeds tracks which
    *  stacks have actually needed the current lookahead.  During deterministic
    *  operation, yylookaheadNeeds[0] is not maintained since it would merely
-   *  duplicate yychar != YYEMPTY.  */
+   *  duplicate yychar != ]b4_symbol(empty, id)[.  */
   yybool* yylookaheadNeeds;
-  ptrdiff_t yysize;
-  ptrdiff_t yycapacity;
+  YYPTRDIFF_T yysize;
+  YYPTRDIFF_T yycapacity;
 };
 
-struct yySemanticOption {
+struct yySemanticOption
+{
   /** Type tag: always false.  */
   yybool yyisState;
   /** Rule number for this reduction */
@@ -732,7 +582,7 @@
   YYJMP_BUF yyexception_buffer;
   yyGLRStackItem* yyitems;
   yyGLRStackItem* yynextFree;
-  ptrdiff_t yyspaceLeft;
+  YYPTRDIFF_T yyspaceLeft;
   yyGLRState* yysplitPoint;
   yyGLRState* yylastDeleted;
   yyGLRStateSet yytops;
@@ -756,14 +606,206 @@
   YYLONGJMP (yystackp->yyexception_buffer, 2);
 }
 
-#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE
-/** A printable representation of TOKEN.  */
-static inline const char*
-yytokenName (yySymbol yytoken)
+/** Accessing symbol of state YYSTATE.  */
+static inline yysymbol_kind_t
+yy_accessing_symbol (yy_state_t yystate)
 {
-  return yytoken == YYEMPTY ? "" : yytname[yytoken];
+  return YY_CAST (yysymbol_kind_t, yystos[yystate]);
+}
+
+#if ]b4_parse_error_case([simple], [b4_api_PREFIX[DEBUG || ]b4_token_table_flag], [[1]])[
+/* The user-facing name of the symbol whose (internal) number is
+   YYSYMBOL.  No bounds checking.  */
+static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+]b4_parse_error_bmatch([simple\|verbose],
+[[/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  ]b4_tname[
+};
+
+static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+  return yytname[yysymbol];
+}]],
+[[static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+  static const char *const yy_sname[] =
+  {
+  ]b4_symbol_names[
+  };]b4_has_translations_if([[
+  /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+     internationalizable.  */
+  static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
+  {
+  ]b4_translatable[
+  };
+  return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
+          ? _(yy_sname[yysymbol])
+          : yy_sname[yysymbol]);]], [[
+  return yy_sname[yysymbol];]])[
+}]])[
+#endif
+
+/** Left-hand-side symbol for rule #YYRULE.  */
+static inline yysymbol_kind_t
+yylhsNonterm (yyRuleNum yyrule)
+{
+  return YY_CAST (yysymbol_kind_t, yyr1[yyrule]);
+}
+
+#if ]b4_api_PREFIX[DEBUG
+
+# ifndef YYFPRINTF
+#  define YYFPRINTF fprintf
+# endif
+
+# define YY_FPRINTF                             \
+  YY_IGNORE_USELESS_CAST_BEGIN YY_FPRINTF_
+
+# define YY_FPRINTF_(Args)                      \
+  do {                                          \
+    YYFPRINTF Args;                             \
+    YY_IGNORE_USELESS_CAST_END                  \
+  } while (0)
+
+# define YY_DPRINTF                             \
+  YY_IGNORE_USELESS_CAST_BEGIN YY_DPRINTF_
+
+# define YY_DPRINTF_(Args)                      \
+  do {                                          \
+    if (yydebug)                                \
+      YYFPRINTF Args;                           \
+    YY_IGNORE_USELESS_CAST_END                  \
+  } while (0)
+
+]b4_yylocation_print_define[
+
+]b4_yy_symbol_print_define[
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                  \
+  do {                                                                  \
+    if (yydebug)                                                        \
+      {                                                                 \
+        YY_FPRINTF ((stderr, "%s ", Title));                            \
+        yy_symbol_print (stderr, Kind, Value]b4_locuser_args([Location])[);        \
+        YY_FPRINTF ((stderr, "\n"));                                    \
+      }                                                                 \
+  } while (0)
+
+static inline void
+yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
+                 yyRuleNum yyrule]b4_user_formals[);
+
+# define YY_REDUCE_PRINT(Args)          \
+  do {                                  \
+    if (yydebug)                        \
+      yy_reduce_print Args;             \
+  } while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+
+static void yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
+  YY_ATTRIBUTE_UNUSED;
+static void yypdumpstack (yyGLRStack* yystackp)
+  YY_ATTRIBUTE_UNUSED;
+
+#else /* !]b4_api_PREFIX[DEBUG */
+
+# define YY_DPRINTF(Args) do {} while (yyfalse)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_REDUCE_PRINT(Args)
+
+#endif /* !]b4_api_PREFIX[DEBUG */
+
+]b4_parse_error_case(
+         [simple],
+[[]],
+[[#ifndef yystrlen
+# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
+#endif
+
+]b4_parse_error_bmatch(
+           [detailed\|verbose],
+[[#ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#  define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+# endif
+#endif]])[
+
+]b4_parse_error_case(
+         [verbose],
+[[#ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYPTRDIFF_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYPTRDIFF_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+        switch (*++yyp)
+          {
+          case '\'':
+          case ',':
+            goto do_not_strip_quotes;
+
+          case '\\':
+            if (*++yyp != '\\')
+              goto do_not_strip_quotes;
+            else
+              goto append;
+
+          append:
+          default:
+            if (yyres)
+              yyres[yyn] = *yyp;
+            yyn++;
+            break;
+
+          case '"':
+            if (yyres)
+              yyres[yyn] = '\0';
+            return yyn;
+          }
+    do_not_strip_quotes: ;
+    }
+
+  if (yyres)
+    return yystpcpy (yyres, yystr) - yyres;
+  else
+    return yystrlen (yystr);
 }
 #endif
+]])])[
 
 /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
  *  at YYVSP[YYLOW0].yystate.yypred.  Leaves YYVSP[YYLOW1].yystate.yypred
@@ -781,9 +823,9 @@
 #endif
       yyvsp[i].yystate.yyresolved = s->yyresolved;
       if (s->yyresolved)
-        yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval;
+        yyvsp[i].yystate.yysemantics.yyval = s->yysemantics.yyval;
       else
-        /* The effect of using yysval or yyloc (in an immediate rule) is
+        /* The effect of using yyval or yyloc (in an immediate rule) is
          * undefined.  */
         yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[
       yyvsp[i].yystate.yyloc = s->yyloc;]])[
@@ -794,19 +836,19 @@
 ]m4_define([b4_yygetToken_call],
            [[yygetToken (&yychar][]b4_pure_if([, yystackp])[]b4_user_args[)]])[
 /** If yychar is empty, fetch the next token.  */
-static inline yySymbol
+static inline yysymbol_kind_t
 yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals[)
 {
-  yySymbol yytoken;
+  yysymbol_kind_t yytoken;
 ]b4_parse_param_use()dnl
-[  if (*yycharp == YYEMPTY)
+[  if (*yycharp == ]b4_symbol(empty, id)[)
     {
-      YY_DPRINTF ((stderr, "Reading a token: "));]b4_glr_cc_if([[
+      YY_DPRINTF ((stderr, "Reading a token\n"));]b4_glr_cc_if([[
 #if YY_EXCEPTIONS
       try
         {
 #endif // YY_EXCEPTIONS
-          *yycharp = ]b4_lex[;
+          *yycharp = ]b4_yylex[;
 #if YY_EXCEPTIONS
         }
       catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc)
@@ -814,17 +856,18 @@
           YY_DPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));]b4_locations_if([
           yylloc = yyexc.location;])[
           yyerror (]b4_lyyerror_args[yyexc.what ());
-          // Map errors caught in the scanner to the undefined token
-          // (YYUNDEFTOK), so that error handling is started.
-          // However, record this with this special value of yychar.
-          *yycharp = YYFAULTYTOK;
+          // Map errors caught in the scanner to the undefined token,
+          // so that error handling is started.  However, record this
+          // with this special value of yychar.
+          *yycharp = ]b4_symbol(error, id)[;
         }
 #endif // YY_EXCEPTIONS]], [[
-      *yycharp = ]b4_lex[;]])[
+      *yycharp = ]b4_yylex[;]])[
     }
-  if (*yycharp <= YYEOF)
+  if (*yycharp <= ]b4_symbol(eof, [id])[)
     {
-      *yycharp = yytoken = YYEOF;
+      *yycharp = ]b4_symbol(eof, [id])[;
+      yytoken = ]b4_symbol_prefix[YYEOF;
       YY_DPRINTF ((stderr, "Now at end of input.\n"));
     }
   else
@@ -855,28 +898,31 @@
  *  and top stack item YYVSP.  YYLVALP points to place to put semantic
  *  value ($$), and yylocp points to place for location information
  *  (@@$).  Returns yyok for normal return, yyaccept for YYACCEPT,
- *  yyerr for YYERROR, yyabort for YYABORT.  */
+ *  yyerr for YYERROR, yyabort for YYABORT, yynomem for YYNOMEM.  */
 static YYRESULTTAG
-yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
-              yyGLRStack* yystackp,
+yyuserAction (yyRuleNum yyrule, int yyrhslen, yyGLRStackItem* yyvsp,
+              yyGLRStack* yystackp, YYPTRDIFF_T yyk,
               YYSTYPE* yyvalp]b4_locuser_formals[)
 {
-  yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
-  int yylow;
+  const yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
+  int yylow = 1;
 ]b4_parse_param_use([yyvalp], [yylocp])dnl
-[  YYUSE (yyrhslen);
+[  YY_USE (yyk);
+  YY_USE (yyrhslen);
 # undef yyerrok
 # define yyerrok (yystackp->yyerrState = 0)
 # undef YYACCEPT
 # define YYACCEPT return yyaccept
 # undef YYABORT
 # define YYABORT return yyabort
+# undef YYNOMEM
+# define YYNOMEM return yynomem
 # undef YYERROR
 # define YYERROR return yyerrok, yyerr
 # undef YYRECOVERING
 # define YYRECOVERING() (yystackp->yyerrState != 0)
 # undef yyclearin
-# define yyclearin (yychar = YYEMPTY)
+# define yyclearin (yychar = ]b4_symbol(empty, id)[)
 # undef YYFILL
 # define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal)
 # undef YYBACKUP
@@ -884,21 +930,23 @@
   return yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")),     \
          yyerrok, yyerr
 
-  yylow = 1;
   if (yyrhslen == 0)
     *yyvalp = yyval_default;
   else
-    *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;]b4_locations_if([[
+    *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yyval;]b4_locations_if([[
   /* Default location. */
   YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
-  yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
-]])[]b4_glr_cc_if([[
+  yystackp->yyerror_range[1].yystate.yyloc = *yylocp;]])[
+  /* If yyk == -1, we are running a deferred action on a temporary
+     stack.  In that case, YY_REDUCE_PRINT must not play with YYFILL,
+     so pretend the stack is "normal". */
+  YY_REDUCE_PRINT ((yynormal || yyk == -1, yyvsp, yyk, yyrule]b4_user_args[));]b4_glr_cc_if([[
 #if YY_EXCEPTIONS
   typedef ]b4_namespace_ref[::]b4_parser_class[::syntax_error syntax_error;
   try
   {
 #endif // YY_EXCEPTIONS]])[
-  switch (yyn)
+  switch (yyrule)
     {
 ]b4_user_actions[
       default: break;
@@ -913,11 +961,13 @@
       YYERROR;
     }
 #endif // YY_EXCEPTIONS]])[
+  YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), yyvalp, yylocp);
 
   return yyok;
 # undef yyerrok
 # undef YYABORT
 # undef YYACCEPT
+# undef YYNOMEM
 # undef YYERROR
 # undef YYBACKUP
 # undef yyclearin
@@ -928,8 +978,8 @@
 static void
 yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
 {
-  YYUSE (yy0);
-  YYUSE (yy1);
+  YY_USE (yy0);
+  YY_USE (yy1);
 
   switch (yyn)
     {
@@ -953,8 +1003,8 @@
 yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
 {
   if (yys->yyresolved)
-    yydestruct (yymsg, yystos[yys->yylrState],
-                &yys->yysemantics.yysval]b4_locuser_args([&yys->yyloc])[);
+    yydestruct (yymsg, yy_accessing_symbol (yys->yylrState),
+                &yys->yysemantics.yyval]b4_locuser_args([&yys->yyloc])[);
   else
     {
 #if ]b4_api_PREFIX[DEBUG
@@ -964,7 +1014,7 @@
             YY_FPRINTF ((stderr, "%s unresolved", yymsg));
           else
             YY_FPRINTF ((stderr, "%s incomplete", yymsg));
-          YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, &yys->yyloc);
+          YY_SYMBOL_PRINT ("", yy_accessing_symbol (yys->yylrState), YY_NULLPTR, &yys->yyloc);
         }
 #endif
 
@@ -981,27 +1031,20 @@
     }
 }
 
-/** Left-hand-side symbol for rule #YYRULE.  */
-static inline yySymbol
-yylhsNonterm (yyRuleNum yyrule)
-{
-  return yyr1[yyrule];
-}
-
 #define yypact_value_is_default(Yyn) \
   ]b4_table_value_equals([[pact]], [[Yyn]], [b4_pact_ninf], [YYPACT_NINF])[
 
 /** True iff LR state YYSTATE has only a default reduction (regardless
  *  of token).  */
 static inline yybool
-yyisDefaultedState (yyStateNum yystate)
+yyisDefaultedState (yy_state_t yystate)
 {
   return yypact_value_is_default (yypact[yystate]);
 }
 
 /** The default reduction for YYSTATE, assuming it has one.  */
 static inline yyRuleNum
-yydefaultAction (yyStateNum yystate)
+yydefaultAction (yy_state_t yystate)
 {
   return yydefact[yystate];
 }
@@ -1018,11 +1061,17 @@
  *  of conflicting reductions.
  */
 static inline int
-yygetLRActions (yyStateNum yystate, yySymbol yytoken, const short** yyconflicts)
+yygetLRActions (yy_state_t yystate, yysymbol_kind_t yytoken, const short** yyconflicts)
 {
   int yyindex = yypact[yystate] + yytoken;
-  if (yyisDefaultedState (yystate)
-      || yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
+  if (yytoken == ]b4_symbol(error, kind)[)
+    {
+      // This is the error token.
+      *yyconflicts = yyconfl;
+      return 0;
+    }
+  else if (yyisDefaultedState (yystate)
+           || yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
     {
       *yyconflicts = yyconfl;
       return -yydefact[yystate];
@@ -1043,8 +1092,8 @@
  * \param yystate   the current state
  * \param yysym     the nonterminal to push on the stack
  */
-static inline yyStateNum
-yyLRgotoState (yyStateNum yystate, yySymbol yysym)
+static inline yy_state_t
+yyLRgotoState (yy_state_t yystate, yysymbol_kind_t yysym)
 {
   int yyr = yypgoto[yysym - YYNTOKENS] + yystate;
   if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
@@ -1087,7 +1136,7 @@
  *  alternative actions for YYSTATE.  Assumes that YYRHS comes from
  *  stack #YYK of *YYSTACKP. */
 static void
-yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
+yyaddDeferredAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyGLRState* yystate,
                      yyGLRState* yyrhs, yyRuleNum yyrule)
 {
   yySemanticOption* yynewOption =
@@ -1102,7 +1151,7 @@
       yynewOption->yyloc = yylloc;])[
     }
   else
-    yynewOption->yyrawchar = YYEMPTY;
+    yynewOption->yyrawchar = ]b4_symbol(empty, id)[;
   yynewOption->yynext = yystate->yysemantics.yyfirstVal;
   yystate->yysemantics.yyfirstVal = yynewOption;
 
@@ -1119,14 +1168,14 @@
   yyset->yycapacity = 16;
   yyset->yystates
     = YY_CAST (yyGLRState**,
-               YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
+               YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
                          * sizeof yyset->yystates[0]));
   if (! yyset->yystates)
     return yyfalse;
   yyset->yystates[0] = YY_NULLPTR;
   yyset->yylookaheadNeeds
     = YY_CAST (yybool*,
-               YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
+               YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
                          * sizeof yyset->yylookaheadNeeds[0]));
   if (! yyset->yylookaheadNeeds)
     {
@@ -1135,7 +1184,7 @@
     }
   memset (yyset->yylookaheadNeeds,
           0,
-          YY_CAST (size_t, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
+          YY_CAST (YYSIZE_T, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
   return yytrue;
 }
 
@@ -1148,14 +1197,14 @@
 /** Initialize *YYSTACKP to a single empty stack, with total maximum
  *  capacity for all stacks of YYSIZE.  */
 static yybool
-yyinitGLRStack (yyGLRStack* yystackp, ptrdiff_t yysize)
+yyinitGLRStack (yyGLRStack* yystackp, YYPTRDIFF_T yysize)
 {
   yystackp->yyerrState = 0;
   yynerrs = 0;
   yystackp->yyspaceLeft = yysize;
   yystackp->yyitems
     = YY_CAST (yyGLRStackItem*,
-               YYMALLOC (YY_CAST (size_t, yysize)
+               YYMALLOC (YY_CAST (YYSIZE_T, yysize)
                          * sizeof yystackp->yynextFree[0]));
   if (!yystackp->yyitems)
     return yyfalse;
@@ -1181,9 +1230,9 @@
 {
   yyGLRStackItem* yynewItems;
   yyGLRStackItem* yyp0, *yyp1;
-  ptrdiff_t yynewSize;
-  ptrdiff_t yyn;
-  ptrdiff_t yysize = yystackp->yynextFree - yystackp->yyitems;
+  YYPTRDIFF_T yynewSize;
+  YYPTRDIFF_T yyn;
+  YYPTRDIFF_T yysize = yystackp->yynextFree - yystackp->yyitems;
   if (YYMAXDEPTH - YYHEADROOM < yysize)
     yyMemoryExhausted (yystackp);
   yynewSize = 2*yysize;
@@ -1191,7 +1240,7 @@
     yynewSize = YYMAXDEPTH;
   yynewItems
     = YY_CAST (yyGLRStackItem*,
-               YYMALLOC (YY_CAST (size_t, yynewSize)
+               YYMALLOC (YY_CAST (YYSIZE_T, yynewSize)
                          * sizeof yynewItems[0]));
   if (! yynewItems)
     yyMemoryExhausted (yystackp);
@@ -1256,7 +1305,7 @@
 
 /** Invalidate stack #YYK in *YYSTACKP.  */
 static inline void
-yymarkStackDeleted (yyGLRStack* yystackp, ptrdiff_t yyk)
+yymarkStackDeleted (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
 {
   if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
     yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
@@ -1280,7 +1329,7 @@
 static inline void
 yyremoveDeletes (yyGLRStack* yystackp)
 {
-  ptrdiff_t yyi, yyj;
+  YYPTRDIFF_T yyi, yyj;
   yyi = yyj = 0;
   while (yyj < yystackp->yytops.yysize)
     {
@@ -1313,8 +1362,8 @@
  * state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
  * value *YYVALP and source location *YYLOCP.  */
 static inline void
-yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
-            ptrdiff_t yyposn,
+yyglrShift (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
+            YYPTRDIFF_T yyposn,
             YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[)
 {
   yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
@@ -1323,7 +1372,7 @@
   yynewState->yyposn = yyposn;
   yynewState->yyresolved = yytrue;
   yynewState->yypred = yystackp->yytops.yystates[yyk];
-  yynewState->yysemantics.yysval = *yyvalp;]b4_locations_if([
+  yynewState->yysemantics.yyval = *yyvalp;]b4_locations_if([
   yynewState->yyloc = *yylocp;])[
   yystackp->yytops.yystates[yyk] = yynewState;
 
@@ -1334,8 +1383,8 @@
  *  state YYLRSTATE, at input position YYPOSN, with the (unresolved)
  *  semantic value of YYRHS under the action for YYRULE.  */
 static inline void
-yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
-                 ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
+yyglrShiftDefer (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
+                 YYPTRDIFF_T yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
 {
   yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
   YY_ASSERT (yynewState->yyisState);
@@ -1351,21 +1400,14 @@
   yyaddDeferredAction (yystackp, yyk, yynewState, yyrhs, yyrule);
 }
 
-#if !]b4_api_PREFIX[DEBUG
-# define YY_REDUCE_PRINT(Args)
-#else
-# define YY_REDUCE_PRINT(Args)          \
-  do {                                  \
-    if (yydebug)                        \
-      yy_reduce_print Args;             \
-  } while (0)
+#if ]b4_api_PREFIX[DEBUG
 
 /*----------------------------------------------------------------------.
 | Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
 `----------------------------------------------------------------------*/
 
 static inline void
-yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
+yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
                  yyRuleNum yyrule]b4_user_formals[)
 {
   int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
@@ -1380,8 +1422,8 @@
     {
       YY_FPRINTF ((stderr, "   $%d = ", yyi + 1));
       yy_symbol_print (stderr,
-                       yystos[yyvsp[yyi - yynrhs + 1].yystate.yylrState],
-                       &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval]b4_locations_if([,
+                       yy_accessing_symbol (yyvsp[yyi - yynrhs + 1].yystate.yylrState),
+                       &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yyval]b4_locations_if([,
                        &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
                        b4_user_args[);
       if (!yyvsp[yyi - yynrhs + 1].yystate.yyresolved)
@@ -1398,7 +1440,7 @@
  *  and *YYLOCP to the computed location (if any).  Return value is as
  *  for userAction.  */
 static inline YYRESULTTAG
-yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
+yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
             YYSTYPE* yyvalp]b4_locuser_formals[)
 {
   int yynrhs = yyrhsLength (yyrule);
@@ -1412,8 +1454,7 @@
       yystackp->yynextFree -= yynrhs;
       yystackp->yyspaceLeft += yynrhs;
       yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
-      YY_REDUCE_PRINT ((yytrue, yyrhs, yyk, yyrule]b4_user_args[));
-      return yyuserAction (yyrule, yynrhs, yyrhs, yystackp,
+      return yyuserAction (yyrule, yynrhs, yyrhs, yystackp, yyk,
                            yyvalp]b4_locuser_args[);
     }
   else
@@ -1432,9 +1473,8 @@
         }
       yyupdateSplit (yystackp, yys);
       yystackp->yytops.yystates[yyk] = yys;
-      YY_REDUCE_PRINT ((yyfalse, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule]b4_user_args[));
       return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
-                           yystackp, yyvalp]b4_locuser_args[);
+                           yystackp, yyk, yyvalp]b4_locuser_args[);
     }
 }
 
@@ -1450,35 +1490,34 @@
  *  added to the options for the existing state's semantic value.
  */
 static inline YYRESULTTAG
-yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
+yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
              yybool yyforceEval]b4_user_formals[)
 {
-  ptrdiff_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
+  YYPTRDIFF_T yyposn = yystackp->yytops.yystates[yyk]->yyposn;
 
   if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
     {
-      YYSTYPE yysval;]b4_locations_if([[
+      YYSTYPE yyval;]b4_locations_if([[
       YYLTYPE yyloc;]])[
 
-      YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
+      YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yyval]b4_locuser_args([&yyloc])[);
       if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
         YY_DPRINTF ((stderr,
                      "Parse on stack %ld rejected by rule %d (line %d).\n",
-                     YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1]));
+                     YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule]));
       if (yyflag != yyok)
         return yyflag;
-      YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyrule], &yysval, &yyloc);
       yyglrShift (yystackp, yyk,
                   yyLRgotoState (yystackp->yytops.yystates[yyk]->yylrState,
                                  yylhsNonterm (yyrule)),
-                  yyposn, &yysval]b4_locations_if([, &yyloc])[);
+                  yyposn, &yyval]b4_locations_if([, &yyloc])[);
     }
   else
     {
-      ptrdiff_t yyi;
+      YYPTRDIFF_T yyi;
       int yyn;
       yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
-      yyStateNum yynewLRState;
+      yy_state_t yynewLRState;
 
       for (yys = yystackp->yytops.yystates[yyk], yyn = yyrhsLength (yyrule);
            0 < yyn; yyn -= 1)
@@ -1491,7 +1530,7 @@
       YY_DPRINTF ((stderr,
                    "Reduced stack %ld by rule %d (line %d); action deferred.  "
                    "Now in state %d.\n",
-                   YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1],
+                   YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule],
                    yynewLRState));
       for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
         if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
@@ -1517,8 +1556,8 @@
   return yyok;
 }
 
-static ptrdiff_t
-yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
+static YYPTRDIFF_T
+yysplitStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
 {
   if (yystackp->yysplitPoint == YY_NULLPTR)
     {
@@ -1527,8 +1566,8 @@
     }
   if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
     {
-      ptrdiff_t state_size = sizeof yystackp->yytops.yystates[0];
-      ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
+      YYPTRDIFF_T state_size = YYSIZEOF (yystackp->yytops.yystates[0]);
+      YYPTRDIFF_T half_max_capacity = YYSIZE_MAXIMUM / 2 / state_size;
       if (half_max_capacity < yystackp->yytops.yycapacity)
         yyMemoryExhausted (yystackp);
       yystackp->yytops.yycapacity *= 2;
@@ -1537,7 +1576,7 @@
         yyGLRState** yynewStates
           = YY_CAST (yyGLRState**,
                      YYREALLOC (yystackp->yytops.yystates,
-                                (YY_CAST (size_t, yystackp->yytops.yycapacity)
+                                (YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
                                  * sizeof yynewStates[0])));
         if (yynewStates == YY_NULLPTR)
           yyMemoryExhausted (yystackp);
@@ -1548,7 +1587,7 @@
         yybool* yynewLookaheadNeeds
           = YY_CAST (yybool*,
                      YYREALLOC (yystackp->yytops.yylookaheadNeeds,
-                                (YY_CAST (size_t, yystackp->yytops.yycapacity)
+                                (YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
                                  * sizeof yynewLookaheadNeeds[0])));
         if (yynewLookaheadNeeds == YY_NULLPTR)
           yyMemoryExhausted (yystackp);
@@ -1602,12 +1641,12 @@
       else if (yys0->yyresolved)
         {
           yys1->yyresolved = yytrue;
-          yys1->yysemantics.yysval = yys0->yysemantics.yysval;
+          yys1->yysemantics.yyval = yys0->yysemantics.yyval;
         }
       else if (yys1->yyresolved)
         {
           yys0->yyresolved = yytrue;
-          yys0->yysemantics.yysval = yys1->yysemantics.yysval;
+          yys0->yysemantics.yyval = yys1->yysemantics.yyval;
         }
       else
         {
@@ -1661,8 +1700,8 @@
   return 0;
 }
 
-static YYRESULTTAG yyresolveValue (yyGLRState* yys,
-                                   yyGLRStack* yystackp]b4_user_formals[);
+static YYRESULTTAG
+yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[);
 
 
 /** Resolve the previous YYN states starting at and including state YYS
@@ -1718,7 +1757,7 @@
     yylloc = yyopt->yyloc;])[
     yyflag = yyuserAction (yyopt->yyrule, yynrhs,
                            yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
-                           yystackp, yyvalp]b4_locuser_args[);
+                           yystackp, -1, yyvalp]b4_locuser_args[);
     yychar = yychar_current;
     yylval = yylval_current;]b4_locations_if([
     yylloc = yylloc_current;])[
@@ -1748,11 +1787,11 @@
 
   if (yyx->yystate->yyposn < yys->yyposn + 1)
     YY_FPRINTF ((stderr, "%*s%s -> <Rule %d, empty>\n",
-                 yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
+                 yyindent, "", yysymbol_name (yylhsNonterm (yyx->yyrule)),
                  yyx->yyrule - 1));
   else
     YY_FPRINTF ((stderr, "%*s%s -> <Rule %d, tokens %ld .. %ld>\n",
-                 yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
+                 yyindent, "", yysymbol_name (yylhsNonterm (yyx->yyrule)),
                  yyx->yyrule - 1, YY_CAST (long, yys->yyposn + 1),
                  YY_CAST (long, yyx->yystate->yyposn)));
   for (yyi = 1; yyi <= yynrhs; yyi += 1)
@@ -1761,10 +1800,10 @@
         {
           if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
             YY_FPRINTF ((stderr, "%*s%s <empty>\n", yyindent+2, "",
-                         yytokenName (yystos[yystates[yyi]->yylrState])));
+                         yysymbol_name (yy_accessing_symbol (yystates[yyi]->yylrState))));
           else
             YY_FPRINTF ((stderr, "%*s%s <tokens %ld .. %ld>\n", yyindent+2, "",
-                         yytokenName (yystos[yystates[yyi]->yylrState]),
+                         yysymbol_name (yy_accessing_symbol (yystates[yyi]->yylrState)),
                          YY_CAST (long, yystates[yyi-1]->yyposn + 1),
                          YY_CAST (long, yystates[yyi]->yyposn)));
         }
@@ -1778,8 +1817,8 @@
 yyreportAmbiguity (yySemanticOption* yyx0,
                    yySemanticOption* yyx1]b4_pure_formals[)
 {
-  YYUSE (yyx0);
-  YYUSE (yyx1);
+  YY_USE (yyx0);
+  YY_USE (yyx1);
 
 #if ]b4_api_PREFIX[DEBUG
   YY_FPRINTF ((stderr, "Ambiguity detected.\n"));
@@ -1853,7 +1892,7 @@
   yySemanticOption* yybest = yyoptionList;
   yySemanticOption** yypp;
   yybool yymerge = yyfalse;
-  YYSTYPE yysval;
+  YYSTYPE yyval;
   YYRESULTTAG yyflag;]b4_locations_if([
   YYLTYPE *yylocp = &yys->yyloc;])[
 
@@ -1897,33 +1936,33 @@
     {
       yySemanticOption* yyp;
       int yyprec = yydprec[yybest->yyrule];
-      yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
+      yyflag = yyresolveAction (yybest, yystackp, &yyval]b4_locuser_args[);
       if (yyflag == yyok)
         for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext)
           {
             if (yyprec == yydprec[yyp->yyrule])
               {
-                YYSTYPE yysval_other;]b4_locations_if([
+                YYSTYPE yyval_other;]b4_locations_if([
                 YYLTYPE yydummy;])[
-                yyflag = yyresolveAction (yyp, yystackp, &yysval_other]b4_locuser_args([&yydummy])[);
+                yyflag = yyresolveAction (yyp, yystackp, &yyval_other]b4_locuser_args([&yydummy])[);
                 if (yyflag != yyok)
                   {
                     yydestruct ("Cleanup: discarding incompletely merged value for",
-                                yystos[yys->yylrState],
-                                &yysval]b4_locuser_args[);
+                                yy_accessing_symbol (yys->yylrState),
+                                &yyval]b4_locuser_args[);
                     break;
                   }
-                yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other);
+                yyuserMerge (yymerger[yyp->yyrule], &yyval, &yyval_other);
               }
           }
     }
   else
-    yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args([yylocp])[);
+    yyflag = yyresolveAction (yybest, yystackp, &yyval]b4_locuser_args([yylocp])[);
 
   if (yyflag == yyok)
     {
       yys->yyresolved = yytrue;
-      yys->yysemantics.yysval = yysval;
+      yys->yysemantics.yyval = yyval;
     }
   else
     yys->yysemantics.yyfirstVal = YY_NULLPTR;
@@ -1948,18 +1987,24 @@
   return yyok;
 }
 
+/** Called when returning to deterministic operation to clean up the extra
+ * stacks. */
 static void
 yycompressStack (yyGLRStack* yystackp)
 {
-  yyGLRState* yyp, *yyq, *yyr;
+  /* yyr is the state after the split point.  */
+  yyGLRState *yyr;
 
   if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR)
     return;
 
-  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;
+  {
+    yyGLRState *yyp, *yyq;
+    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;
+  }
 
   yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
   yystackp->yynextFree = YY_REINTERPRET_CAST (yyGLRStackItem*, yystackp->yysplitPoint) + 1;
@@ -1979,13 +2024,14 @@
 }
 
 static YYRESULTTAG
-yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
-                   ptrdiff_t yyposn]b4_pure_formals[)
+yyprocessOneStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk,
+                   YYPTRDIFF_T yyposn]b4_pure_formals[)
 {
   while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
     {
-      yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
-      YY_DPRINTF ((stderr, "Stack %ld Entering state %d\n", YY_CAST (long, yyk), yystate));
+      yy_state_t yystate = yystackp->yytops.yystates[yyk]->yylrState;
+      YY_DPRINTF ((stderr, "Stack %ld Entering state %d\n",
+                   YY_CAST (long, yyk), yystate));
 
       YY_ASSERT (yystate != YYFINAL);
 
@@ -2014,15 +2060,15 @@
         }
       else
         {
-          yySymbol yytoken = ]b4_yygetToken_call[;
+          yysymbol_kind_t yytoken = ]b4_yygetToken_call[;
           const short* yyconflicts;
           const int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
           yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
 
-          while (*yyconflicts != 0)
+          for (/* nothing */; *yyconflicts; yyconflicts += 1)
             {
               YYRESULTTAG yyflag;
-              ptrdiff_t yynewStack = yysplitStack (yystackp, yyk);
+              YYPTRDIFF_T yynewStack = yysplitStack (yystackp, yyk);
               YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
                            YY_CAST (long, yynewStack), YY_CAST (long, yyk)));
               yyflag = yyglrReduce (yystackp, yynewStack,
@@ -2038,7 +2084,6 @@
                 }
               else
                 return yyflag;
-              yyconflicts += 1;
             }
 
           if (yyisShiftAction (yyaction))
@@ -2070,29 +2115,82 @@
   return yyok;
 }
 
-static void
-yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
+]b4_parse_error_case([simple], [],
+[[/* Put in YYARG at most YYARGN of the expected tokens given the
+   current YYSTACKP, and return the number of tokens stored in YYARG.  If
+   YYARG is null, return the number of expected tokens (guaranteed to
+   be less than YYNTOKENS).  */
+static int
+yypcontext_expected_tokens (const yyGLRStack* yystackp,
+                            yysymbol_kind_t yyarg[], int yyargn)
 {
-  if (yystackp->yyerrState != 0)
-    return;
-#if ! YYERROR_VERBOSE
-  yyerror (]b4_lyyerror_args[YY_("syntax error"));
-#else
-  {
-  yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-  yybool yysize_overflow = yyfalse;
-  char* yymsg = YY_NULLPTR;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat: reported tokens (one for the "unexpected",
-     one per "expected"). */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Actual size of YYARG. */
   int yycount = 0;
-  /* Cumulated lengths of YYARG.  */
-  ptrdiff_t yysize = 0;
+  int yyn = yypact[yystackp->yytops.yystates[0]->yylrState];
+  if (!yypact_value_is_default (yyn))
+    {
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+         YYCHECK.  In other words, skip the first -YYN actions for
+         this state because they are default actions.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yyx;
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+        if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+            && !yytable_value_is_error (yytable[yyx + yyn]))
+          {
+            if (!yyarg)
+              ++yycount;
+            else if (yycount == yyargn)
+              return 0;
+            else
+              yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
+          }
+    }
+  if (yyarg && yycount == 0 && 0 < yyargn)
+    yyarg[0] = ]b4_symbol(empty, kind)[;
+  return yycount;
+}]])[
 
+]b4_parse_error_bmatch(
+         [custom],
+[[/* User defined function to report a syntax error.  */
+typedef yyGLRStack yypcontext_t;
+static int
+yyreport_syntax_error (const yyGLRStack* yystackp]b4_user_formals[);
+
+/* The kind of the lookahead of this context.  */
+static yysymbol_kind_t
+yypcontext_token (const yyGLRStack *yystackp) YY_ATTRIBUTE_UNUSED;
+
+static yysymbol_kind_t
+yypcontext_token (const yyGLRStack *yystackp)
+{
+  YY_USE (yystackp);
+  yysymbol_kind_t yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
+  return yytoken;
+}
+
+]b4_locations_if([[/* The location of the lookahead of this context.  */
+static const YYLTYPE *
+yypcontext_location (const yyGLRStack *yystackp) YY_ATTRIBUTE_UNUSED;
+
+static const YYLTYPE *
+yypcontext_location (const yyGLRStack *yystackp)
+{
+  YY_USE (yystackp);
+  return &yylloc;
+}]])],
+         [detailed\|verbose],
+[[static int
+yy_syntax_error_arguments (const yyGLRStack* yystackp,
+                           yysymbol_kind_t yyarg[], int yyargn)
+{
+  yysymbol_kind_t yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
+  /* Actual size of YYARG. */
+  int yycount = 0;
   /* There are many possibilities here to consider:
      - If this state is a consistent state with a default action, then
        the only way this function was invoked is if the default action
@@ -2116,43 +2214,52 @@
        one exception: it will still contain any token that will not be
        accepted due to an error action in a later state.
   */
-  if (yytoken != YYEMPTY)
+  if (yytoken != ]b4_symbol(empty, kind)[)
     {
-      int yyn = yypact[yystackp->yytops.yystates[0]->yylrState];
-      ptrdiff_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
-      yysize = yysize0;
-      yyarg[yycount++] = yytokenName (yytoken);
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for this
-             state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytokenName (yyx);
-                {
-                  ptrdiff_t yysz = yytnamerr (YY_NULLPTR, yytokenName (yyx));
-                  if (YYSIZEMAX - yysize < yysz)
-                    yysize_overflow = yytrue;
-                  else
-                    yysize += yysz;
-                }
-              }
-        }
+      int yyn;
+      if (yyarg)
+        yyarg[yycount] = yytoken;
+      ++yycount;
+      yyn = yypcontext_expected_tokens (yystackp,
+                                        yyarg ? yyarg + 1 : yyarg, yyargn - 1);
+      if (yyn == YYENOMEM)
+        return YYENOMEM;
+      else
+        yycount += yyn;
     }
+  return yycount;
+}
+]])[
+
+
+static void
+yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
+{
+  if (yystackp->yyerrState != 0)
+    return;
+]b4_parse_error_case(
+         [custom],
+[[  if (yyreport_syntax_error (yystackp]b4_user_args[))
+    yyMemoryExhausted (yystackp);]],
+         [simple],
+[[  yyerror (]b4_lyyerror_args[YY_("syntax error"));]],
+[[  {
+  yybool yysize_overflow = yyfalse;
+  char* yymsg = YY_NULLPTR;
+  enum { YYARGS_MAX = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat: reported tokens (one for the "unexpected",
+     one per "expected"). */
+  yysymbol_kind_t yyarg[YYARGS_MAX];
+  /* Cumulated lengths of YYARG.  */
+  YYPTRDIFF_T yysize = 0;
+
+  /* Actual size of YYARG. */
+  int yycount
+    = yy_syntax_error_arguments (yystackp, yyarg, YYARGS_MAX);
+  if (yycount == YYENOMEM)
+    yyMemoryExhausted (yystackp);
 
   switch (yycount)
     {
@@ -2170,18 +2277,26 @@
 #undef YYCASE_
     }
 
+  /* Compute error message size.  Don't count the "%s"s, but reserve
+     room for the terminator.  */
+  yysize = yystrlen (yyformat) - 2 * yycount + 1;
   {
-    /* Don't count the "%s"s in the final size, but reserve room for
-       the terminator.  */
-    ptrdiff_t yysz = YY_CAST (ptrdiff_t, strlen (yyformat)) - 2 * yycount + 1;
-    if (YYSIZEMAX - yysize < yysz)
-      yysize_overflow = yytrue;
-    else
-      yysize += yysz;
+    int yyi;
+    for (yyi = 0; yyi < yycount; ++yyi)
+      {
+        YYPTRDIFF_T yysz
+          = ]b4_parse_error_case(
+                     [verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]],
+                     [[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
+        if (YYSIZE_MAXIMUM - yysize < yysz)
+          yysize_overflow = yytrue;
+        else
+          yysize += yysz;
+      }
   }
 
   if (!yysize_overflow)
-    yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (size_t, yysize)));
+    yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (YYSIZE_T, yysize)));
 
   if (yymsg)
     {
@@ -2190,8 +2305,9 @@
       while ((*yyp = *yyformat))
         {
           if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-            {
-              yyp += yytnamerr (yyp, yyarg[yyi++]);
+            {]b4_parse_error_case([verbose], [[
+              yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]);]], [[
+              yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++]));]])[
               yyformat += 2;
             }
           else
@@ -2208,8 +2324,7 @@
       yyerror (]b4_lyyerror_args[YY_("syntax error"));
       yyMemoryExhausted (yystackp);
     }
-  }
-#endif /* YYERROR_VERBOSE */
+  }]])[
   yynerrs += 1;
 }
 
@@ -2224,11 +2339,11 @@
        reductions.  Skip tokens until we can proceed.  */
     while (yytrue)
       {
-        yySymbol yytoken;
+        yysymbol_kind_t yytoken;
         int yyj;
-        if (yychar == YYEOF)
+        if (yychar == ]b4_symbol(eof, [id])[)
           yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
-        if (yychar != YYEMPTY)
+        if (yychar != ]b4_symbol(empty, id)[)
           {]b4_locations_if([[
             /* We throw away the lookahead, but the error range
                of the shifted error token must take it into account.  */
@@ -2240,7 +2355,7 @@
             yytoken = YYTRANSLATE (yychar);
             yydestruct ("Error: discarding",
                         yytoken, &yylval]b4_locuser_args([&yylloc])[);
-            yychar = YYEMPTY;
+            yychar = ]b4_symbol(empty, id)[;
           }
         yytoken = ]b4_yygetToken_call[;
         yyj = yypact[yystackp->yytops.yystates[0]->yylrState];
@@ -2258,7 +2373,7 @@
 
   /* Reduce to one stack.  */
   {
-    ptrdiff_t yyk;
+    YYPTRDIFF_T yyk;
     for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
       if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
         break;
@@ -2270,7 +2385,7 @@
     yycompressStack (yystackp);
   }
 
-  /* Now pop stack until we find a state that shifts the error token.  */
+  /* Pop stack until we find a state that shifts the error token.  */
   yystackp->yyerrState = 3;
   while (yystackp->yytops.yystates[0] != YY_NULLPTR)
     {
@@ -2278,8 +2393,8 @@
       int yyj = yypact[yys->yylrState];
       if (! yypact_value_is_default (yyj))
         {
-          yyj += YYTERROR;
-          if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR
+          yyj += ]b4_symbol(error, kind)[;
+          if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol(error, kind)[
               && yyisShiftAction (yytable[yyj]))
             {
               /* Shift the error token.  */
@@ -2288,7 +2403,7 @@
               YYLTYPE yyerrloc;
               yystackp->yyerror_range[2].yystate.yyloc = yylloc;
               YYLLOC_DEFAULT (yyerrloc, (yystackp->yyerror_range), 2);]])[
-              YY_SYMBOL_PRINT ("Shifting", yystos[yyaction],
+              YY_SYMBOL_PRINT ("Shifting", yy_accessing_symbol (yyaction),
                                &yylval, &yyerrloc);
               yyglrShift (yystackp, 0, yyaction,
                           yys->yyposn, &yylval]b4_locations_if([, &yyerrloc])[);
@@ -2307,36 +2422,33 @@
     yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
 }
 
-#define YYCHK1(YYE)                                                          \
-  do {                                                                       \
-    switch (YYE) {                                                           \
-    case yyok:                                                               \
-      break;                                                                 \
-    case yyabort:                                                            \
-      goto yyabortlab;                                                       \
-    case yyaccept:                                                           \
-      goto yyacceptlab;                                                      \
-    case yyerr:                                                              \
-      goto yyuser_error;                                                     \
-    default:                                                                 \
-      goto yybuglab;                                                         \
-    }                                                                        \
+#define YYCHK1(YYE)                             \
+  do {                                          \
+    switch (YYE) {                              \
+    case yyok:     break;                       \
+    case yyabort:  goto yyabortlab;             \
+    case yyaccept: goto yyacceptlab;            \
+    case yyerr:    goto yyuser_error;           \
+    case yynomem:  goto yyexhaustedlab;         \
+    default:       goto yybuglab;               \
+    }                                           \
   } while (0)
 
 /*----------.
 | yyparse.  |
 `----------*/
 
-]b4_function_define([yyparse], [int], b4_parse_param)[
+int
+]b4_glr_cc_if([yy_parse_impl], [yyparse])[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
 {
   int yyresult;
   yyGLRStack yystack;
   yyGLRStack* const yystackp = &yystack;
-  ptrdiff_t yyposn;
+  YYPTRDIFF_T yyposn;
 
   YY_DPRINTF ((stderr, "Starting parse\n"));
 
-  yychar = YYEMPTY;
+  yychar = ]b4_symbol(empty, id)[;
   yylval = yyval_default;]b4_locations_if([
   yylloc = yyloc_default;])[
 ]m4_ifdef([b4_initial_action], [
@@ -2361,10 +2473,10 @@
       /* For efficiency, we have two loops, the first of which is
          specialized to deterministic operation (single stack, no
          potential ambiguity).  */
-      /* Standard mode */
+      /* Standard mode. */
       while (yytrue)
         {
-          yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
+          yy_state_t yystate = yystack.yytops.yystates[0]->yylrState;
           YY_DPRINTF ((stderr, "Entering state %d\n", yystate));
           if (yystate == YYFINAL)
             goto yyacceptlab;
@@ -2381,15 +2493,16 @@
             }
           else
             {
-              yySymbol yytoken = ]b4_yygetToken_call;[
+              yysymbol_kind_t yytoken = ]b4_yygetToken_call;[
               const short* yyconflicts;
               int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
-              if (*yyconflicts != 0)
+              if (*yyconflicts)
+                /* Enter nondeterministic mode.  */
                 break;
               if (yyisShiftAction (yyaction))
                 {
                   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-                  yychar = YYEMPTY;
+                  yychar = ]b4_symbol(empty, id)[;
                   yyposn += 1;
                   yyglrShift (&yystack, 0, yyaction, yyposn, &yylval]b4_locations_if([, &yylloc])[);
                   if (0 < yystack.yyerrState)
@@ -2397,11 +2510,11 @@
                 }
               else if (yyisErrorAction (yyaction))
                 {]b4_locations_if([[
-                  yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[]b4_glr_cc_if([[
-                  /* Don't issue an error message again for exceptions
-                     thrown from the scanner.  */
-                  if (yychar != YYFAULTYTOK)
-  ]])[                  yyreportSyntaxError (&yystack]b4_user_args[);
+                  yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
+                  /* Issue an error message unless the scanner already
+                     did. */
+                  if (yychar != ]b4_symbol(error, id)[)
+                    yyreportSyntaxError (&yystack]b4_user_args[);
                   goto yyuser_error;
                 }
               else
@@ -2409,13 +2522,14 @@
             }
         }
 
+      /* Nondeterministic mode. */
       while (yytrue)
         {
-          yySymbol yytoken_to_shift;
-          ptrdiff_t yys;
+          yysymbol_kind_t yytoken_to_shift;
+          YYPTRDIFF_T yys;
 
           for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
-            yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY;
+            yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(empty, id)[;
 
           /* yyprocessOneStack returns one of three things:
 
@@ -2453,15 +2567,15 @@
 
           /* If any yyglrShift call fails, it will fail after shifting.  Thus,
              a copy of yylval will already be on stack 0 in the event of a
-             failure in the following loop.  Thus, yychar is set to YYEMPTY
+             failure in the following loop.  Thus, yychar is set to ]b4_symbol(empty, id)[
              before the loop to make sure the user destructor for yylval isn't
              called twice.  */
           yytoken_to_shift = YYTRANSLATE (yychar);
-          yychar = YYEMPTY;
+          yychar = ]b4_symbol(empty, id)[;
           yyposn += 1;
           for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
             {
-              yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
+              yy_state_t yystate = yystack.yytops.yystates[yys]->yylrState;
               const short* yyconflicts;
               int yyaction = yygetLRActions (yystate, yytoken_to_shift,
                               &yyconflicts);
@@ -2470,7 +2584,7 @@
               YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
               yyglrShift (&yystack, yys, yyaction, yyposn,
                           &yylval]b4_locations_if([, &yylloc])[);
-              YY_DPRINTF ((stderr, "Stack %ld now in state #%d\n",
+              YY_DPRINTF ((stderr, "Stack %ld now in state %d\n",
                            YY_CAST (long, yys),
                            yystack.yytops.yystates[yys]->yylrState));
             }
@@ -2491,7 +2605,7 @@
 
  yyacceptlab:
   yyresult = 0;
-  goto yyreturn;
+  goto yyreturnlab;
 
  yybuglab:
   YY_ASSERT (yyfalse);
@@ -2499,15 +2613,15 @@
 
  yyabortlab:
   yyresult = 1;
-  goto yyreturn;
+  goto yyreturnlab;
 
  yyexhaustedlab:
   yyerror (]b4_lyyerror_args[YY_("memory exhausted"));
   yyresult = 2;
-  goto yyreturn;
+  goto yyreturnlab;
 
- yyreturn:
-  if (yychar != YYEMPTY)
+ yyreturnlab:
+  if (yychar != ]b4_symbol(empty, id)[)
     yydestruct ("Cleanup: discarding lookahead",
                 YYTRANSLATE (yychar), &yylval]b4_locuser_args([&yylloc])[);
 
@@ -2519,8 +2633,8 @@
       yyGLRState** yystates = yystack.yytops.yystates;
       if (yystates)
         {
-          ptrdiff_t yysize = yystack.yytops.yysize;
-          ptrdiff_t yyk;
+          YYPTRDIFF_T yysize = yystack.yytops.yysize;
+          YYPTRDIFF_T yyk;
           for (yyk = 0; yyk < yysize; yyk += 1)
             if (yystates[yyk])
               {
@@ -2545,6 +2659,7 @@
 
 /* DEBUGGING ONLY */
 #if ]b4_api_PREFIX[DEBUG
+/* Print *YYS and its predecessors. */
 static void
 yy_yypstack (yyGLRState* yys)
 {
@@ -2556,22 +2671,25 @@
   YY_FPRINTF ((stderr, "%d@@%ld", yys->yylrState, YY_CAST (long, yys->yyposn)));
 }
 
+/* Print YYS (possibly NULL) and its predecessors. */
 static void
-yypstates (yyGLRState* yyst)
+yypstates (yyGLRState* yys)
 {
-  if (yyst == YY_NULLPTR)
+  if (yys == YY_NULLPTR)
     YY_FPRINTF ((stderr, "<null>"));
   else
-    yy_yypstack (yyst);
+    yy_yypstack (yys);
   YY_FPRINTF ((stderr, "\n"));
 }
 
+/* Print the stack #YYK.  */
 static void
-yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
+yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
 {
   yypstates (yystackp->yytops.yystates[yyk]);
 }
 
+/* Print all the stacks.  */
 static void
 yypdumpstack (yyGLRStack* yystackp)
 {
@@ -2612,7 +2730,7 @@
 
   YY_FPRINTF ((stderr, "Tops:"));
   {
-    ptrdiff_t yyi;
+    YYPTRDIFF_T yyi;
     for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
       YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi),
                    YYINDEX (yystackp->yytops.yystates[yyi])));
@@ -2638,5 +2756,8 @@
 #define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
 #define yylloc  ]b4_prefix[lloc]])])[
 
-]b4_epilogue[]dnl
+]b4_glr_cc_if([b4_glr_cc_pre_epilogue
+b4_glr_cc_cleanup])[
+]b4_percent_code_get([[epilogue]])[]dnl
+b4_epilogue[]dnl
 b4_output_end
diff --git a/common/bison/skeletons/glr.cc b/common/bison/skeletons/glr.cc
index 343b52e..7181402 100644
--- a/common/bison/skeletons/glr.cc
+++ b/common/bison/skeletons/glr.cc
@@ -1,6 +1,6 @@
 # C++ GLR skeleton for Bison
 
-# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,7 +13,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 
 # This skeleton produces a C++ class that encapsulates a C glr parser.
@@ -72,24 +72,17 @@
 # Bypass the default implementation to generate the "yy_symbol_print"
 # and "yy_symbol_value_print" functions.
 m4_define([b4_yy_symbol_print_define],
-[[
-/*--------------------.
+[[/*--------------------.
 | Print this symbol.  |
 `--------------------*/
 
-]b4_function_define([yy_symbol_print],
-    [static void],
-    [[FILE *],      []],
-    [[int yytype],  [yytype]],
-    [[const ]b4_namespace_ref::b4_parser_class[::semantic_type *yyvaluep],
-                    [yyvaluep]][]dnl
-b4_locations_if([,
-    [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp],
-                    [yylocationp]]]),
-    b4_parse_param)[
+static void
+yy_symbol_print (FILE *, ]b4_namespace_ref::b4_parser_class[::symbol_kind_type yytoken,
+                 const ]b4_namespace_ref::b4_parser_class[::value_type *yyvaluep]b4_locations_if([[,
+                 const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp]])[]b4_user_formals[)
 {
 ]b4_parse_param_use[]dnl
-[  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
+[  yyparser.yy_symbol_print_ (yytoken, yyvaluep]b4_locations_if([, yylocationp])[);
 }
 ]])[
 
@@ -101,45 +94,24 @@
 # Hijack the post prologue to declare yyerror.
 ]m4_append([b4_post_prologue],
 [b4_syncline([@oline@], [@ofile@])dnl
-b4_function_declare([yyerror],
-    [static void],b4_locations_if([
-    [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp],
-                        [yylocationp]],])
-    b4_parse_param,
-    [[const char* msg], [msg]])])[
+[static void
+yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp,
+         ]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
+         ])[const char* msg);]])[
 
-
-#undef yynerrs
-#undef yychar
-#undef yylval]b4_locations_if([
-#undef yylloc])
-
-m4_if(b4_prefix, [yy], [],
-[[/* Substitute the variable and function names.  */
-#define yyparse ]b4_prefix[parse
-#define yylex   ]b4_prefix[lex
-#define yyerror ]b4_prefix[error
-#define yydebug ]b4_prefix[debug]]b4_pure_if([], [[
-#define yylval  ]b4_prefix[lval
-#define yychar  ]b4_prefix[char
-#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
-#define yylloc  ]b4_prefix[lloc]])]))
-
-# Hijack the epilogue to define implementations (yyerror, parser member
+# Inserted before the epilogue to define implementations (yyerror, parser member
 # functions etc.).
-m4_append([b4_epilogue],
+]m4_define([b4_glr_cc_pre_epilogue],
 [b4_syncline([@oline@], [@ofile@])dnl
 [
 /*------------------.
 | Report an error.  |
 `------------------*/
 
-]b4_function_define([yyerror],
-    [static void],b4_locations_if([
-    [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp],
-                        [yylocationp]],])
-    b4_parse_param,
-    [[const char* msg], [msg]])[
+static void
+yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp,
+         ]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
+         ])[const char* msg)
 {
 ]b4_parse_param_use[]dnl
 [  yyparser.error (]b4_locations_if([[*yylocationp, ]])[msg);
@@ -172,7 +144,7 @@
   int
   ]b4_parser_class[::parse ()
   {
-    return ::yyparse (*this]b4_user_args[);
+    return ::yy_parse_impl (*this]b4_user_args[);
   }
 
 #if ]b4_api_PREFIX[DEBUG
@@ -181,28 +153,28 @@
   `--------------------*/
 
   void
-  ]b4_parser_class[::yy_symbol_value_print_ (int yytype,
-                           const semantic_type* yyvaluep]b4_locations_if([[,
-                           const location_type* yylocationp]])[)
+  ]b4_parser_class[::yy_symbol_value_print_ (symbol_kind_type yykind,
+                           const value_type* yyvaluep]b4_locations_if([[,
+                           const location_type* yylocationp]])[) const
   {]b4_locations_if([[
-    YYUSE (yylocationp);]])[
-    YYUSE (yyvaluep);
+    YY_USE (yylocationp);]])[
+    YY_USE (yyvaluep);
     std::ostream& yyo = debug_stream ();
     std::ostream& yyoutput = yyo;
-    YYUSE (yyoutput);
+    YY_USE (yyoutput);
     ]b4_symbol_actions([printer])[
   }
 
 
   void
-  ]b4_parser_class[::yy_symbol_print_ (int yytype,
-                           const semantic_type* yyvaluep]b4_locations_if([[,
-                           const location_type* yylocationp]])[)
+  ]b4_parser_class[::yy_symbol_print_ (symbol_kind_type yykind,
+                           const value_type* yyvaluep]b4_locations_if([[,
+                           const location_type* yylocationp]])[) const
   {
-    *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
-               << ' ' << yytname[yytype] << " ("]b4_locations_if([[
+    *yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
+               << ' ' << yysymbol_name (yykind) << " ("]b4_locations_if([[
                << *yylocationp << ": "]])[;
-    yy_symbol_value_print_ (yytype, yyvaluep]b4_locations_if([[, yylocationp]])[);
+    yy_symbol_value_print_ (yykind, yyvaluep]b4_locations_if([[, yylocationp]])[);
     *yycdebug_ << ')';
   }
 
@@ -238,23 +210,18 @@
 ])
 
 
-# b4_shared_declarations(hh|cc)
-# -----------------------------
-# Declaration that might either go into the header (if --defines, $1 = hh)
-# or in the implementation file.
-m4_define([b4_shared_declarations],
-[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
-b4_percent_code_get([[requires]])[
-#include <iostream>
-#include <stdexcept>
-#include <string>
+m4_define([b4_define_symbol_kind],
+[m4_format([#define %-15s %s],
+           b4_symbol($][1, kind_base),
+           b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($1, kind_base))
+])
 
-]b4_cxx_portability[
-]m4_ifdef([b4_location_include],
-          [[# include ]b4_location_include])[
-]b4_variant_if([b4_variant_includes])[
-
-]b4_attribute_define[
+# b4_glr_cc_setup
+# ---------------
+# Setup redirections for glr.c: Map the names used in c.m4 to the ones used
+# in c++.m4.
+m4_define([b4_glr_cc_setup],
+[[]b4_attribute_define[
 ]b4_null_define[
 
 // This skeleton is based on C, yet compiles it as C++.
@@ -267,10 +234,67 @@
 
 // On MacOS, PTRDIFF_MAX is defined as long long, which Clang's
 // -pedantic reports as being a C++11 extension.
-#if defined __APPLE__ && YY_CPLUSPLUS < 201103L && 4 <= __clang_major__
+#if defined __APPLE__ && YY_CPLUSPLUS < 201103L \
+    && defined __clang__ && 4 <= __clang_major__
 # pragma clang diagnostic ignored "-Wc++11-long-long"
 #endif
 
+#undef ]b4_symbol(empty, [id])[
+#define ]b4_symbol(empty, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, [id])[
+#undef ]b4_symbol(eof, [id])[
+#define ]b4_symbol(eof, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, [id])[
+#undef ]b4_symbol(error, [id])[
+#define ]b4_symbol(error, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(error, [id])[
+
+#ifndef ]b4_api_PREFIX[STYPE
+# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::value_type
+#endif
+#ifndef ]b4_api_PREFIX[LTYPE
+# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
+#endif
+
+typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
+
+// Expose C++ symbol kinds to C.
+]b4_define_symbol_kind(-2)dnl
+b4_symbol_foreach([b4_define_symbol_kind])])[
+]])
+
+
+m4_define([b4_undef_symbol_kind],
+[[#undef ]b4_symbol($1, kind_base)[
+]])
+
+
+# b4_glr_cc_cleanup
+# -----------------
+# Remove redirections for glr.c.
+m4_define([b4_glr_cc_cleanup],
+[[#undef ]b4_symbol(empty, [id])[
+#undef ]b4_symbol(eof, [id])[
+#undef ]b4_symbol(error, [id])[
+
+]b4_undef_symbol_kind(-2)dnl
+b4_symbol_foreach([b4_undef_symbol_kind])dnl
+])
+
+
+# b4_shared_declarations(hh|cc)
+# -----------------------------
+# Declaration that might either go into the header (if --header, $1 = hh)
+# or in the implementation file.
+m4_define([b4_shared_declarations],
+[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
+b4_percent_code_get([[requires]])[
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+]b4_cxx_portability[
+]m4_ifdef([b4_location_include],
+          [[# include ]b4_location_include])[
+]b4_variant_if([b4_variant_includes])[
+
 // Whether we are compiled with exception support.
 #ifndef YY_EXCEPTIONS
 # if defined __GNUC__ && !defined __EXCEPTIONS
@@ -327,53 +351,43 @@
 # if ]b4_api_PREFIX[DEBUG
   public:
     /// \brief Report a symbol value on the debug stream.
-    /// \param yytype       The token type.
+    /// \param yykind       The symbol kind.
     /// \param yyvaluep     Its semantic value.]b4_locations_if([[
     /// \param yylocationp  Its location.]])[
-    virtual void yy_symbol_value_print_ (int yytype,
-                                         const semantic_type* yyvaluep]b4_locations_if([[,
-                                         const location_type* yylocationp]])[);
+    virtual void yy_symbol_value_print_ (symbol_kind_type yykind,
+                                         const value_type* yyvaluep]b4_locations_if([[,
+                                         const location_type* yylocationp]])[) const;
     /// \brief Report a symbol on the debug stream.
-    /// \param yytype       The token type.
+    /// \param yykind       The symbol kind.
     /// \param yyvaluep     Its semantic value.]b4_locations_if([[
     /// \param yylocationp  Its location.]])[
-    virtual void yy_symbol_print_ (int yytype,
-                                   const semantic_type* yyvaluep]b4_locations_if([[,
-                                   const location_type* yylocationp]])[);
+    virtual void yy_symbol_print_ (symbol_kind_type yykind,
+                                   const value_type* yyvaluep]b4_locations_if([[,
+                                   const location_type* yylocationp]])[) const;
   private:
-    // Debugging.
+    /// Debug stream.
     std::ostream* yycdebug_;
 #endif
 
 ]b4_parse_param_vars[
   };
 
-]dnl Redirections for glr.c.
-b4_percent_define_flag_if([[global_tokens_and_yystype]],
-[b4_token_defines])
-[
-#ifndef ]b4_api_PREFIX[STYPE
-# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
-#endif
-#ifndef ]b4_api_PREFIX[LTYPE
-# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
-#endif
-
 ]b4_namespace_close[
+
 ]b4_percent_code_get([[provides]])[
 ]m4_popdef([b4_parse_param])dnl
-])
+])[
 
-b4_defines_if(
+]b4_header_if(
 [b4_output_begin([b4_spec_header_file])
 b4_copyright([Skeleton interface for Bison GLR parsers in C++],
-             [2002-2015, 2018-2019])[
+             [2002-2015, 2018-2021])[
 // C++ GLR parser skeleton written by Akim Demaille.
 
 ]b4_disclaimer[
-]b4_cpp_guard_open([b4_spec_header_file])[
+]b4_cpp_guard_open([b4_spec_mapped_header_file])[
 ]b4_shared_declarations[
-]b4_cpp_guard_close([b4_spec_header_file])[
+]b4_cpp_guard_close([b4_spec_mapped_header_file])[
 ]b4_output_end])
 
 # Let glr.c (and b4_shared_declarations) believe that the user
diff --git a/common/bison/skeletons/glr2.cc b/common/bison/skeletons/glr2.cc
new file mode 100644
index 0000000..757d68d
--- /dev/null
+++ b/common/bison/skeletons/glr2.cc
@@ -0,0 +1,3533 @@
+# C++ GLR skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+m4_include(b4_skeletonsdir/[c++.m4])
+
+# api.value.type=variant is valid.
+m4_define([b4_value_type_setup_variant])
+
+# b4_tname_if(TNAME-NEEDED, TNAME-NOT-NEEDED)
+# -------------------------------------------
+m4_define([b4_tname_if],
+[m4_case(b4_percent_define_get([[parse.error]]),
+         [verbose],         [$1],
+         [b4_token_table_if([$1],
+                            [$2])])])
+
+b4_bison_locations_if([
+   m4_define([b4_location_constructors])
+   m4_include(b4_skeletonsdir/[location.cc])])
+b4_variant_if([m4_include(b4_skeletonsdir/[variant.hh])])
+
+m4_define([b4_parser_class],
+          [b4_percent_define_get([[api.parser.class]])])
+
+]m4_define([b4_define_symbol_kind],
+[m4_format([#define %-15s %s],
+           b4_symbol($][1, kind_base),
+           b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($1, kind_base))
+])
+
+
+# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
+# -------------------------------------------------------------
+# Define "yy<TABLE-NAME>" whose contents is CONTENT.  Does not use "static",
+# should be in unnamed namespace.
+m4_define([b4_integral_parser_table_define],
+[m4_ifvaln([$3], [  b4_comment([$3])])dnl
+  const b4_int_type_for([$2]) yy$1[[]] =
+  {
+  $2
+  };dnl
+])
+
+
+## ---------------- ##
+## Default values.  ##
+## ---------------- ##
+
+# Stack parameters.
+m4_define_default([b4_stack_depth_max], [10000])
+m4_define_default([b4_stack_depth_init],  [200])
+
+
+
+## ------------ ##
+## Interfaces.  ##
+## ------------ ##
+
+# b4_user_formals
+# ---------------
+# The possible parse-params formal arguments preceded by a comma.
+#
+# This is not shared with yacc.c in c.m4 because  GLR relies on ISO C
+# formal argument declarations.
+m4_define([b4_user_formals],
+[m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])])
+
+
+# b4_symbol_kind(NUM)
+# -------------------
+m4_define([b4_symbol_kind],
+[symbol_kind::b4_symbol_kind_base($@)])
+
+
+## ----------------- ##
+## Semantic Values.  ##
+## ----------------- ##
+
+
+# b4_lhs_value(SYMBOL-NUM, [TYPE])
+# --------------------------------
+# See README.
+m4_define([b4_lhs_value],
+[b4_symbol_value([(*yyvalp)], [$1], [$2])])
+
+
+# b4_rhs_data(RULE-LENGTH, POS)
+# -----------------------------
+# See README.
+m4_define([b4_rhs_data],
+[(static_cast<glr_stack_item const *>(yyvsp))@{YYFILL (b4_subtract([$2], [$1]))@}.getState()])
+
+
+# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
+# --------------------------------------------------
+# Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
+m4_define([b4_rhs_value],
+[b4_symbol_value([b4_rhs_data([$1], [$2]).value ()], [$3], [$4])])
+
+
+
+## ----------- ##
+## Locations.  ##
+## ----------- ##
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[(*yylocp)])
+
+
+# b4_rhs_location(RULE-LENGTH, NUM)
+# ---------------------------------
+# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+[(b4_rhs_data([$1], [$2]).yyloc)])
+
+
+# b4_symbol_action(SYMBOL-NUM, KIND)
+# ----------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# Same as in C, but using references instead of pointers.
+#
+# Currently we need two different b4_symbol_action: once for the
+# self-contained symbols, and another time for yy_destroy_ and
+# yy_symbol_value_print_, which don't use genuine symbols yet.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
+b4_dollar_pushdef([yysym.value],
+                  [$1],
+                  [],
+                  [yysym.location])dnl
+      _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
+        b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])dnl
+        break;
+
+m4_popdef([b4_symbol_value])[]dnl
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_symbol_action_for_yyval(SYMBOL-NUM, KIND)
+# --------------------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# Same as in C, but using references instead of pointers.
+m4_define([b4_symbol_action_for_yyval],
+[b4_symbol_if([$1], [has_$2],
+[b4_dollar_pushdef([yyval],
+                   [$1],
+                   [],
+                   [yyloc])dnl
+      _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
+        b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])dnl
+        break;
+
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_call_merger(MERGER-NUM, MERGER-NAME, SYMBOL-SUM)
+# ---------------------------------------------------
+m4_define([b4_call_merger],
+[b4_case([$1],
+         [    b4_symbol_if([$3], [has_type],
+                           [b4_variant_if([yy0.as< b4_symbol($3, type) > () = $2 (yy0.as< b4_symbol($3, type) >(), yy1.as< b4_symbol($3, type) >());],
+                                          [yy0.b4_symbol($3, slot) = $2 (yy0, yy1);])],
+                           [yy0 = $2 (yy0, yy1);])])])
+
+# b4_yylex
+# --------
+# Call yylex.
+m4_define([b4_yylex],
+[b4_token_ctor_if(
+[b4_function_call([yylex],
+                  [symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))],
+[b4_function_call([yylex], [int],
+                  [[value_type *], [&this->yyla.value]][]dnl
+b4_locations_if([, [[location_type *], [&this->yyla.location]]])dnl
+m4_ifdef([b4_lex_param], [, ]b4_lex_param))])])
+
+
+# b4_shared_declarations(hh|cc)
+# -----------------------------
+# Declaration that might either go into the header (if --header, $1 = hh)
+# or in the implementation file.
+m4_define([b4_shared_declarations],
+[b4_percent_code_get([[requires]])[
+#include <algorithm>
+#include <cstddef> // ptrdiff_t
+#include <cstring> // memcpy
+#include <iostream>
+#include <iomanip>
+#include <limits>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+]b4_cxx_portability[
+]m4_ifdef([b4_location_include],
+          [[# include ]b4_location_include])[
+]b4_variant_if([b4_variant_includes])[
+
+]b4_YYDEBUG_define[
+
+]b4_namespace_open[
+
+]b4_bison_locations_if([m4_ifndef([b4_location_file],
+                                  [b4_location_define])])[
+
+  /// A Bison parser.
+  class ]b4_parser_class[
+  {
+  public:
+]b4_public_types_declare[
+]b4_symbol_type_define[
+
+    // FIXME: should be private eventually.
+    class glr_stack;
+    class glr_state;
+
+    /// Build a parser object.
+    ]b4_parser_class[ (]b4_parse_param_decl[);
+    ~]b4_parser_class[ ();
+
+    /// Parse.  An alias for parse ().
+    /// \returns  0 iff parsing succeeded.
+    int operator() ();
+
+    /// Parse.
+    /// \returns  0 iff parsing succeeded.
+    int parse ();
+
+#if ]b4_api_PREFIX[DEBUG
+    /// The current debugging stream.
+    std::ostream& debug_stream () const;
+    /// Set the current debugging stream.
+    void set_debug_stream (std::ostream &);
+
+    /// Type for debugging levels.
+    using debug_level_type = int;
+    /// The current debugging level.
+    debug_level_type debug_level () const;
+    /// Set the current debugging level.
+    void set_debug_level (debug_level_type l);
+#endif
+
+    /// Report a syntax error.]b4_locations_if([[
+    /// \param loc    where the syntax error is found.]])[
+    /// \param msg    a description of the syntax error.
+    void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
+
+]b4_parse_error_bmatch(
+[custom\|detailed],
+[[    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static const char *symbol_name (symbol_kind_type yysymbol);]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static const char *symbol_name (symbol_kind_type yysymbol);
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static std::string symbol_name (symbol_kind_type yysymbol);]])[
+
+]b4_token_constructor_define[
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+    class context
+    {
+    public:
+      context (glr_stack& yystack, const symbol_type& yyla);
+      const symbol_type& lookahead () const YY_NOEXCEPT { return yyla_; }
+      symbol_kind_type token () const YY_NOEXCEPT { return yyla_.kind (); }]b4_locations_if([[
+      const location_type& location () const YY_NOEXCEPT { return yyla_.location; }
+]])[
+      /// Put in YYARG at most YYARGN of the expected tokens, and return the
+      /// number of tokens stored in YYARG.  If YYARG is null, return the
+      /// number of expected tokens (guaranteed to be less than YYNTOKENS).
+      int expected_tokens (symbol_kind_type yyarg[], int yyargn) const;
+
+    private:
+      glr_stack& yystack_;
+      const symbol_type& yyla_;
+    };
+]])[
+# if ]b4_api_PREFIX[DEBUG
+  public:
+    /// \brief Report a symbol value on the debug stream.
+    /// \param yykind   The symbol kind.
+    /// \param yyval    Its semantic value.]b4_locations_if([[
+    /// \param yyloc    Its location.]])[
+    void yy_symbol_value_print_ (symbol_kind_type yykind,
+                                 const value_type& yyval]b4_locations_if([[,
+                                 const location_type& yyloc]])[) const;
+    /// \brief Report a symbol on the debug stream.
+    /// \param yykind   The symbol kind.
+    /// \param yyval    Its semantic value.]b4_locations_if([[
+    /// \param yyloc    Its location.]])[
+    void yy_symbol_print_ (symbol_kind_type yykind,
+                           const value_type& yyval]b4_locations_if([[,
+                           const location_type& yyloc]])[) const;
+  private:
+    /// Debug stream.
+    std::ostream* yycdebug_;
+#endif
+
+]b4_parse_error_bmatch(
+[custom], [[
+  private:
+    /// Report a syntax error
+    /// \param yyctx     the context in which the error occurred.
+    void report_syntax_error (const context& yyctx) const;]],
+[detailed\|verbose], [[
+  private:
+    /// The arguments of the error message.
+    int yy_syntax_error_arguments_ (const context& yyctx,
+                                    symbol_kind_type yyarg[], int yyargn) const;
+
+    /// Generate an error message.
+    /// \param yyctx     the context in which the error occurred.
+    virtual std::string yysyntax_error_ (const context& yyctx) const;]])[
+
+    /// Convert a scanner token kind \a t to a symbol kind.
+    /// In theory \a t should be a token_kind_type, but character literals
+    /// are valid, yet not members of the token_kind_type enum.
+    static symbol_kind_type yytranslate_ (int t) YY_NOEXCEPT;
+
+]b4_parse_error_bmatch(
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *yystr);
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+]])[
+
+    /// \brief Reclaim the memory associated to a symbol.
+    /// \param yymsg     Why this token is reclaimed.
+    ///                  If null, print nothing.
+    /// \param yykind    The symbol kind.
+    void yy_destroy_ (const char* yymsg, symbol_kind_type yykind,
+                      value_type& yyval]b4_locations_if([[,
+                      location_type& yyloc]])[);
+
+]b4_parse_param_vars[
+    // Needs access to yy_destroy_, report_syntax_error, etc.
+    friend glr_stack;
+  };
+
+]b4_token_ctor_if([b4_yytranslate_define([$1])[
+]b4_public_types_define([$1])])[
+]b4_namespace_close[
+
+]b4_percent_code_get([[provides]])[
+]])[
+
+
+## -------------- ##
+## Output files.  ##
+## -------------- ##
+
+
+# ------------- #
+# Header file.  #
+# ------------- #
+
+]b4_header_if([[
+]b4_output_begin([b4_spec_header_file])[
+]b4_copyright([Skeleton interface for Bison GLR parsers in C++],
+             [2002-2015, 2018-2021])[
+// C++ GLR parser skeleton written by Valentin Tolmer.
+
+]b4_disclaimer[
+]b4_cpp_guard_open([b4_spec_mapped_header_file])[
+]b4_shared_declarations([hh])[
+]b4_cpp_guard_close([b4_spec_mapped_header_file])[
+]b4_output_end])[
+
+
+# --------------------- #
+# Implementation file.  #
+# --------------------- #
+
+]b4_output_begin([b4_parser_file_name])[
+]b4_copyright([Skeleton implementation for Bison GLR parsers in C],
+              [2002-2015, 2018-2021])[
+// C++ GLR parser skeleton written by Valentin Tolmer.
+
+]b4_disclaimer[
+]b4_identification[
+
+]b4_percent_code_get([[top]])[
+]m4_if(b4_prefix, [yy], [],
+[[/* Substitute the variable and function names.  */
+#define yyparse ]b4_prefix[parse
+#define yylex   ]b4_prefix[lex
+#define yyerror ]b4_prefix[error
+#define yydebug ]b4_prefix[debug]])[
+
+]b4_user_pre_prologue[
+
+]b4_null_define[
+
+]b4_header_if([[#include "@basename(]b4_spec_header_file[@)"]],
+              [b4_shared_declarations([cc])])[
+
+namespace
+{
+  /* Default (constant) value used for initialization for null
+     right-hand sides.  Unlike the standard yacc.c template, here we set
+     the default value of $$ to a zeroed-out value.  Since the default
+     value is undefined, this behavior is technically correct.  */
+  ]b4_namespace_ref[::]b4_parser_class[::value_type yyval_default;
+}
+
+]b4_user_post_prologue[
+]b4_percent_code_get[
+
+#include <cstdio>
+#include <cstdlib>
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+// Whether we are compiled with exception support.
+#ifndef YY_EXCEPTIONS
+# if defined __GNUC__ && !defined __EXCEPTIONS
+#  define YY_EXCEPTIONS 0
+# else
+#  define YY_EXCEPTIONS 1
+# endif
+#endif
+
+#ifndef YYFREE
+# define YYFREE free
+#endif
+#ifndef YYMALLOC
+# define YYMALLOC malloc
+#endif
+
+#ifndef YYSETJMP
+# include <setjmp.h>
+# define YYJMP_BUF jmp_buf
+# define YYSETJMP(Env) setjmp (Env)
+/* Pacify Clang and ICC.  */
+# define YYLONGJMP(Env, Val)                    \
+ do {                                           \
+   longjmp (Env, Val);                          \
+   YYASSERT (0);                                \
+ } while (false)
+#endif
+
+]b4_attribute_define([noreturn])[
+
+#if defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_NULL_DEREFERENCE_BEGIN                               \
+  _Pragma ("GCC diagnostic push")                                       \
+  _Pragma ("GCC diagnostic ignored \"-Wnull-dereference\"")
+# define YY_IGNORE_NULL_DEREFERENCE_END         \
+  _Pragma ("GCC diagnostic pop")
+#else
+# define YY_IGNORE_NULL_DEREFERENCE_BEGIN
+# define YY_IGNORE_NULL_DEREFERENCE_END
+#endif
+
+]b4_null_define[
+]b4_cast_define[
+
+// FIXME: Use the same conventions as lalr1.cc.
+]b4_parse_assert_if[
+#ifndef YYASSERT
+# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
+#endif
+
+#ifdef YYDEBUG
+# define YYDASSERT(Condition) YYASSERT(Condition)
+#else
+# define YYDASSERT(Condition)
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  ]b4_final_state_number[
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   ]b4_last[
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  ]b4_tokens_number[
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  ]b4_nterms_number[
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  ]b4_rules_number[
+/* YYNSTATES -- Number of states.  */
+#define YYNSTATES  ]b4_states_number[
+/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule.  */
+#define YYMAXRHS ]b4_r2_max[
+/* YYMAXLEFT -- Maximum number of symbols to the left of a handle
+   accessed by $0, $-1, etc., in any rule.  */
+#define YYMAXLEFT ]b4_max_left_semantic_context[
+
+namespace
+{
+#if ]b4_api_PREFIX[DEBUG
+  /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+  const ]b4_int_type_for([b4_rline])[ yyrline[] =
+  {
+  ]b4_rline[
+  };
+#endif
+
+#define YYPACT_NINF ]b4_pact_ninf[
+#define YYTABLE_NINF ]b4_table_ninf[
+
+]b4_parser_tables_define[
+
+  /* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none).  */
+  const ]b4_int_type_for([b4_dprec])[ yydprec[] =
+  {
+  ]b4_dprec[
+  };
+
+  /* YYMERGER[RULE-NUM] -- Index of merging function for rule #RULE-NUM.  */
+  const ]b4_int_type_for([b4_merger])[ yymerger[] =
+  {
+  ]b4_merger[
+  };
+
+  /* YYIMMEDIATE[RULE-NUM] -- True iff rule #RULE-NUM is not to be deferred, as
+     in the case of predicates.  */
+  const bool yyimmediate[] =
+  {
+  ]b4_immediate[
+  };
+
+  /* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
+     list of conflicting reductions corresponding to action entry for
+     state STATE-NUM in yytable.  0 means no conflicts.  The list in
+     yyconfl is terminated by a rule number of 0.  */
+  const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] =
+  {
+  ]b4_conflict_list_heads[
+  };
+
+  /* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
+     0, pointed into by YYCONFLP.  */
+  ]dnl Do not use b4_int_type_for here, since there are places where
+  dnl pointers onto yyconfl are taken, whose type is "short*".
+  dnl We probably ought to introduce a type for confl.
+  [const short yyconfl[] =
+  {
+  ]b4_conflicting_rules[
+  };
+} // namespace
+
+
+/* Error token number */
+#define YYTERROR 1
+
+]b4_locations_if([[
+]b4_yylloc_default_define[
+# define YYRHSLOC(Rhs, K) ((Rhs)[K].getState().yyloc)
+]])[
+
+enum YYRESULTTAG { yyok, yyaccept, yyabort, yyerr };
+
+#define YYCHK(YYE)                              \
+  do {                                          \
+    YYRESULTTAG yychk_flag = YYE;               \
+    if (yychk_flag != yyok)                     \
+      return yychk_flag;                        \
+  } while (false)
+
+#if ]b4_api_PREFIX[DEBUG
+
+#define YYCDEBUG if (!yydebug) {} else std::cerr
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                  \
+  do {                                                                  \
+    if (yydebug)                                                        \
+      {                                                                 \
+        std::cerr << Title << ' ';                                      \
+        yyparser.yy_symbol_print_ (Kind, Value]b4_locations_if([, Location])[); \
+        std::cerr << '\n';                                              \
+      }                                                                 \
+  } while (false)
+
+# define YY_REDUCE_PRINT(Args)                  \
+  do {                                          \
+    if (yydebug)                                \
+      yystateStack.yy_reduce_print Args;        \
+  } while (false)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+
+namespace
+{
+  using glr_stack = ]b4_namespace_ref[::]b4_parser_class[::glr_stack;
+  using glr_state = ]b4_namespace_ref[::]b4_parser_class[::glr_state;
+
+  void yypstack (const glr_stack& yystack, size_t yyk)
+    YY_ATTRIBUTE_UNUSED;
+  void yypdumpstack (const glr_stack& yystack)
+    YY_ATTRIBUTE_UNUSED;
+}
+
+#else /* !]b4_api_PREFIX[DEBUG */
+
+# define YYCDEBUG if (true) {} else std::cerr
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) {}
+# define YY_REDUCE_PRINT(Args) {}
+
+#endif /* !]b4_api_PREFIX[DEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH ]b4_stack_depth_init[
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYMAXDEPTH * sizeof (GLRStackItem)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH ]b4_stack_depth_max[
+#endif
+
+/* Minimum number of free items on the stack allowed after an
+   allocation.  This is to allow allocation and initialization
+   to be completed by functions that call yyexpandGLRStack before the
+   stack is expanded, thus insuring that all necessary pointers get
+   properly redirected to new data.  */
+#define YYHEADROOM 2
+
+#ifndef YYSTACKEXPANDABLE
+# define YYSTACKEXPANDABLE 1
+#endif
+
+namespace
+{
+  template <typename Parameter>
+  class strong_index_alias
+  {
+  public:
+    static strong_index_alias create (std::ptrdiff_t value)
+    {
+      strong_index_alias result;
+      result.value_ = value;
+      return result;
+    }
+
+    std::ptrdiff_t const& get () const { return value_; }
+
+    size_t uget () const { return static_cast<size_t> (value_); }
+
+    strong_index_alias operator+ (std::ptrdiff_t other) const
+    {
+      return strong_index_alias (get () + other);
+    }
+
+    void operator+= (std::ptrdiff_t other)
+    {
+      value_ += other;
+    }
+
+    strong_index_alias operator- (std::ptrdiff_t other)
+    {
+      return strong_index_alias (get () - other);
+    }
+
+    void operator-= (std::ptrdiff_t other)
+    {
+      value_ -= other;
+    }
+
+    size_t operator- (strong_index_alias other)
+    {
+      return strong_index_alias (get () - other.get ());
+    }
+
+    strong_index_alias& operator++ ()
+    {
+      ++value_;
+      return *this;
+    }
+
+    bool isValid () const
+    {
+      return value_ != INVALID_INDEX;
+    }
+
+    void setInvalid()
+    {
+      value_ = INVALID_INDEX;
+    }
+
+    bool operator== (strong_index_alias other)
+    {
+      return get () == other.get ();
+    }
+
+    bool operator!= (strong_index_alias other)
+    {
+      return get () != other.get ();
+    }
+
+    bool operator< (strong_index_alias other)
+    {
+      return get () < other.get ();
+    }
+
+  private:
+    static const std::ptrdiff_t INVALID_INDEX;
+
+    // WARNING: 0-initialized.
+    std::ptrdiff_t value_;
+  }; // class strong_index_alias
+
+  template<typename T>
+  const std::ptrdiff_t strong_index_alias<T>::INVALID_INDEX =
+    std::numeric_limits<std::ptrdiff_t>::max ();
+
+  using state_set_index = strong_index_alias<struct glr_state_set_tag>;
+
+  state_set_index create_state_set_index (std::ptrdiff_t value)
+  {
+    return state_set_index::create (value);
+  }
+
+  /** State numbers, as in LALR(1) machine */
+  using state_num = int;
+
+  /** Rule numbers, as in LALR(1) machine */
+  using rule_num = int;
+
+  using parser_type = ]b4_namespace_ref[::]b4_parser_class[;
+  using glr_state = parser_type::glr_state;
+  using symbol_kind = parser_type::symbol_kind;
+  using symbol_kind_type = parser_type::symbol_kind_type;
+  using symbol_type = parser_type::symbol_type;
+  using value_type = parser_type::value_type;]b4_locations_if([[
+  using location_type = parser_type::location_type;]])[
+
+  // Forward declarations.
+  class glr_stack_item;
+  class semantic_option;
+} // namespace
+
+namespace
+{
+  /** Accessing symbol of state YYSTATE.  */
+  inline symbol_kind_type
+  yy_accessing_symbol (state_num yystate)
+  {
+    return YY_CAST (symbol_kind_type, yystos[yystate]);
+  }
+
+  /** Left-hand-side symbol for rule #YYRULE.  */
+  inline symbol_kind_type
+  yylhsNonterm (rule_num yyrule)
+  {
+    return static_cast<symbol_kind_type>(yyr1[yyrule]);
+  }
+
+  /** Number of symbols composing the right hand side of rule #RULE.  */
+  inline int
+  yyrhsLength (rule_num yyrule)
+  {
+    return yyr2[yyrule];
+  }
+}
+
+namespace ]b4_namespace_ref[
+{
+  class ]b4_parser_class[::glr_state
+  {
+  public:
+    glr_state ()
+      : yyresolved (false)
+      , yylrState (0)
+      , yyposn (0)
+      , yypred (0)
+      , yyfirstVal (0)]b4_locations_if([[
+      , yyloc ()]])[]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {}
+
+    /// Build with a semantic value.
+    glr_state (state_num lrState, size_t posn, const value_type& val]b4_locations_if([[, const location_type& loc]])[)
+      : yyresolved (true)
+      , yylrState (lrState)
+      , yyposn (posn)
+      , yypred (0)
+      , yyval (]b4_variant_if([], [[val]])[)]b4_locations_if([[
+      , yyloc (loc)]])[]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {]b4_variant_if([[
+      ]b4_symbol_variant([yy_accessing_symbol (lrState)],
+                         [yyval], [copy], [val])])[}
+
+    /// Build with a semantic option.
+    glr_state (state_num lrState, size_t posn)
+      : yyresolved (false)
+      , yylrState (lrState)
+      , yyposn (posn)
+      , yypred (0)
+      , yyfirstVal (0)]b4_locations_if([[
+      , yyloc ()]])[]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {}
+
+    glr_state (const glr_state& other)
+      : yyresolved (other.yyresolved)
+      , yylrState (other.yylrState)
+      , yyposn (other.yyposn)
+      , yypred (0)]b4_locations_if([[
+      , yyloc (other.yyloc)]])[]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {
+      setPred (other.pred ());
+      if (other.yyresolved)]b4_variant_if([[
+        {
+          new (&yyval) value_type ();
+          ]b4_symbol_variant([yy_accessing_symbol (other.yylrState)],
+                             [yyval], [copy], [other.value ()])[
+        }]], [[
+        new (&yyval) value_type (other.value ());]])[
+      else
+        {
+          yyfirstVal = 0;
+          setFirstVal (other.firstVal ());
+        }]b4_parse_assert_if([[
+      check_();]])[
+    }
+
+    ~glr_state ()
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      if (yyresolved)
+        {]b4_variant_if([[
+          symbol_kind_type yykind = yy_accessing_symbol (yylrState);
+          // FIXME: User destructors.
+          // Value type destructor.
+          ]b4_symbol_variant([[yykind]], [[yyval]], [[template destroy]])])[
+          yyval.~value_type ();
+        }]b4_parse_assert_if([[
+      magic_ = 0;]])[
+    }
+
+    glr_state& operator= (const glr_state& other)
+    {]b4_parse_assert_if([[
+      check_ ();
+      other.check_ ();]])[
+      if (!yyresolved && other.yyresolved)
+        new (&yyval) value_type;
+      yyresolved = other.yyresolved;
+      yylrState = other.yylrState;
+      yyposn = other.yyposn;
+      setPred (other.pred ());
+      if (other.yyresolved)]b4_variant_if([[
+        ]b4_symbol_variant([yy_accessing_symbol (other.yylrState)],
+                           [yyval], [copy], [other.value ()])], [[
+        value () = other.value ();]])[
+      else
+        setFirstVal (other.firstVal ());]b4_locations_if([[
+      yyloc = other.yyloc;]])[
+      return *this;
+    }
+
+    /** Type tag for the semantic value.  If true, yyval applies, otherwise
+     *  yyfirstVal applies.  */
+    bool yyresolved;
+    /** Number of corresponding LALR(1) machine state.  */
+    state_num yylrState;
+    /** Source position of the last token produced by my symbol */
+    size_t yyposn;
+
+    /// Only call pred() and setPred() on objects in yyitems, not temporaries.
+    glr_state* pred ();
+    const glr_state* pred () const;
+    void setPred (const glr_state* state);
+
+    /// Only call firstVal() and setFirstVal() on objects in yyitems, not
+    /// temporaries.
+    semantic_option* firstVal ();
+    const semantic_option* firstVal () const;
+    void setFirstVal (const semantic_option* option);
+
+    value_type& value ()
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      return yyval;
+    }
+
+    const value_type& value () const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      return yyval;
+    }
+
+    void
+    destroy (char const *yymsg, ]b4_namespace_ref[::]b4_parser_class[& yyparser);
+
+    /* DEBUGGING ONLY */
+  #if ]b4_api_PREFIX[DEBUG
+    void yy_yypstack () const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      if (pred () != YY_NULLPTR)
+        {
+          pred ()->yy_yypstack ();
+          std::cerr << " -> ";
+        }
+      std::cerr << yylrState << "@@" << yyposn;
+    }
+  #endif
+
+    std::ptrdiff_t indexIn (const glr_stack_item* array) const YY_ATTRIBUTE_UNUSED;
+
+    glr_stack_item* asItem ()
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      return asItem(this);
+    }
+
+    const glr_stack_item* asItem () const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      return asItem (this);
+    }
+
+  private:
+    template <typename T>
+    static const glr_stack_item* asItem (const T* state)
+    {
+      return reinterpret_cast<const glr_stack_item*>(state);
+    }
+    template <typename T>
+    static glr_stack_item* asItem (T* state)
+    {
+      return reinterpret_cast<glr_stack_item*> (state);
+    }
+    static const char *as_pointer_ (const glr_state *state)
+    {
+      return reinterpret_cast<const char *> (state);
+    }
+    static char *as_pointer_ (glr_state *state)
+    {
+      return reinterpret_cast<char *> (state);
+    }
+    /** Preceding state in this stack */
+    std::ptrdiff_t yypred;
+    union {
+      /** First in a chain of alternative reductions producing the
+       *  nonterminal corresponding to this state, threaded through
+       *  yyfirstVal.  Value "0" means empty.  */
+      std::ptrdiff_t yyfirstVal;
+      /** Semantic value for this state.  */
+      value_type yyval;
+    };]b4_locations_if([[
+   // FIXME: Why public?
+   public:
+    /** Source location for this state.  */
+    location_type yyloc;]])[
+
+]b4_parse_assert_if([[
+  public:
+    // Check invariants.
+    void check_ () const
+    {
+      YY_IGNORE_NULL_DEREFERENCE_BEGIN
+      YYASSERT (this->magic_ == MAGIC);
+      YY_IGNORE_NULL_DEREFERENCE_END
+    }
+
+    // A magic number to check our pointer arithmetic is sane.
+    enum { MAGIC = 713705 };
+    unsigned int magic_;]])[
+  }; // class ]b4_parser_class[::glr_state
+} // namespace ]b4_namespace_ref[
+
+
+namespace
+{
+  /** A stack of GLRState representing the different heads during
+    * nondeterministic evaluation. */
+  class glr_state_set
+  {
+  public:
+    /** Initialize YYSET to a singleton set containing an empty stack.  */
+    glr_state_set ()
+      : yylastDeleted (YY_NULLPTR)
+    {
+      yystates.push_back (YY_NULLPTR);
+      yylookaheadNeeds.push_back (false);
+    }
+
+    // Behave like a vector of states.
+    glr_state*& operator[] (state_set_index index)
+    {
+      return yystates[index.uget()];
+    }
+
+    glr_state* operator[] (state_set_index index) const
+    {
+      return yystates[index.uget()];
+    }
+
+    size_t size () const
+    {
+      return yystates.size ();
+    }
+
+    std::vector<glr_state*>::iterator begin ()
+    {
+      return yystates.begin ();
+    }
+
+    std::vector<glr_state*>::iterator end ()
+    {
+      return yystates.end ();
+    }
+
+    bool lookaheadNeeds (state_set_index index) const
+    {
+      return yylookaheadNeeds[index.uget ()];
+    }
+
+    bool setLookaheadNeeds (state_set_index index, bool value)
+    {
+      return yylookaheadNeeds[index.uget ()] = value;
+    }
+
+    /** Invalidate stack #YYK.  */
+    void
+    yymarkStackDeleted (state_set_index yyk)
+    {
+      size_t k = yyk.uget ();
+      if (yystates[k] != YY_NULLPTR)
+        yylastDeleted = yystates[k];
+      yystates[k] = YY_NULLPTR;
+    }
+
+    /** Undelete the last stack in *this that was marked as deleted.  Can
+        only be done once after a deletion, and only when all other stacks have
+        been deleted.  */
+    void
+    yyundeleteLastStack ()
+    {
+      if (yylastDeleted == YY_NULLPTR || !yystates.empty ())
+        return;
+      yystates.push_back (yylastDeleted);
+      YYCDEBUG << "Restoring last deleted stack as stack #0.\n";
+      clearLastDeleted ();
+    }
+
+    /** Remove the dead stacks (yystates[i] == YY_NULLPTR) and shift the later
+     * ones.  */
+    void
+    yyremoveDeletes ()
+    {
+      size_t newsize = yystates.size ();
+      /* j is the number of live stacks we have seen.  */
+      for (size_t i = 0, j = 0; j < newsize; ++i)
+        {
+          if (yystates[i] == YY_NULLPTR)
+            {
+              if (i == j)
+                {
+                  YYCDEBUG << "Removing dead stacks.\n";
+                }
+              newsize -= 1;
+            }
+          else
+            {
+              yystates[j] = yystates[i];
+              /* In the current implementation, it's unnecessary to copy
+                 yylookaheadNeeds[i] since, after
+                 yyremoveDeletes returns, the parser immediately either enters
+                 deterministic operation or shifts a token.  However, it doesn't
+                 hurt, and the code might evolve to need it.  */
+              yylookaheadNeeds[j] = yylookaheadNeeds[i];
+              if (j != i)
+                {
+                  YYCDEBUG << "Rename stack " << i << " -> " << j << ".\n";
+                }
+              j += 1;
+            }
+        }
+      yystates.resize (newsize);
+      yylookaheadNeeds.resize (newsize);
+    }
+
+
+    state_set_index
+    yysplitStack (state_set_index yyk)
+    {
+      const size_t k = yyk.uget ();
+      yystates.push_back (yystates[k]);
+      yylookaheadNeeds.push_back (yylookaheadNeeds[k]);
+      return create_state_set_index (static_cast<std::ptrdiff_t> (yystates.size () - 1));
+    }
+
+    void clearLastDeleted ()
+    {
+      yylastDeleted = YY_NULLPTR;
+    }
+
+  private:
+
+    std::vector<glr_state*> yystates;
+    /** During nondeterministic operation, yylookaheadNeeds tracks which
+     *  stacks have actually needed the current lookahead.  During deterministic
+     *  operation, yylookaheadNeeds[0] is not maintained since it would merely
+     *  duplicate !yyla.empty ().  */
+    std::vector<bool> yylookaheadNeeds;
+
+    /** The last stack we invalidated.  */
+    glr_state* yylastDeleted;
+  }; // class glr_state_set
+} // namespace
+
+namespace
+{
+  class semantic_option
+  {
+  public:
+    semantic_option ()
+      : yyrule (0)
+      , yystate (0)
+      , yynext (0)
+      , yyla ()]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {}
+
+    semantic_option (rule_num rule)
+      : yyrule (rule)
+      , yystate (0)
+      , yynext (0)
+      , yyla ()]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {}
+
+    semantic_option (const semantic_option& that)
+      : yyrule (that.yyrule)
+      , yystate (that.yystate)
+      , yynext (that.yynext)
+      , yyla (that.yyla)]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {]b4_parse_assert_if([[
+      that.check_ ();]])[
+    }
+
+    // Needed for the assignment in yynewSemanticOption.
+    semantic_option& operator= (const semantic_option& that)
+    {]b4_parse_assert_if([[
+      check_ ();
+      that.check_ ();]])[
+      yyrule = that.yyrule;
+      yystate = that.yystate;
+      yynext = that.yynext;
+      yyla = that.yyla;
+      return *this;
+    }
+
+    /// Only call state() and setState() on objects in yyitems, not temporaries.
+    glr_state* state();
+    const glr_state* state() const;
+    void setState(const glr_state* s);
+
+    const semantic_option* next () const YY_ATTRIBUTE_UNUSED;
+    semantic_option* next ();
+    void setNext (const semantic_option* s);
+
+    std::ptrdiff_t indexIn (const glr_stack_item* array) const YY_ATTRIBUTE_UNUSED;
+
+    /** True iff YYY0 and YYY1 represent identical options at the top level.
+     *  That is, they represent the same rule applied to RHS symbols
+     *  that produce the same terminal symbols.  */
+    bool
+    isIdenticalTo (const semantic_option& yyy1) const
+    {]b4_parse_assert_if([[
+      check_ ();
+      yyy1.check_ ();]])[
+      if (this->yyrule == yyy1.yyrule)
+        {
+          const glr_state *yys0, *yys1;
+          int yyn;
+          for (yys0 = this->state(),
+               yys1 = yyy1.state(),
+               yyn = yyrhsLength (this->yyrule);
+               yyn > 0;
+               yys0 = yys0->pred(),
+               yys1 = yys1->pred(), yyn -= 1)
+            if (yys0->yyposn != yys1->yyposn)
+              return false;
+          return true;
+        }
+      else
+        return false;
+    }
+
+    /** Assuming identicalOptions (YYY0,YYY1), destructively merge the
+     *  alternative semantic values for the RHS-symbols of YYY1 and YYY0.  */
+    void
+    mergeWith (semantic_option& yyy1)
+    {]b4_parse_assert_if([[
+      check_ ();
+      yyy1.check_ ();]])[
+      glr_state *yys0 = this->state ();
+      glr_state *yys1 = yyy1.state ();
+      for (int yyn = yyrhsLength (this->yyrule);
+           yyn > 0;
+           yyn -= 1, yys0 = yys0->pred (), yys1 = yys1->pred ())
+        {
+          if (yys0 == yys1)
+            break;
+          else if (yys0->yyresolved)
+            {
+              yys1->yyresolved = true;]b4_variant_if([[
+              YYASSERT (yys1->yylrState == yys0->yylrState);
+              ]b4_symbol_variant([yy_accessing_symbol (yys0->yylrState)],
+                                 [yys1->value ()], [copy], [yys0->value ()])], [[
+              yys1->value () = yys0->value ();]])[
+            }
+          else if (yys1->yyresolved)
+            {
+              yys0->yyresolved = true;]b4_variant_if([[
+              YYASSERT (yys0->yylrState == yys1->yylrState);
+              ]b4_symbol_variant([yy_accessing_symbol (yys1->yylrState)],
+                                 [yys0->value ()], [copy], [yys1->value ()])], [[
+              yys0->value () = yys1->value ();]])[
+            }
+          else
+            {
+              semantic_option* yyz0prev = YY_NULLPTR;
+              semantic_option* yyz0 = yys0->firstVal();
+              semantic_option* yyz1 = yys1->firstVal();
+              while (true)
+                {
+                  if (yyz1 == yyz0 || yyz1 == YY_NULLPTR)
+                    break;
+                  else if (yyz0 == YY_NULLPTR)
+                    {
+                      if (yyz0prev != YY_NULLPTR)
+                        yyz0prev->setNext (yyz1);
+                      else
+                        yys0->setFirstVal (yyz1);
+                      break;
+                    }
+                  else if (yyz0 < yyz1)
+                    {
+                      semantic_option* yyz = yyz0;
+                      if (yyz0prev != YY_NULLPTR)
+                        yyz0prev->setNext(yyz1);
+                      else
+                        yys0->setFirstVal(yyz1);
+                      yyz1 = yyz1->next();
+                      yyz0->setNext(yyz);
+                    }
+                  yyz0prev = yyz0;
+                  yyz0 = yyz0->next();
+                }
+              yys1->setFirstVal(yys0->firstVal());
+            }
+        }
+    }
+
+#if ]b4_api_PREFIX[DEBUG
+    void yyreportTree (size_t yyindent = 2) const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      int yynrhs = yyrhsLength (this->yyrule);
+      const glr_state* yystates[1 + YYMAXRHS];
+      glr_state yyleftmost_state;
+
+      {
+        const glr_state* yys = this->state();
+        for (int yyi = yynrhs; 0 < yyi; yyi -= 1)
+          {
+            yystates[yyi] = yys;
+            yys = yys->pred();
+          }
+        if (yys == YY_NULLPTR)
+          {
+            yyleftmost_state.yyposn = 0;
+            yystates[0] = &yyleftmost_state;
+          }
+        else
+          yystates[0] = yys;
+      }
+
+      std::string yylhs = ]b4_namespace_ref[::]b4_parser_class[::symbol_name (yylhsNonterm (this->yyrule));
+      YYASSERT(this->state());
+      if (this->state()->yyposn < yystates[0]->yyposn + 1)
+        std::cerr << std::string(yyindent, ' ') << yylhs << " -> <Rule "
+                  << this->yyrule - 1 << ", empty>\n";
+      else
+        std::cerr << std::string(yyindent, ' ') << yylhs << " -> <Rule "
+                  << this->yyrule - 1 << ", tokens "
+                  << yystates[0]->yyposn + 1 << " .. "
+                  << this->state()->yyposn << ">\n";
+      for (int yyi = 1; yyi <= yynrhs; yyi += 1)
+        {
+          if (yystates[yyi]->yyresolved)
+            {
+              std::string yysym = ]b4_namespace_ref[::]b4_parser_class[::symbol_name (yy_accessing_symbol (yystates[yyi]->yylrState));
+              if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
+                std::cerr << std::string(yyindent + 2, ' ') << yysym
+                          << " <empty>\n";
+              else
+                std::cerr << std::string(yyindent + 2, ' ') << yysym
+                          << " <tokens " << yystates[yyi-1]->yyposn + 1
+                          << " .. " << yystates[yyi]->yyposn << ">\n";
+            }
+          else
+            yystates[yyi]->firstVal ()->yyreportTree (yyindent+2);
+        }
+    }
+#endif
+
+    /** Rule number for this reduction */
+    rule_num yyrule;
+
+  private:
+    template <typename T>
+    static const glr_stack_item* asItem(const T* state)
+    {
+      return reinterpret_cast<const glr_stack_item*>(state);
+    }
+    template <typename T>
+    static glr_stack_item* asItem(T* state)
+    {
+      return reinterpret_cast<glr_stack_item*>(state);
+    }
+    /** The last RHS state in the list of states to be reduced.  */
+    std::ptrdiff_t yystate;
+    /** Next sibling in chain of options.  To facilitate merging,
+     *  options are chained in decreasing order by address.  */
+    std::ptrdiff_t yynext;
+
+  public:
+    /** The lookahead for this reduction.  */
+    symbol_type yyla;
+
+]b4_parse_assert_if([[
+  public:
+    // Check invariants.
+    void check_ () const
+    {
+      YY_IGNORE_NULL_DEREFERENCE_BEGIN
+      YYASSERT (this->magic_ == MAGIC);
+      YY_IGNORE_NULL_DEREFERENCE_END
+    }
+
+    // A magic number to check our pointer arithmetic is sane.
+    enum { MAGIC = 0xeff1cace };
+    unsigned int magic_;]])[
+  }; // class semantic_option
+} // namespace
+
+namespace
+{
+  /** Type of the items in the GLR stack.
+   *  It can be either a glr_state or a semantic_option. The is_state_ field
+   *  indicates which item of the union is valid.  */
+  class glr_stack_item
+  {
+  public:
+    glr_stack_item (bool state = true)
+      : is_state_ (state)]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {
+      if (is_state_)
+        new (&raw_) glr_state;
+      else
+        new (&raw_) semantic_option;
+    }
+
+    glr_stack_item (const glr_stack_item& other) YY_NOEXCEPT YY_NOTHROW
+      : is_state_ (other.is_state_)]b4_parse_assert_if([[
+      , magic_ (MAGIC)]])[
+    {]b4_parse_assert_if([[
+      other.check_ ();]])[
+      std::memcpy (raw_, other.raw_, union_size);
+    }
+
+    glr_stack_item& operator= (glr_stack_item other)
+    {]b4_parse_assert_if([[
+      check_ ();
+      other.check_ ();]])[
+      std::swap (is_state_, other.is_state_);
+      std::swap (raw_, other.raw_);
+      return *this;
+    }
+
+    ~glr_stack_item ()
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      if (is_state ())
+        getState ().~glr_state ();
+      else
+        getOption ().~semantic_option ();
+    }
+
+    void setState (const glr_state &state)
+    {]b4_parse_assert_if([[
+      check_ ();
+      state.check_ ();]])[
+      if (this != state.asItem ())
+        {
+          if (is_state_)
+            getState ().~glr_state ();
+          else
+            getOption ().~semantic_option ();
+          new (&raw_) glr_state (state);
+          is_state_ = true;
+        }
+    }
+
+    glr_state& getState ()
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      YYDASSERT (is_state ());
+      void *yyp = raw_;
+      glr_state& res = *static_cast<glr_state*> (yyp);]b4_parse_assert_if([[
+      res.check_ ();]])[
+      return res;
+    }
+
+    const glr_state& getState () const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      YYDASSERT (is_state ());
+      const void *yyp = raw_;
+      const glr_state& res = *static_cast<const glr_state*> (yyp);]b4_parse_assert_if([[
+      res.check_ ();]])[
+      return res;
+    }
+
+    semantic_option& getOption ()
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      YYDASSERT (!is_state ());
+      void *yyp = raw_;
+      return *static_cast<semantic_option*> (yyp);
+    }
+    const semantic_option& getOption () const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      YYDASSERT (!is_state ());
+      const void *yyp = raw_;
+      return *static_cast<const semantic_option*> (yyp);
+    }
+    bool is_state () const
+    {]b4_parse_assert_if([[
+      check_ ();]])[
+      return is_state_;
+    }
+
+  private:
+    /// The possible contents of raw_. Since they have constructors, they cannot
+    /// be directly included in the union.
+    union contents
+    {
+      char yystate[sizeof (glr_state)];
+      char yyoption[sizeof (semantic_option)];
+    };
+    enum { union_size = sizeof (contents) };
+    union {
+      /// Strongest alignment constraints.
+      long double yyalign_me;
+      /// A buffer large enough to store the contents.
+      char raw_[union_size];
+    };
+    /** Type tag for the union. */
+    bool is_state_;
+]b4_parse_assert_if([[
+  public:
+    // Check invariants.
+    void check_ () const
+    {
+      YYASSERT (this->magic_ == MAGIC);
+      YYASSERT (this->is_state_ == false || this->is_state_ == true);
+    }
+    // A magic number to check our pointer arithmetic is sane.
+    enum { MAGIC = 0xDEAD1ACC }; // 3735886540.
+    const unsigned int magic_;]])[
+  }; // class glr_stack_item
+} // namespace
+
+glr_state* glr_state::pred ()
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  YY_IGNORE_NULL_DEREFERENCE_BEGIN
+  return yypred ? &asItem (as_pointer_ (this) - yypred)->getState () : YY_NULLPTR;
+  YY_IGNORE_NULL_DEREFERENCE_END
+}
+
+const glr_state* glr_state::pred () const
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  YY_IGNORE_NULL_DEREFERENCE_BEGIN
+  return yypred ? &asItem (as_pointer_ (this) - yypred)->getState () : YY_NULLPTR;
+  YY_IGNORE_NULL_DEREFERENCE_END
+}
+
+void glr_state::setPred (const glr_state* state)
+{]b4_parse_assert_if([[
+  check_ ();
+  if (state)
+    state->check_ ();]])[
+  yypred = state ? as_pointer_ (this) - as_pointer_ (state) : 0;
+}
+
+semantic_option* glr_state::firstVal ()
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  return yyfirstVal ? &(asItem(this) - yyfirstVal)->getOption() : YY_NULLPTR;
+}
+
+const semantic_option* glr_state::firstVal () const
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  return yyfirstVal ? &(asItem(this) - yyfirstVal)->getOption() : YY_NULLPTR;
+}
+
+void glr_state::setFirstVal (const semantic_option* option)
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  yyfirstVal = option ? asItem(this) - asItem(option) : 0;
+}
+
+std::ptrdiff_t glr_state::indexIn (const glr_stack_item* array) const
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  return asItem(this) - array;
+}
+
+std::ptrdiff_t semantic_option::indexIn (const glr_stack_item* array) const
+{
+  return asItem(this) - array;
+}
+
+glr_state* semantic_option::state ()
+{
+  YY_IGNORE_NULL_DEREFERENCE_BEGIN
+  return yystate ? &(asItem(this) - yystate)->getState() : YY_NULLPTR;
+  YY_IGNORE_NULL_DEREFERENCE_END
+}
+
+const glr_state* semantic_option::state () const
+{
+  return yystate ? &(asItem(this) - yystate)->getState() : YY_NULLPTR;
+}
+
+void semantic_option::setState (const glr_state* s)
+{
+  yystate = s ? asItem(this) - asItem(s) : 0;
+}
+
+const semantic_option* semantic_option::next () const
+{
+  return yynext ? &(asItem(this) - yynext)->getOption() : YY_NULLPTR;
+}
+
+semantic_option* semantic_option::next ()
+{
+  return yynext ? &(asItem(this) - yynext)->getOption() : YY_NULLPTR;
+}
+
+void semantic_option::setNext (const semantic_option* s)
+{
+  yynext = s ? asItem(this) - asItem(s) : 0;
+}
+
+void glr_state::destroy (char const* yymsg, ]b4_namespace_ref[::]b4_parser_class[& yyparser)
+{]b4_parse_assert_if([[
+  check_ ();]])[
+  if (yyresolved)
+    yyparser.yy_destroy_ (yymsg, yy_accessing_symbol(yylrState),
+                          value ()]b4_locations_if([, yyloc])[);
+  else
+    {
+#if ]b4_api_PREFIX[DEBUG
+      YYCDEBUG << yymsg
+               << (firstVal() ? " unresolved " : " incomplete ")
+               << (yy_accessing_symbol (yylrState) < YYNTOKENS ? "token" : "nterm")
+               << ' ' << yyparser.symbol_name (yy_accessing_symbol (yylrState))
+               << " ("]b4_locations_if([[
+               << yyloc << ": "]])[
+               << ")\n";
+#endif
+      if (firstVal() != YY_NULLPTR)
+        {
+          semantic_option& yyoption = *firstVal ();
+          glr_state *yyrh = yyoption.state ();
+          for (int yyn = yyrhsLength (yyoption.yyrule); yyn > 0; yyn -= 1)
+            {
+              yyrh->destroy (yymsg, yyparser);
+              yyrh = yyrh->pred();
+            }
+        }
+    }
+}
+
+
+#undef YYFILL
+#define YYFILL(N) yyfill (yyvsp, yylow, (N), yynormal)
+
+namespace
+{
+  class state_stack
+  {
+  public:
+    using parser_type = ]b4_namespace_ref[::]b4_parser_class[;
+    using symbol_kind = parser_type::symbol_kind;
+    using value_type = parser_type::value_type;]b4_locations_if([[
+    using location_type = parser_type::location_type;]])[
+
+    /** Initialize to a single empty stack, with total maximum
+     *  capacity for all stacks of YYSIZE.  */
+    state_stack (size_t yysize)
+      : yysplitPoint (YY_NULLPTR)
+    {
+      yyitems.reserve (yysize);
+    }
+
+#if YYSTACKEXPANDABLE
+    /** Returns false if it tried to expand but could not. */
+    bool
+    yyexpandGLRStackIfNeeded ()
+    {
+      return YYHEADROOM <= spaceLeft () || yyexpandGLRStack ();
+    }
+
+  private:
+    /** If *this is expandable, extend it.  WARNING: Pointers into the
+        stack from outside should be considered invalid after this call.
+        We always expand when there are 1 or fewer items left AFTER an
+        allocation, so that we can avoid having external pointers exist
+        across an allocation.  */
+    bool
+    yyexpandGLRStack ()
+    {
+      const size_t oldsize = yyitems.size();
+      if (YYMAXDEPTH - YYHEADROOM < oldsize)
+        return false;
+      const size_t yynewSize = YYMAXDEPTH < 2 * oldsize ? YYMAXDEPTH : 2 * oldsize;
+      const glr_stack_item *oldbase = &yyitems[0];
+
+      yyitems.reserve (yynewSize);
+      const glr_stack_item *newbase = &yyitems[0];
+
+      // Adjust the pointers.  Perform raw pointer arithmetic, as there
+      // is no reason for objects to be aligned on their size.
+      const ptrdiff_t disp
+        = reinterpret_cast<const char*> (newbase) - reinterpret_cast<const char*> (oldbase);
+      if (yysplitPoint)
+        const_cast<glr_state*&> (yysplitPoint)
+          = reinterpret_cast<glr_state*> (reinterpret_cast<char*> (const_cast<glr_state*> (yysplitPoint)) + disp);
+
+      for (std::vector<glr_state*>::iterator
+             i = yytops.begin (),
+             yyend = yytops.end ();
+           i != yyend; ++i)
+        if (glr_state_not_null (*i))
+          *i = reinterpret_cast<glr_state*>(reinterpret_cast<char*>(*i) + disp);
+
+      return true;
+    }
+
+  public:
+#else
+    bool yyexpandGLRStackIfNeeded ()
+    {
+      return YYHEADROOM <= spaceLeft ();
+    }
+#endif
+#undef YYSTACKEXPANDABLE
+
+    static bool glr_state_not_null (glr_state* s)
+    {
+      return s != YY_NULLPTR;
+    }
+
+    bool
+    reduceToOneStack ()
+    {
+      using iterator = std::vector<glr_state*>::iterator;
+      const iterator yybegin = yytops.begin();
+      const iterator yyend = yytops.end();
+      const iterator yyit = std::find_if(yybegin, yyend, glr_state_not_null);
+      if (yyit == yyend)
+        return false;
+      for (state_set_index yyk = create_state_set_index(yyit + 1 - yybegin);
+           yyk.uget() != numTops(); ++yyk)
+        yytops.yymarkStackDeleted (yyk);
+      yytops.yyremoveDeletes ();
+      yycompressStack ();
+      return true;
+    }
+
+    /** Called when returning to deterministic operation to clean up the extra
+     * stacks. */
+    void
+    yycompressStack ()
+    {
+      if (yytops.size() != 1 || !isSplit())
+        return;
+
+      // yyr is the state after the split point.
+      glr_state* yyr = YY_NULLPTR;
+      for (glr_state *yyp = firstTop(), *yyq = yyp->pred();
+           yyp != yysplitPoint;
+           yyr = yyp, yyp = yyq, yyq = yyp->pred())
+        yyp->setPred(yyr);
+
+      // This const_cast is okay, since anyway we have access to the mutable
+      // yyitems into which yysplitPoint points.
+      glr_stack_item* nextFreeItem
+        = const_cast<glr_state*> (yysplitPoint)->asItem () + 1;
+      yysplitPoint = YY_NULLPTR;
+      yytops.clearLastDeleted ();
+
+      while (yyr != YY_NULLPTR)
+        {
+          nextFreeItem->setState (*yyr);
+          glr_state& nextFreeState = nextFreeItem->getState();
+          yyr = yyr->pred();
+          nextFreeState.setPred(&(nextFreeItem - 1)->getState());
+          setFirstTop (&nextFreeState);
+          ++nextFreeItem;
+        }
+      yyitems.resize(static_cast<size_t>(nextFreeItem - yyitems.data()));
+    }
+
+    bool isSplit() const {
+      return yysplitPoint != YY_NULLPTR;
+    }
+
+    // Present the interface of a vector of glr_stack_item.
+    std::vector<glr_stack_item>::const_iterator begin () const
+    {
+      return yyitems.begin ();
+    }
+
+    std::vector<glr_stack_item>::const_iterator end () const
+    {
+      return yyitems.end ();
+    }
+
+    size_t size() const
+    {
+      return yyitems.size ();
+    }
+
+    glr_stack_item& operator[] (size_t i)
+    {
+      return yyitems[i];
+    }
+
+    glr_stack_item& stackItemAt (size_t index)
+    {
+      return yyitems[index];
+    }
+
+    size_t numTops () const
+    {
+      return yytops.size ();
+    }
+
+    glr_state* firstTop () const
+    {
+      return yytops[create_state_set_index (0)];
+    }
+
+    glr_state* topAt (state_set_index i) const
+    {
+      return yytops[i];
+    }
+
+    void setFirstTop (glr_state* value)
+    {
+      yytops[create_state_set_index (0)] = value;
+    }
+
+    void setTopAt (state_set_index i, glr_state* value)
+    {
+      yytops[i] = value;
+    }
+
+    void pop_back ()
+    {
+      yyitems.pop_back ();
+    }
+
+    void pop_back (size_t n)
+    {
+      yyitems.resize (yyitems.size () - n);
+    }
+
+    state_set_index
+    yysplitStack (state_set_index yyk)
+    {
+      if (!isSplit ())
+        {
+          YYASSERT (yyk.get () == 0);
+          yysplitPoint = topAt (yyk);
+        }
+      return yytops.yysplitStack (yyk);
+    }
+
+    /** Assuming that YYS is a GLRState somewhere on *this, update the
+     *  splitpoint of *this, if needed, so that it is at least as deep as
+     *  YYS.  */
+    void
+    yyupdateSplit (glr_state& yys)
+    {
+      if (isSplit() && &yys < yysplitPoint)
+        yysplitPoint = &yys;
+    }
+
+    /** Return a fresh GLRState.
+     * Callers should call yyreserveStack afterwards to make sure there is
+     * sufficient headroom.  */
+    glr_state& yynewGLRState (const glr_state& newState)
+    {
+      glr_state& state = yyitems[yynewGLRStackItem (true)].getState ();
+#if false && 201103L <= YY_CPLUSPLUS
+      state = std::move (newState);
+#else
+      state = newState;
+#endif
+      return state;
+    }
+
+    /** Return a fresh SemanticOption.
+     * Callers should call yyreserveStack afterwards to make sure there is
+     * sufficient headroom.  */
+    semantic_option& yynewSemanticOption (semantic_option newOption)
+    {
+      semantic_option& option = yyitems[yynewGLRStackItem (false)].getOption ();
+      option = std::move (newOption);
+      return option;
+    }
+
+    /* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1.  Otherwise, fill in
+     * YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
+     * For convenience, always return YYLOW1.  */
+    int
+    yyfill (glr_stack_item *yyvsp, int &yylow, int yylow1, bool yynormal)
+    {
+      if (!yynormal && yylow1 < yylow)
+        {
+          yyfillin (yyvsp, yylow, yylow1);
+          yylow = yylow1;
+        }
+      return yylow1;
+    }
+
+    /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
+     *  at YYVSP[YYLOW0].getState().pred().  Leaves YYVSP[YYLOW1].getState().pred()
+     *  containing the pointer to the next state in the chain.  */
+    void
+    yyfillin (glr_stack_item *yyvsp, int yylow0, int yylow1)
+    {
+      glr_state* s = yyvsp[yylow0].getState().pred();
+      YYASSERT(s != YY_NULLPTR);
+      for (int i = yylow0-1; i >= yylow1; i -= 1, s = s->pred())
+        {
+          glr_state& yys = yyvsp[i].getState();
+#if ]b4_api_PREFIX[DEBUG
+          yys.yylrState = s->yylrState;
+#endif
+          yys.yyresolved = s->yyresolved;
+          if (s->yyresolved)
+            {]b4_variant_if([[
+              new (&yys.value ()) value_type ();
+              ]b4_symbol_variant([yy_accessing_symbol (s->yylrState)],
+                                 [yys.value ()], [copy], [s->value ()])], [[
+              new (&yys.value ()) value_type (s->value ());]])[
+            }
+          else
+            /* The effect of using yyval or yyloc (in an immediate
+             * rule) is undefined.  */
+            yys.setFirstVal (YY_NULLPTR);]b4_locations_if([[
+          yys.yyloc = s->yyloc;]])[
+          yys.setPred(s->pred());
+        }
+    }
+
+#if ]b4_api_PREFIX[DEBUG
+
+    /*----------------------------------------------------------------------.
+    | Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
+    `----------------------------------------------------------------------*/
+
+    void
+    yy_reduce_print (bool yynormal, glr_stack_item* yyvsp, state_set_index yyk,
+                     rule_num yyrule, parser_type& yyparser)
+    {
+      int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
+      int yylow = 1;])[
+      int yyi;
+      std::cerr << "Reducing stack " << yyk.get() << " by rule " << yyrule - 1
+                << " (line " << int (yyrline[yyrule]) << "):\n";
+      if (! yynormal)
+        yyfillin (yyvsp, 1, -yynrhs);
+      /* The symbols being reduced.  */
+      for (yyi = 0; yyi < yynrhs; yyi++)
+        {
+          std::cerr << "   $" << yyi + 1 << " = ";
+          yyparser.yy_symbol_print_
+            (yy_accessing_symbol (yyvsp[yyi - yynrhs + 1].getState().yylrState),
+             yyvsp[yyi - yynrhs + 1].getState().value ()]b4_locations_if([[,
+             ]b4_rhs_location(yynrhs, yyi + 1)])[);
+          if (!yyvsp[yyi - yynrhs + 1].getState().yyresolved)
+            std::cerr << " (unresolved)";
+          std::cerr << '\n';
+        }
+    }
+
+
+#define YYINDEX(YYX)                                                         \
+      ((YYX) == YY_NULLPTR ? -1 : (YYX)->indexIn (yyitems.data ()))
+
+    void
+    dumpStack () const
+    {
+      for (size_t yyi = 0; yyi < size(); ++yyi)
+        {
+          const glr_stack_item& item = yyitems[yyi];
+          std::cerr << std::setw(3) << yyi << ". ";
+          if (item.is_state())
+            {
+              std::cerr << "Res: " << item.getState().yyresolved
+                        << ", LR State: " << item.getState().yylrState
+                        << ", posn: " << item.getState().yyposn
+                        << ", pred: " << YYINDEX(item.getState().pred());
+              if (! item.getState().yyresolved)
+                std::cerr << ", firstVal: "
+                          << YYINDEX(item.getState().firstVal());
+            }
+          else
+            {
+              std::cerr << "Option. rule: " << item.getOption().yyrule - 1
+                        << ", state: " << YYINDEX(item.getOption().state())
+                        << ", next: " << YYINDEX(item.getOption().next());
+            }
+          std::cerr << '\n';
+        }
+      std::cerr << "Tops:";
+      for (state_set_index yyi = create_state_set_index(0); yyi.uget() < numTops(); ++yyi) {
+        std::cerr << yyi.get() << ": " << YYINDEX(topAt(yyi)) << "; ";
+      }
+      std::cerr << '\n';
+    }
+
+#undef YYINDEX
+#endif
+
+    YYRESULTTAG
+    yyreportAmbiguity (const semantic_option& yyx0,
+                       const semantic_option& yyx1, parser_type& yyparser]b4_locations_if([, const location_type& yyloc])[)
+    {
+      YY_USE (yyx0);
+      YY_USE (yyx1);
+
+#if ]b4_api_PREFIX[DEBUG
+      std::cerr << "Ambiguity detected.\n"
+        "Option 1,\n";
+      yyx0.yyreportTree ();
+      std::cerr << "\nOption 2,\n";
+      yyx1.yyreportTree ();
+      std::cerr << '\n';
+#endif
+
+      yyparser.error (]b4_locations_if([yyloc, ])[YY_("syntax is ambiguous"));
+      return yyabort;
+    }
+
+#if ]b4_api_PREFIX[DEBUG
+    /* Print YYS (possibly NULL) and its predecessors. */
+    void
+    yypstates (const glr_state* yys) const
+    {
+      if (yys != YY_NULLPTR)
+        yys->yy_yypstack();
+      else
+        std::cerr << "<null>";
+      std::cerr << '\n';
+    }
+#endif
+
+  private:
+    size_t spaceLeft() const
+    {
+      return yyitems.capacity() - yyitems.size();
+    }
+
+    /** Return a fresh GLRStackItem in this.  The item is an LR state
+     *  if YYIS_STATE, and otherwise a semantic option.  Callers should call
+     *  yyreserveStack afterwards to make sure there is sufficient
+     *  headroom.  */
+    size_t
+    yynewGLRStackItem (bool yyis_state)
+    {
+      YYDASSERT(yyitems.size() < yyitems.capacity());
+      yyitems.push_back(glr_stack_item(yyis_state));
+      return yyitems.size() - 1;
+    }
+
+
+  public:
+    std::vector<glr_stack_item> yyitems;
+    // Where the stack splits. Anything below this address is deterministic.
+    const glr_state* yysplitPoint;
+    glr_state_set yytops;
+  }; // class state_stack
+} // namespace
+
+#undef YYFILL
+#define YYFILL(N) yystateStack.yyfill (yyvsp, yylow, (N), yynormal)
+
+namespace ]b4_namespace_ref[
+{
+  class ]b4_parser_class[::glr_stack
+  {
+  public:
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+    // Needs access to yypact_value_is_default, etc.
+    friend context;
+]])[
+
+    glr_stack (size_t yysize, parser_type& yyparser_yyarg]m4_ifset([b4_parse_param], [, b4_parse_param_decl])[)
+      : yyerrState (0)
+      , yystateStack (yysize)
+      , yyerrcnt (0)
+      , yyla ()
+      , yyparser (yyparser_yyarg)]m4_ifset([b4_parse_param], [,b4_parse_param_cons])[
+    {}
+
+    ~glr_stack ()
+    {
+      if (!this->yyla.empty ())
+        yyparser.yy_destroy_ ("Cleanup: discarding lookahead",
+                              this->yyla.kind (), this->yyla.value]b4_locations_if([, this->yyla.location])[);
+      popall_ ();
+    }
+
+    int yyerrState;
+]b4_locations_if([[  /* To compute the location of the error token.  */
+    glr_stack_item yyerror_range[3];]])[
+    state_stack yystateStack;
+    int yyerrcnt;
+    symbol_type yyla;
+    YYJMP_BUF yyexception_buffer;
+    parser_type& yyparser;
+
+  #define YYCHK1(YYE)                                                          \
+    do {                                                                       \
+      switch (YYE) {                                                           \
+      case yyok:                                                               \
+        break;                                                                 \
+      case yyabort:                                                            \
+        goto yyabortlab;                                                       \
+      case yyaccept:                                                           \
+        goto yyacceptlab;                                                      \
+      case yyerr:                                                              \
+        goto yyuser_error;                                                     \
+      default:                                                                 \
+        goto yybuglab;                                                         \
+      }                                                                        \
+    } while (false)
+
+    int
+    parse ()
+    {
+      int yyresult;
+      size_t yyposn;
+
+      YYCDEBUG << "Starting parse\n";
+
+      this->yyla.clear ();
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
+      b4_user_initial_action
+b4_dollar_popdef])[]dnl
+[
+      switch (YYSETJMP (this->yyexception_buffer))
+        {
+        case 0: break;
+        case 1: goto yyabortlab;
+        case 2: goto yyexhaustedlab;
+        default: goto yybuglab;
+        }
+      this->yyglrShift (create_state_set_index(0), 0, 0, this->yyla.value]b4_locations_if([, this->yyla.location])[);
+      yyposn = 0;
+
+      while (true)
+        {
+          /* For efficiency, we have two loops, the first of which is
+             specialized to deterministic operation (single stack, no
+             potential ambiguity).  */
+          /* Standard mode */
+          while (true)
+            {
+              const state_num yystate = this->firstTopState()->yylrState;
+              YYCDEBUG << "Entering state " << yystate << '\n';
+              if (yystate == YYFINAL)
+                goto yyacceptlab;
+              if (yy_is_defaulted_state (yystate))
+                {
+                  const rule_num yyrule = yy_default_action (yystate);
+                  if (yyrule == 0)
+                    {]b4_locations_if([[
+                      this->yyerror_range[1].getState().yyloc = this->yyla.location;]])[
+                      this->yyreportSyntaxError ();
+                      goto yyuser_error;
+                    }
+                  YYCHK1 (this->yyglrReduce (create_state_set_index(0), yyrule, true));
+                }
+              else
+                {
+                  yyget_token ();
+                  const short* yyconflicts;
+                  const int yyaction = yygetLRActions (yystate, this->yyla.kind (), yyconflicts);
+                  if (*yyconflicts != 0)
+                    break;
+                  if (yy_is_shift_action (yyaction))
+                    {
+                      YY_SYMBOL_PRINT ("Shifting", this->yyla.kind (), this->yyla.value, this->yyla.location);
+                      yyposn += 1;
+                      // FIXME: we should move yylval.
+                      this->yyglrShift (create_state_set_index(0), yyaction, yyposn, this->yyla.value]b4_locations_if([, this->yyla.location])[);
+                      yyla.clear ();
+                      if (0 < this->yyerrState)
+                        this->yyerrState -= 1;
+                    }
+                  else if (yy_is_error_action (yyaction))
+                    {]b4_locations_if([[
+                      this->yyerror_range[1].getState().yyloc = this->yyla.location;]])[
+                      /* Don't issue an error message again for exceptions
+                         thrown from the scanner.  */
+                      if (this->yyla.kind () != ]b4_symbol(error, kind)[)
+                        this->yyreportSyntaxError ();
+                      goto yyuser_error;
+                    }
+                  else
+                    YYCHK1 (this->yyglrReduce (create_state_set_index(0), -yyaction, true));
+                }
+            }
+
+          while (true)
+            {
+              for (state_set_index yys = create_state_set_index(0); yys.uget() < this->yystateStack.numTops(); ++yys)
+                this->yystateStack.yytops.setLookaheadNeeds(yys, !this->yyla.empty ());
+
+              /* yyprocessOneStack returns one of three things:
+
+                  - An error flag.  If the caller is yyprocessOneStack, it
+                    immediately returns as well.  When the caller is finally
+                    yyparse, it jumps to an error label via YYCHK1.
+
+                  - yyok, but yyprocessOneStack has invoked yymarkStackDeleted
+                    (yys), which sets the top state of yys to NULL.  Thus,
+                    yyparse's following invocation of yyremoveDeletes will remove
+                    the stack.
+
+                  - yyok, when ready to shift a token.
+
+                 Except in the first case, yyparse will invoke yyremoveDeletes and
+                 then shift the next token onto all remaining stacks.  This
+                 synchronization of the shift (that is, after all preceding
+                 reductions on all stacks) helps prevent double destructor calls
+                 on yylval in the event of memory exhaustion.  */
+
+              for (state_set_index yys = create_state_set_index (0); yys.uget () < this->yystateStack.numTops (); ++yys)
+                YYCHK1 (this->yyprocessOneStack (yys, yyposn]b4_locations_if([, &this->yyla.location])[));
+              this->yystateStack.yytops.yyremoveDeletes ();
+              if (this->yystateStack.yytops.size() == 0)
+                {
+                  this->yystateStack.yytops.yyundeleteLastStack ();
+                  if (this->yystateStack.yytops.size() == 0)
+                    this->yyFail (]b4_locations_if([&this->yyla.location, ])[YY_("syntax error"));
+                  YYCHK1 (this->yyresolveStack ());
+                  YYCDEBUG << "Returning to deterministic operation.\n";]b4_locations_if([[
+                  this->yyerror_range[1].getState ().yyloc = this->yyla.location;]])[
+                  this->yyreportSyntaxError ();
+                  goto yyuser_error;
+                }
+
+              /* If any yyglrShift call fails, it will fail after shifting.  Thus,
+                 a copy of yylval will already be on stack 0 in the event of a
+                 failure in the following loop.  Thus, yyla is emptied
+                 before the loop to make sure the user destructor for yylval isn't
+                 called twice.  */
+              symbol_kind_type yytoken_to_shift = this->yyla.kind ();
+              this->yyla.kind_ = ]b4_symbol(empty, kind)[;
+              yyposn += 1;
+              for (state_set_index yys = create_state_set_index (0); yys.uget () < this->yystateStack.numTops (); ++yys)
+                {
+                  const state_num yystate = this->topState (yys)->yylrState;
+                  const short* yyconflicts;
+                  const int yyaction = yygetLRActions (yystate, yytoken_to_shift, yyconflicts);
+                  /* Note that yyconflicts were handled by yyprocessOneStack.  */
+                  YYCDEBUG << "On stack " << yys.get() << ", ";
+                  YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, this->yyla.value, this->yyla.location);
+                  this->yyglrShift (yys, yyaction, yyposn, this->yyla.value]b4_locations_if([, this->yyla.location])[);
+                  YYCDEBUG << "Stack " << yys.get() << " now in state "
+                           << this->topState(yys)->yylrState << '\n';
+                }
+]b4_variant_if([[
+                // FIXME: User destructors.
+                // Value type destructor.
+                ]b4_symbol_variant([[yytoken_to_shift]], [[this->yyla.value]], [[template destroy]])])[
+
+              if (this->yystateStack.yytops.size () == 1)
+                {
+                  YYCHK1 (this->yyresolveStack ());
+                  YYCDEBUG << "Returning to deterministic operation.\n";
+                  this->yystateStack.yycompressStack ();
+                  break;
+                }
+            }
+          continue;
+        yyuser_error:
+          this->yyrecoverSyntaxError (]b4_locations_if([&this->yyla.location])[);
+          yyposn = this->firstTopState()->yyposn;
+        }
+
+    yyacceptlab:
+      yyresult = 0;
+      goto yyreturn;
+
+    yybuglab:
+      YYASSERT (false);
+      goto yyabortlab;
+
+    yyabortlab:
+      yyresult = 1;
+      goto yyreturn;
+
+    yyexhaustedlab:
+      yyparser.error (]b4_locations_if([this->yyla.location, ])[YY_("memory exhausted"));
+      yyresult = 2;
+      goto yyreturn;
+
+    yyreturn:
+      return yyresult;
+    }
+  #undef YYCHK1
+
+    void yyreserveGlrStack ()
+    {
+      if (!yystateStack.yyexpandGLRStackIfNeeded ())
+        yyMemoryExhausted ();
+    }
+
+    _Noreturn void
+    yyMemoryExhausted ()
+    {
+      YYLONGJMP (yyexception_buffer, 2);
+    }
+
+    _Noreturn void
+    yyFail (]b4_locations_if([location_type* yylocp, ])[const char* yymsg)
+    {
+      if (yymsg != YY_NULLPTR)
+        yyparser.error (]b4_locations_if([*yylocp, ])[yymsg);
+      YYLONGJMP (yyexception_buffer, 1);
+    }
+
+                                  /* GLRStates */
+
+
+    /** Add a new semantic action that will execute the action for rule
+     *  YYRULE on the semantic values in YYRHS to the list of
+     *  alternative actions for YYSTATE.  Assumes that YYRHS comes from
+     *  stack #YYK of *this. */
+    void
+    yyaddDeferredAction (state_set_index yyk, glr_state* yystate,
+                         glr_state* yyrhs, rule_num yyrule)
+    {
+      semantic_option& yyopt = yystateStack.yynewSemanticOption (semantic_option (yyrule));
+      yyopt.setState (yyrhs);
+      yyopt.setNext (yystate->firstVal ());
+      if (yystateStack.yytops.lookaheadNeeds (yyk))
+        yyopt.yyla = this->yyla;
+      yystate->setFirstVal (&yyopt);
+
+      yyreserveGlrStack ();
+    }
+
+  #if ]b4_api_PREFIX[DEBUG
+    void yypdumpstack () const
+    {
+      yystateStack.dumpStack();
+    }
+  #endif
+
+    void
+    yyreportSyntaxError ()
+    {
+      if (yyerrState != 0)
+        return;
+]b4_parse_error_case(
+[simple], [[
+      std::string msg = YY_("syntax error");
+      yyparser.error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]],
+[custom], [[
+      context yyctx (*this, yyla);
+      yyparser.report_syntax_error (yyctx);]],
+[[
+      context yyctx (*this, yyla);
+      std::string msg = yyparser.yysyntax_error_ (yyctx);
+      yyparser.error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]])[
+      yyerrcnt += 1;
+    }
+
+    /* Recover from a syntax error on this, assuming that yytoken,
+       yylval, and yylloc are the syntactic category, semantic value, and location
+       of the lookahead.  */
+    void
+    yyrecoverSyntaxError (]b4_locations_if([location_type* yylocp])[)
+    {
+      if (yyerrState == 3)
+        /* We just shifted the error token and (perhaps) took some
+           reductions.  Skip tokens until we can proceed.  */
+        while (true)
+          {
+            if (this->yyla.kind () == ]b4_symbol(eof, kind)[)
+              yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
+            if (this->yyla.kind () != ]b4_symbol(empty, kind)[)
+              {]b4_locations_if([[
+                /* We throw away the lookahead, but the error range
+                   of the shifted error token must take it into account.  */
+                glr_state *yys = firstTopState();
+                yyerror_range[1].getState().yyloc = yys->yyloc;
+                yyerror_range[2].getState().yyloc = this->yyla.location;
+                YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);]])[
+                yyparser.yy_destroy_ ("Error: discarding",
+                                      this->yyla.kind (), this->yyla.value]b4_locations_if([, this->yyla.location])[);]b4_variant_if([[
+                // Value type destructor.
+                ]b4_symbol_variant([[this->yyla.kind ()]], [[this->yyla.value]], [[template destroy]])])[
+                this->yyla.kind_ = ]b4_symbol(empty, kind)[;
+              }
+            yyget_token ();
+            int yyj = yypact[firstTopState()->yylrState];
+            if (yypact_value_is_default (yyj))
+              return;
+            yyj += this->yyla.kind ();
+            if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != this->yyla.kind ())
+              {
+                if (yydefact[firstTopState()->yylrState] != 0)
+                  return;
+              }
+            else if (! yytable_value_is_error (yytable[yyj]))
+              return;
+          }
+
+      if (!yystateStack.reduceToOneStack())
+        yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
+
+      /* Now pop stack until we find a state that shifts the error token.  */
+      yyerrState = 3;
+      while (firstTopState () != YY_NULLPTR)
+        {
+          glr_state *yys = firstTopState ();
+          int yyj = yypact[yys->yylrState];
+          if (! yypact_value_is_default (yyj))
+            {
+              yyj += YYTERROR;
+              if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR
+                  && yy_is_shift_action (yytable[yyj]))
+                {
+                  /* Shift the error token.  */]b4_locations_if([[
+                  /* First adjust its location.*/
+                  location_type yyerrloc;
+                  yyerror_range[2].getState().yyloc = this->yyla.location;
+                  YYLLOC_DEFAULT (yyerrloc, (yyerror_range), 2);]])[
+                  YY_SYMBOL_PRINT ("Shifting", yy_accessing_symbol (yytable[yyj]),
+                                   this->yyla.value, yyerrloc);
+                  yyglrShift (create_state_set_index(0), yytable[yyj],
+                              yys->yyposn, yyla.value]b4_locations_if([, yyerrloc])[);
+                  yys = firstTopState();
+                  break;
+                }
+            }]b4_locations_if([[
+          yyerror_range[1].getState().yyloc = yys->yyloc;]])[
+          if (yys->pred() != YY_NULLPTR)
+            yys->destroy ("Error: popping", yyparser);
+          yystateStack.setFirstTop(yys->pred());
+          yystateStack.pop_back();
+        }
+      if (firstTopState() == YY_NULLPTR)
+        yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
+    }
+
+    YYRESULTTAG
+    yyprocessOneStack (state_set_index yyk,
+                       size_t yyposn]b4_locations_if([, location_type* yylocp])[)
+    {
+      while (yystateStack.topAt(yyk) != YY_NULLPTR)
+        {
+          const state_num yystate = topState(yyk)->yylrState;
+          YYCDEBUG << "Stack " << yyk.get()
+                   << " Entering state " << yystate << '\n';
+
+          YYASSERT (yystate != YYFINAL);
+
+          if (yy_is_defaulted_state (yystate))
+            {
+              const rule_num yyrule = yy_default_action (yystate);
+              if (yyrule == 0)
+                {
+                  YYCDEBUG << "Stack " << yyk.get() << " dies.\n";
+                  yystateStack.yytops.yymarkStackDeleted (yyk);
+                  return yyok;
+                }
+              const YYRESULTTAG yyflag
+                = yyglrReduce (yyk, yyrule, yyimmediate[yyrule]);
+              if (yyflag == yyerr)
+                {
+                  YYCDEBUG << "Stack " << yyk.get() << " dies"
+                    " (predicate failure or explicit user error).\n";
+                  yystateStack.yytops.yymarkStackDeleted (yyk);
+                  return yyok;
+                }
+              if (yyflag != yyok)
+                return yyflag;
+            }
+          else
+            {
+              yystateStack.yytops.setLookaheadNeeds(yyk, true);
+              yyget_token ();
+              const short* yyconflicts;
+              const int yyaction = yygetLRActions (yystate, this->yyla.kind (), yyconflicts);
+
+              for (; *yyconflicts != 0; ++yyconflicts)
+                {
+                  state_set_index yynewStack = yystateStack.yysplitStack (yyk);
+                  YYCDEBUG << "Splitting off stack " << yynewStack.get()
+                           << " from " << yyk.get() << ".\n";
+                  YYRESULTTAG yyflag =
+                    yyglrReduce (yynewStack, *yyconflicts, yyimmediate[*yyconflicts]);
+                  if (yyflag == yyok)
+                    YYCHK (yyprocessOneStack (yynewStack,
+                                              yyposn]b4_locations_if([, yylocp])[));
+                  else if (yyflag == yyerr)
+                    {
+                      YYCDEBUG << "Stack " << yynewStack.get() << " dies.\n";
+                      yystateStack.yytops.yymarkStackDeleted (yynewStack);
+                    }
+                  else
+                    return yyflag;
+                }
+
+              if (yy_is_shift_action (yyaction))
+                break;
+              else if (yy_is_error_action (yyaction))
+                {
+                  YYCDEBUG << "Stack " << yyk.get() << " dies.\n";
+                  yystateStack.yytops.yymarkStackDeleted (yyk);
+                  break;
+                }
+              else
+                {
+                  YYRESULTTAG yyflag
+                    = yyglrReduce (yyk, -yyaction, yyimmediate[-yyaction]);
+                  if (yyflag == yyerr)
+                    {
+                      YYCDEBUG << "Stack " << yyk.get() << " dies"
+                        " (predicate failure or explicit user error).\n";
+                      yystateStack.yytops.yymarkStackDeleted (yyk);
+                      break;
+                    }
+                  else if (yyflag != yyok)
+                    return yyflag;
+                }
+            }
+        }
+      return yyok;
+    }
+
+    /** Perform user action for rule number YYN, with RHS length YYRHSLEN,
+     *  and top stack item YYVSP.  YYVALP points to place to put semantic
+     *  value ($$), and yylocp points to place for location information
+     *  (@@$).  Returns yyok for normal return, yyaccept for YYACCEPT,
+     *  yyerr for YYERROR, yyabort for YYABORT.  */
+    YYRESULTTAG
+    yyuserAction (rule_num yyrule, int yyrhslen, glr_stack_item* yyvsp, state_set_index yyk,
+                  value_type* yyvalp]b4_locations_if([, location_type* yylocp])[)
+    {
+      bool yynormal YY_ATTRIBUTE_UNUSED = !yystateStack.isSplit();
+      int yylow = 1;
+]b4_parse_param_use([yyvalp], [yylocp])dnl
+[      YY_USE (yyk);
+      YY_USE (yyrhslen);
+    # undef yyerrok
+    # define yyerrok (yyerrState = 0)
+    # undef YYACCEPT
+    # define YYACCEPT return yyaccept
+    # undef YYABORT
+    # define YYABORT return yyabort
+    # undef YYERROR
+    # define YYERROR return yyerrok, yyerr
+    # undef YYRECOVERING
+    # define YYRECOVERING() (yyerrState != 0)
+    # undef yytoken
+    # define yytoken this->yyla.kind_
+    # undef yyclearin
+    # define yyclearin (yytoken = ]b4_symbol(empty, kind)[)
+    # undef YYBACKUP
+    # define YYBACKUP(Token, Value)                                              \
+      return yyparser.error (]b4_locations_if([*yylocp, ])[YY_("syntax error: cannot back up")),     \
+             yyerrok, yyerr
+
+]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.  */
+      // However we really need to prepare yyvsp now if we want to get
+      // correct locations, so invoke YYFILL for $1 anyway.
+      (void) YYFILL (1-yyrhslen);
+      ]b4_symbol_variant([[yylhsNonterm (yyrule)]], [(*yyvalp)], [emplace])], [[
+      if (yyrhslen == 0)
+        *yyvalp = yyval_default;
+      else
+        *yyvalp = yyvsp[YYFILL (1-yyrhslen)].getState().value ();]])[]b4_locations_if([[
+      /* Default location. */
+      YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
+      yyerror_range[1].getState().yyloc = *yylocp;
+]])[
+    /* If yyk == -1, we are running a deferred action on a temporary
+       stack.  In that case, YY_REDUCE_PRINT must not play with YYFILL,
+       so pretend the stack is "normal". */
+    YY_REDUCE_PRINT ((yynormal || yyk == create_state_set_index (-1), yyvsp, yyk, yyrule, yyparser));
+    #if YY_EXCEPTIONS
+      try
+      {
+    #endif // YY_EXCEPTIONS
+      switch (yyrule)
+        {
+    ]b4_user_actions[
+          default: break;
+        }
+    #if YY_EXCEPTIONS
+      }
+      catch (const syntax_error& yyexc)
+        {
+          YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';]b4_locations_if([
+          *yylocp = yyexc.location;])[
+          yyparser.error (]b4_locations_if([*yylocp, ])[yyexc.what ());
+          YYERROR;
+        }
+    #endif // YY_EXCEPTIONS
+    YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), *yyvalp, *yylocp);
+
+      return yyok;
+    # undef yyerrok
+    # undef YYABORT
+    # undef YYACCEPT
+    # undef YYERROR
+    # undef YYBACKUP
+    # undef yytoken
+    # undef yyclearin
+    # undef YYRECOVERING
+    }
+
+    YYRESULTTAG
+    yyresolveStack ()
+    {
+      if (yystateStack.isSplit ())
+        {
+          int yyn = 0;
+          for (glr_state* yys = firstTopState ();
+               yys != yystateStack.yysplitPoint;
+               yys = yys->pred ())
+            yyn += 1;
+          YYCHK (yyresolveStates (*firstTopState (), yyn));
+        }
+      return yyok;
+    }
+
+    /** Pop the symbols consumed by reduction #YYRULE from the top of stack
+     *  #YYK of *YYSTACKP, and perform the appropriate semantic action on their
+     *  semantic values.  Assumes that all ambiguities in semantic values
+     *  have been previously resolved.  Set *YYVALP to the resulting value,
+     *  and *YYLOCP to the computed location (if any).  Return value is as
+     *  for userAction.  */
+    YYRESULTTAG
+    yydoAction (state_set_index yyk, rule_num yyrule,
+                value_type* yyvalp]b4_locations_if([, location_type* yylocp])[)
+    {
+      const int yynrhs = yyrhsLength (yyrule);
+
+      if (!yystateStack.isSplit())
+        {
+          /* Standard special case: single stack.  */
+          YYASSERT (yyk.get() == 0);
+          glr_stack_item* yyrhs = yystateStack.firstTop()->asItem();
+          const YYRESULTTAG res
+            = yyuserAction (yyrule, yynrhs, yyrhs, yyk, yyvalp]b4_locations_if([, yylocp])[);
+          yystateStack.pop_back(static_cast<size_t>(yynrhs));
+          yystateStack.setFirstTop(&yystateStack[yystateStack.size() - 1].getState());
+          return res;
+        }
+      else
+        {
+          glr_stack_item yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+          glr_state* yys = yystateStack.topAt(yyk);
+          yyrhsVals[YYMAXRHS + YYMAXLEFT].getState().setPred(yys);]b4_locations_if([[
+          if (yynrhs == 0)
+            /* Set default location.  */
+            yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].getState().yyloc = yys->yyloc;]])[
+          for (int yyi = 0; yyi < yynrhs; yyi += 1)
+            {
+              yys = yys->pred();
+              YYASSERT (yys != YY_NULLPTR);
+            }
+          yystateStack.yyupdateSplit (*yys);
+          yystateStack.setTopAt(yyk, yys);
+          return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
+                               yyk,
+                               yyvalp]b4_locations_if([, yylocp])[);
+        }
+    }
+
+    /** Pop items off stack #YYK of *YYSTACKP according to grammar rule YYRULE,
+     *  and push back on the resulting nonterminal symbol.  Perform the
+     *  semantic action associated with YYRULE and store its value with the
+     *  newly pushed state, if YYFORCEEVAL or if *YYSTACKP is currently
+     *  unambiguous.  Otherwise, store the deferred semantic action with
+     *  the new state.  If the new state would have an identical input
+     *  position, LR state, and predecessor to an existing state on the stack,
+     *  it is identified with that existing state, eliminating stack #YYK from
+     *  *YYSTACKP.  In this case, the semantic value is
+     *  added to the options for the existing state's semantic value.
+     */
+    YYRESULTTAG
+    yyglrReduce (state_set_index yyk, rule_num yyrule, bool yyforceEval)
+    {
+      size_t yyposn = topState(yyk)->yyposn;
+
+      if (yyforceEval || !yystateStack.isSplit())
+        {
+          value_type val;]b4_locations_if([[
+          location_type loc;]])[
+
+          YYRESULTTAG yyflag = yydoAction (yyk, yyrule, &val]b4_locations_if([, &loc])[);
+          if (yyflag == yyerr && yystateStack.isSplit())
+            {]b4_parse_trace_if([[
+              YYCDEBUG << "Parse on stack " << yyk.get ()
+                       << " rejected by rule " << yyrule - 1
+                       << " (line " << int (yyrline[yyrule]) << ").\n";
+            ]])[}
+          if (yyflag != yyok)
+            return yyflag;
+          yyglrShift (yyk,
+                      yyLRgotoState (topState(yyk)->yylrState,
+                                     yylhsNonterm (yyrule)),
+                      yyposn, val]b4_locations_if([, loc])[);]b4_variant_if([[
+          // FIXME: User destructors.
+          // Value type destructor.
+          ]b4_symbol_variant([[yylhsNonterm (yyrule)]], [[val]], [[template destroy]])])[
+        }
+      else
+        {
+          glr_state *yys = yystateStack.topAt(yyk);
+          glr_state *yys0 = yys;
+          for (int yyn = yyrhsLength (yyrule); 0 < yyn; yyn -= 1)
+            {
+              yys = yys->pred();
+              YYASSERT (yys != YY_NULLPTR);
+            }
+          yystateStack.yyupdateSplit (*yys);
+          state_num yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));]b4_parse_trace_if([[
+          YYCDEBUG << "Reduced stack " << yyk.get ()
+                   << " by rule " << yyrule - 1 << " (line " << int (yyrline[yyrule])
+                   << "); action deferred.  Now in state " << yynewLRState
+                   << ".\n";]])[
+          for (state_set_index yyi = create_state_set_index(0); yyi.uget() < yystateStack.numTops(); ++yyi)
+            if (yyi != yyk && yystateStack.topAt(yyi) != YY_NULLPTR)
+              {
+                const glr_state* yysplit = yystateStack.yysplitPoint;
+                glr_state* yyp = yystateStack.topAt(yyi);
+                while (yyp != yys && yyp != yysplit
+                       && yyp->yyposn >= yyposn)
+                  {
+                    if (yyp->yylrState == yynewLRState
+                        && yyp->pred() == yys)
+                      {
+                        yyaddDeferredAction (yyk, yyp, yys0, yyrule);
+                        yystateStack.yytops.yymarkStackDeleted (yyk);
+                        YYCDEBUG << "Merging stack " << yyk.get ()
+                                 << " into stack " << yyi.get () << ".\n";
+                        return yyok;
+                      }
+                    yyp = yyp->pred();
+                  }
+              }
+          yystateStack.setTopAt(yyk, yys);
+          yyglrShiftDefer (yyk, yynewLRState, yyposn, yys0, yyrule);
+        }
+      return yyok;
+    }
+
+    /** Shift stack #YYK of *YYSTACKP, to a new state corresponding to LR
+     *  state YYLRSTATE, at input position YYPOSN, with the (unresolved)
+     *  semantic value of YYRHS under the action for YYRULE.  */
+    void
+    yyglrShiftDefer (state_set_index yyk, state_num yylrState,
+                     size_t yyposn, glr_state* yyrhs, rule_num yyrule)
+    {
+      glr_state& yynewState = yystateStack.yynewGLRState (
+        glr_state (yylrState, yyposn));
+      yynewState.setPred (yystateStack.topAt (yyk));
+      yystateStack.setTopAt (yyk, &yynewState);
+
+      /* Invokes yyreserveStack.  */
+      yyaddDeferredAction (yyk, &yynewState, yyrhs, yyrule);
+    }
+
+    /** Shift to a new state on stack #YYK of *YYSTACKP, corresponding to LR
+     * state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
+     * value YYVAL_ARG and source location YYLOC_ARG.  */
+    void
+    yyglrShift (state_set_index yyk, state_num yylrState,
+                size_t yyposn,
+                const value_type& yyval_arg]b4_locations_if([, const location_type& yyloc_arg])[)
+    {
+      glr_state& yynewState = yystateStack.yynewGLRState (
+        glr_state (yylrState, yyposn, yyval_arg]b4_locations_if([, yyloc_arg])[));
+      yynewState.setPred (yystateStack.topAt(yyk));
+      yystateStack.setTopAt (yyk, &yynewState);
+      yyreserveGlrStack ();
+    }
+
+#if ]b4_api_PREFIX[DEBUG
+    void
+    yypstack (state_set_index yyk) const
+    {
+      yystateStack.yypstates (yystateStack.topAt (yyk));
+    }
+#endif
+
+    glr_state* topState(state_set_index i) {
+      return yystateStack.topAt(i);
+    }
+
+    glr_state* firstTopState() {
+      return yystateStack.firstTop();
+    }
+
+  private:
+
+    void popall_ ()
+    {
+      /* If the stack is well-formed, pop the stack until it is empty,
+         destroying its entries as we go.  But free the stack regardless
+         of whether it is well-formed.  */
+      for (state_set_index k = create_state_set_index(0); k.uget() < yystateStack.numTops(); k += 1)
+        if (yystateStack.topAt(k) != YY_NULLPTR)
+          {
+            while (yystateStack.topAt(k) != YY_NULLPTR)
+              {
+                glr_state* state = topState(k);]b4_locations_if([[
+                yyerror_range[1].getState().yyloc = state->yyloc;]])[
+                if (state->pred() != YY_NULLPTR)
+                  state->destroy ("Cleanup: popping", yyparser);
+                yystateStack.setTopAt(k, state->pred());
+                yystateStack.pop_back();
+              }
+              break;
+          }
+    }
+
+    /** Resolve the previous YYN states starting at and including state YYS
+     *  on *YYSTACKP. If result != yyok, some states may have been left
+     *  unresolved possibly with empty semantic option chains.  Regardless
+     *  of whether result = yyok, each state has been left with consistent
+     *  data so that destroy can be invoked if necessary.  */
+    YYRESULTTAG
+    yyresolveStates (glr_state& yys, int yyn)
+    {
+      if (0 < yyn)
+        {
+          YYASSERT (yys.pred() != YY_NULLPTR);
+          YYCHK (yyresolveStates (*yys.pred(), yyn-1));
+          if (! yys.yyresolved)
+            YYCHK (yyresolveValue (yys));
+        }
+      return yyok;
+    }
+
+    static void
+    yyuserMerge (int yyn, value_type& yy0, value_type& yy1)
+    {
+      YY_USE (yy0);
+      YY_USE (yy1);
+
+      switch (yyn)
+        {
+]b4_mergers[
+          default: break;
+        }
+    }
+
+    /** Resolve the ambiguity represented in state YYS in *YYSTACKP,
+     *  perform the indicated actions, and set the semantic value of YYS.
+     *  If result != yyok, the chain of semantic options in YYS has been
+     *  cleared instead or it has been left unmodified except that
+     *  redundant options may have been removed.  Regardless of whether
+     *  result = yyok, YYS has been left with consistent data so that
+     *  destroy can be invoked if necessary.  */
+    YYRESULTTAG
+    yyresolveValue (glr_state& yys)
+    {
+      semantic_option* yybest = yys.firstVal();
+      YYASSERT(yybest != YY_NULLPTR);
+      bool yymerge = false;
+      YYRESULTTAG yyflag;]b4_locations_if([
+      location_type *yylocp = &yys.yyloc;])[
+
+      semantic_option* yypPrev = yybest;
+      for (semantic_option* yyp = yybest->next();
+           yyp != YY_NULLPTR; )
+        {
+          if (yybest->isIdenticalTo (*yyp))
+            {
+              yybest->mergeWith (*yyp);
+              yypPrev->setNext(yyp->next());
+              yyp = yypPrev->next();
+            }
+          else
+            {
+              switch (yypreference (*yybest, *yyp))
+                {
+                case 0:]b4_locations_if([[
+                  yyresolveLocations (yys, 1);]])[
+                  return yystateStack.yyreportAmbiguity (*yybest, *yyp, yyparser]b4_locations_if([, *yylocp])[);
+                  break;
+                case 1:
+                  yymerge = true;
+                  break;
+                case 2:
+                  break;
+                case 3:
+                  yybest = yyp;
+                  yymerge = false;
+                  break;
+                default:
+                  /* This cannot happen so it is not worth a YYASSERT (false),
+                     but some compilers complain if the default case is
+                     omitted.  */
+                  break;
+                }
+              yypPrev = yyp;
+              yyp = yyp->next();
+            }
+        }
+
+      value_type val;
+      if (yymerge)
+        {
+          int yyprec = yydprec[yybest->yyrule];
+          yyflag = yyresolveAction (*yybest, &val]b4_locations_if([, yylocp])[);
+          if (yyflag == yyok)
+            for (semantic_option* yyp = yybest->next();
+                 yyp != YY_NULLPTR;
+                 yyp = yyp->next())
+              {
+                if (yyprec == yydprec[yyp->yyrule])
+                  {
+                    value_type yyval_other;]b4_locations_if([
+                    location_type yydummy;])[
+                    yyflag = yyresolveAction (*yyp, &yyval_other]b4_locations_if([, &yydummy])[);
+                    if (yyflag != yyok)
+                      {
+                        yyparser.yy_destroy_ ("Cleanup: discarding incompletely merged value for",
+                                              yy_accessing_symbol (yys.yylrState),
+                                              this->yyla.value]b4_locations_if([, *yylocp])[);
+                        break;
+                      }
+                    yyuserMerge (yymerger[yyp->yyrule], val, yyval_other);]b4_variant_if([[
+                    // FIXME: User destructors.
+                    // Value type destructor.
+                    ]b4_symbol_variant([[yy_accessing_symbol (yys.yylrState)]], [[yyval_other]], [[template destroy]])])[
+                  }
+              }
+        }
+      else
+        yyflag = yyresolveAction (*yybest, &val]b4_locations_if([, yylocp])[);
+
+      if (yyflag == yyok)
+        {
+          yys.yyresolved = true;
+          YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN]b4_variant_if([[
+          new (&yys.value ()) value_type ();
+          ]b4_symbol_variant([yy_accessing_symbol (yys.yylrState)],
+                             [yys.value ()], [copy], [val])], [[
+          new (&yys.value ()) value_type (val);]])[
+
+          YY_IGNORE_MAYBE_UNINITIALIZED_END
+        }
+      else
+        yys.setFirstVal(YY_NULLPTR);
+]b4_variant_if([[
+      // FIXME: User destructors.
+      // Value type destructor.
+      ]b4_symbol_variant([[yy_accessing_symbol (yys.yylrState)]], [[val]], [[template destroy]])])[
+      return yyflag;
+    }
+
+    /** Resolve the states for the RHS of YYOPT on *YYSTACKP, perform its
+     *  user action, and return the semantic value and location in *YYVALP
+     *  and *YYLOCP.  Regardless of whether result = yyok, all RHS states
+     *  have been destroyed (assuming the user action destroys all RHS
+     *  semantic values if invoked).  */
+    YYRESULTTAG
+    yyresolveAction (semantic_option& yyopt, value_type* yyvalp]b4_locations_if([, location_type* yylocp])[)
+    {
+      glr_state* yyoptState = yyopt.state();
+      YYASSERT(yyoptState != YY_NULLPTR);
+      int yynrhs = yyrhsLength (yyopt.yyrule);
+      YYRESULTTAG yyflag = yyresolveStates (*yyoptState, yynrhs);
+      if (yyflag != yyok)
+        {
+          for (glr_state *yys = yyoptState; yynrhs > 0; yys = yys->pred(), yynrhs -= 1)
+            yys->destroy ("Cleanup: popping", yyparser);
+          return yyflag;
+        }
+
+      glr_stack_item yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+      yyrhsVals[YYMAXRHS + YYMAXLEFT].getState().setPred(yyopt.state());]b4_locations_if([[
+      if (yynrhs == 0)
+        /* Set default location.  */
+        yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].getState().yyloc = yyoptState->yyloc;]])[
+      {
+        symbol_type yyla_current = std::move (this->yyla);
+        this->yyla = std::move (yyopt.yyla);
+        yyflag = yyuserAction (yyopt.yyrule, yynrhs,
+                               yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
+                               create_state_set_index (-1),
+                               yyvalp]b4_locations_if([, yylocp])[);
+        this->yyla = std::move (yyla_current);
+      }
+      return yyflag;
+    }]b4_locations_if([[
+
+    /** Resolve the locations for each of the YYN1 states in *YYSTACKP,
+     *  ending at YYS1.  Has no effect on previously resolved states.
+     *  The first semantic option of a state is always chosen.  */
+    void
+    yyresolveLocations (glr_state &yys1, int yyn1)
+    {
+      if (0 < yyn1)
+        {
+          yyresolveLocations (*yys1.pred(), yyn1 - 1);
+          if (!yys1.yyresolved)
+            {
+              glr_stack_item yyrhsloc[1 + YYMAXRHS];
+              YYASSERT (yys1.firstVal() != YY_NULLPTR);
+              semantic_option& yyoption = *yys1.firstVal();
+              const int yynrhs = yyrhsLength (yyoption.yyrule);
+              if (0 < yynrhs)
+                {
+                  yyresolveLocations (*yyoption.state(), yynrhs);
+                  const glr_state *yys = yyoption.state();
+                  for (int yyn = yynrhs; yyn > 0; yyn -= 1)
+                  {
+                    yyrhsloc[yyn].getState().yyloc = yys->yyloc;
+                    yys = yys->pred();
+                  }
+                }
+              else
+                {
+                  /* Both yyresolveAction and yyresolveLocations traverse the GSS
+                     in reverse rightmost order.  It is only necessary to invoke
+                     yyresolveLocations on a subforest for which yyresolveAction
+                     would have been invoked next had an ambiguity not been
+                     detected.  Thus the location of the previous state (but not
+                     necessarily the previous state itself) is guaranteed to be
+                     resolved already.  */
+                  YY_IGNORE_NULL_DEREFERENCE_BEGIN
+                  yyrhsloc[0].getState().yyloc = yyoption.state()->yyloc;
+                  YY_IGNORE_NULL_DEREFERENCE_END
+                }
+              YYLLOC_DEFAULT ((yys1.yyloc), yyrhsloc, yynrhs);
+            }
+        }
+    }]])[
+
+    /** If yytoken is empty, fetch the next token.  */
+    void
+    yyget_token ()
+    {
+]b4_parse_param_use()dnl
+[      if (this->yyla.empty ())
+        {
+          YYCDEBUG << "Reading a token\n";
+#if YY_EXCEPTIONS
+          try
+#endif // YY_EXCEPTIONS
+            {]b4_token_ctor_if([[
+              symbol_type yylookahead (]b4_yylex[);
+              yyla.move (yylookahead);]], [[
+              yyla.kind_ = yyparser.yytranslate_ (]b4_yylex[);]])[
+            }
+#if YY_EXCEPTIONS
+          catch (const parser_type::syntax_error& yyexc)
+            {
+              YYCDEBUG << "Caught exception: " << yyexc.what () << '\n';]b4_locations_if([
+              this->yyla.location = yyexc.location;])[
+              yyparser.error (]b4_locations_if([this->yyla.location, ])[yyexc.what ());
+              // Map errors caught in the scanner to the error token, so that error
+              // handling is started.
+              this->yyla.kind_ = ]b4_symbol(error, kind)[;
+            }
+        }
+#endif // YY_EXCEPTIONS
+      if (this->yyla.kind () == ]b4_symbol(eof, kind)[)
+        YYCDEBUG << "Now at end of input.\n";
+      else
+        YY_SYMBOL_PRINT ("Next token is", this->yyla.kind (), this->yyla.value, this->yyla.location);
+    }
+
+
+                                /* Bison grammar-table manipulation.  */
+
+    /** The action to take in YYSTATE on seeing YYTOKEN.
+     *  Result R means
+     *    R < 0:  Reduce on rule -R.
+     *    R = 0:  Error.
+     *    R > 0:  Shift to state R.
+     *  Set *YYCONFLICTS to a pointer into yyconfl to a 0-terminated list
+     *  of conflicting reductions.
+     */
+    static int
+    yygetLRActions (state_num yystate, symbol_kind_type yytoken, const short*& yyconflicts)
+    {
+      int yyindex = yypact[yystate] + yytoken;
+      if (yytoken == ]b4_symbol(error, kind)[)
+        {
+          // This is the error token.
+          yyconflicts = yyconfl;
+          return 0;
+        }
+      else if (yy_is_defaulted_state (yystate)
+               || yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
+        {
+          yyconflicts = yyconfl;
+          return -yydefact[yystate];
+        }
+      else if (! yytable_value_is_error (yytable[yyindex]))
+        {
+          yyconflicts = yyconfl + yyconflp[yyindex];
+          return yytable[yyindex];
+        }
+      else
+        {
+          yyconflicts = yyconfl + yyconflp[yyindex];
+          return 0;
+        }
+    }
+
+    /** Compute post-reduction state.
+     * \param yystate   the current state
+     * \param yysym     the nonterminal to push on the stack
+     */
+    static state_num
+    yyLRgotoState (state_num yystate, symbol_kind_type yysym)
+    {
+      const int yyr = yypgoto[yysym - YYNTOKENS] + yystate;
+      if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
+        return yytable[yyr];
+      else
+        return yydefgoto[yysym - YYNTOKENS];
+    }
+
+    static bool
+    yypact_value_is_default (state_num yystate)
+    {
+      return ]b4_table_value_equals([[pact]], [[yystate]], [b4_pact_ninf], [YYPACT_NINF])[;
+    }
+
+    static bool
+    yytable_value_is_error (int yytable_value YY_ATTRIBUTE_UNUSED)
+    {
+      return ]b4_table_value_equals([[table]], [[yytable_value]], [b4_table_ninf], [YYTABLE_NINF])[;
+    }
+
+    static bool
+    yy_is_shift_action (int yyaction) YY_NOEXCEPT
+    {
+      return 0 < yyaction;
+    }
+
+    static bool
+    yy_is_error_action (int yyaction) YY_NOEXCEPT
+    {
+      return yyaction == 0;
+    }
+
+    /** Whether LR state YYSTATE has only a default reduction
+     *  (regardless of token).  */
+    static bool
+    yy_is_defaulted_state (state_num yystate)
+    {
+      return yypact_value_is_default (yypact[yystate]);
+    }
+
+    /** The default reduction for YYSTATE, assuming it has one.  */
+    static rule_num
+    yy_default_action (state_num yystate)
+    {
+      return yydefact[yystate];
+    }
+
+                                    /* GLRStacks */
+
+    /** Y0 and Y1 represent two possible actions to take in a given
+     *  parsing state; return 0 if no combination is possible,
+     *  1 if user-mergeable, 2 if Y0 is preferred, 3 if Y1 is preferred.  */
+    static int
+    yypreference (const semantic_option& y0, const semantic_option& y1)
+    {
+      const rule_num r0 = y0.yyrule, r1 = y1.yyrule;
+      const int p0 = yydprec[r0], p1 = yydprec[r1];
+
+      if (p0 == p1)
+        {
+          if (yymerger[r0] == 0 || yymerger[r0] != yymerger[r1])
+            return 0;
+          else
+            return 1;
+        }
+      else if (p0 == 0 || p1 == 0)
+        return 0;
+      else if (p0 < p1)
+        return 3;
+      else if (p1 < p0)
+        return 2;
+      else
+        return 0;
+    }
+
+]b4_parse_param_vars[
+  }; // class ]b4_parser_class[::glr_stack
+} // namespace ]b4_namespace_ref[
+
+
+#if ]b4_api_PREFIX[DEBUG
+namespace
+{
+  void
+  yypstack (const glr_stack& yystack, size_t yyk)
+  {
+    yystack.yypstack (create_state_set_index (static_cast<std::ptrdiff_t> (yyk)));
+  }
+
+  void
+  yypdumpstack (const glr_stack& yystack)
+  {
+    yystack.yypdumpstack ();
+  }
+}
+#endif
+
+]b4_namespace_open[
+  /// Build a parser object.
+  ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
+    :])[
+#if ]b4_api_PREFIX[DEBUG
+    ]m4_ifset([b4_parse_param], [  ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
+#endif]b4_parse_param_cons[
+  {}
+
+  ]b4_parser_class::~b4_parser_class[ ()
+  {}
+
+  ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+  {}
+
+  int
+  ]b4_parser_class[::operator() ()
+  {
+    return parse ();
+  }
+
+  int
+  ]b4_parser_class[::parse ()
+  {
+    glr_stack yystack(YYINITDEPTH, *this]b4_user_args[);
+    return yystack.parse ();
+  }
+
+]b4_parse_error_bmatch([custom\|detailed],
+[[  const char *
+  ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+  {
+    static const char *const yy_sname[] =
+    {
+    ]b4_symbol_names[
+    };]b4_has_translations_if([[
+    /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+       internationalizable.  */
+    static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
+    {
+    ]b4_translatable[
+    };
+    return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
+            ? _(yy_sname[yysymbol])
+            : yy_sname[yysymbol]);]], [[
+    return yy_sname[yysymbol];]])[
+  }
+]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+  const char *
+  ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+  {
+    return yytname_[yysymbol];
+  }
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[  /* Return YYSTR after stripping away unnecessary quotes and
+     backslashes, so that it's suitable for yyerror.  The heuristic is
+     that double-quoting is unnecessary unless the string contains an
+     apostrophe, a comma, or backslash (other than backslash-backslash).
+     YYSTR is taken from yytname.  */
+  std::string
+  ]b4_parser_class[::yytnamerr_ (const char *yystr)
+  {
+    if (*yystr == '"')
+      {
+        std::string yyr;
+        char const *yyp = yystr;
+
+        for (;;)
+          switch (*++yyp)
+            {
+            case '\'':
+            case ',':
+              goto do_not_strip_quotes;
+
+            case '\\':
+              if (*++yyp != '\\')
+                goto do_not_strip_quotes;
+              else
+                goto append;
+
+            append:
+            default:
+              yyr += *yyp;
+              break;
+
+            case '"':
+              return yyr;
+            }
+      do_not_strip_quotes: ;
+      }
+
+    return yystr;
+  }
+
+  std::string
+  ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+  {
+    return yytnamerr_ (yytname_[yysymbol]);
+  }
+]])[
+
+]b4_parse_error_bmatch([simple\|verbose],
+[[#if ]b4_api_PREFIX[DEBUG]b4_tname_if([[ || 1]])[
+  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+  // First, the terminals, then, starting at \a YYNTOKENS, nonterminals.
+  const char*
+  const ]b4_parser_class[::yytname_[] =
+  {
+  ]b4_tname[
+  };
+#endif
+]])[
+
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+  // ]b4_parser_class[::context.
+  ]b4_parser_class[::context::context (glr_stack& yystack, const symbol_type& yyla)
+    : yystack_ (yystack)
+    , yyla_ (yyla)
+  {}
+
+  int
+  ]b4_parser_class[::context::expected_tokens (symbol_kind_type yyarg[], int yyargn) const
+  {
+    // Actual number of expected tokens
+    int yycount = 0;
+    const int yyn = yypact[yystack_.firstTopState()->yylrState];
+    if (!yystack_.yypact_value_is_default (yyn))
+      {
+        /* Start YYX at -YYN if negative to avoid negative indexes in
+           YYCHECK.  In other words, skip the first -YYN actions for this
+           state because they are default actions.  */
+        const int yyxbegin = yyn < 0 ? -yyn : 0;
+        /* Stay within bounds of both yycheck and yytname.  */
+        const int yychecklim = YYLAST - yyn + 1;
+        const int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+          if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+              && !yystack_.yytable_value_is_error (yytable[yyx + yyn]))
+            {
+              if (!yyarg)
+                ++yycount;
+              else if (yycount == yyargn)
+                return 0;
+              else
+                yyarg[yycount++] = YY_CAST (symbol_kind_type, yyx);
+            }
+      }
+    if (yyarg && yycount == 0 && 0 < yyargn)
+      yyarg[0] = ]b4_symbol(empty, kind)[;
+    return yycount;
+  }
+
+]])[
+
+]b4_parse_error_bmatch([detailed\|verbose], [[
+  int
+  ]b4_parser_class[::yy_syntax_error_arguments_ (const context& yyctx,
+                                                 symbol_kind_type yyarg[], int yyargn) const
+  {
+    /* There are many possibilities here to consider:
+       - If this state is a consistent state with a default action, then
+         the only way this function was invoked is if the default action
+         is an error action.  In that case, don't check for expected
+         tokens because there are none.
+       - The only way there can be no lookahead present (in yyla) is
+         if this state is a consistent state with a default action.
+         Thus, detecting the absence of a lookahead is sufficient to
+         determine that there is no unexpected or expected token to
+         report.  In that case, just report a simple "syntax error".
+       - Don't assume there isn't a lookahead just because this state is
+         a consistent state with a default action.  There might have
+         been a previous inconsistent state, consistent state with a
+         non-default action, or user semantic action that manipulated
+         yyla.  (However, yyla is currently not documented for users.)
+    */
+
+    if (!yyctx.lookahead ().empty ())
+      {
+        if (yyarg)
+          yyarg[0] = yyctx.token ();
+        int yyn = yyctx.expected_tokens (yyarg ? yyarg + 1 : yyarg, yyargn - 1);
+        return yyn + 1;
+      }
+    return 0;
+  }
+
+  // Generate an error message.
+  std::string
+  ]b4_parser_class[::yysyntax_error_ (const context& yyctx) const
+  {
+    // Its maximum.
+    enum { YYARGS_MAX = 5 };
+    // Arguments of yyformat.
+    symbol_kind_type yyarg[YYARGS_MAX];
+    int yycount = yy_syntax_error_arguments_ (yyctx, yyarg, YYARGS_MAX);
+
+    char const* yyformat = YY_NULLPTR;
+    switch (yycount)
+      {
+#define YYCASE_(N, S)                         \
+        case N:                               \
+          yyformat = S;                       \
+        break
+      default: // Avoid compiler warnings.
+        YYCASE_ (0, YY_("syntax error"));
+        YYCASE_ (1, YY_("syntax error, unexpected %s"));
+        YYCASE_ (2, YY_("syntax error, unexpected %s, expecting %s"));
+        YYCASE_ (3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+        YYCASE_ (4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+        YYCASE_ (5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+      }
+
+    std::string yyres;
+    // Argument number.
+    std::ptrdiff_t yyi = 0;
+    for (char const* yyp = yyformat; *yyp; ++yyp)
+      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+        {
+          yyres += symbol_name (yyarg[yyi++]);
+          ++yyp;
+        }
+      else
+        yyres += *yyp;
+    return yyres;
+  }]])[
+
+  void
+  ]b4_parser_class[::yy_destroy_ (const char* yymsg, symbol_kind_type yykind,
+                           value_type& yyval]b4_locations_if([[,
+                           location_type& yyloc]])[)
+  {
+    YY_USE (yyval);]b4_locations_if([[
+    YY_USE (yyloc);]])[
+    if (!yymsg)
+      yymsg = "Deleting";
+    ]b4_parser_class[& yyparser = *this;
+    YY_USE (yyparser);
+    YY_SYMBOL_PRINT (yymsg, yykind, yyval, yyloc);
+
+    YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+    ]m4_do([m4_pushdef([b4_symbol_action], m4_defn([b4_symbol_action_for_yyval]))],
+           [b4_symbol_actions([destructor])],
+           [m4_popdef([b4_symbol_action])])[
+    YY_IGNORE_MAYBE_UNINITIALIZED_END
+  }
+
+#if ]b4_api_PREFIX[DEBUG
+  /*--------------------.
+  | Print this symbol.  |
+  `--------------------*/
+
+  void
+  ]b4_parser_class[::yy_symbol_value_print_ (symbol_kind_type yykind,
+                           const value_type& yyval]b4_locations_if([[,
+                           const location_type& yyloc]])[) const
+  {]b4_locations_if([[
+    YY_USE (yyloc);]])[
+    YY_USE (yyval);
+    std::ostream& yyo = debug_stream ();
+    YY_USE (yyo);
+    ]m4_do([m4_pushdef([b4_symbol_action], m4_defn([b4_symbol_action_for_yyval]))],
+           [b4_symbol_actions([printer])],
+           [m4_popdef([b4_symbol_action])])[
+  }
+
+  void
+  ]b4_parser_class[::yy_symbol_print_ (symbol_kind_type yykind,
+                           const value_type& yyval]b4_locations_if([[,
+                           const location_type& yyloc]])[) const
+  {
+    *yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
+               << ' ' << symbol_name (yykind) << " ("]b4_locations_if([[
+               << yyloc << ": "]])[;
+    yy_symbol_value_print_ (yykind, yyval]b4_locations_if([[, yyloc]])[);
+    *yycdebug_ << ')';
+  }
+
+  std::ostream&
+  ]b4_parser_class[::debug_stream () const
+  {
+    return *yycdebug_;
+  }
+
+  void
+  ]b4_parser_class[::set_debug_stream (std::ostream& o)
+  {
+    yycdebug_ = &o;
+  }
+
+
+  ]b4_parser_class[::debug_level_type
+  ]b4_parser_class[::debug_level () const
+  {
+    return yydebug;
+  }
+
+  void
+  ]b4_parser_class[::set_debug_level (debug_level_type l)
+  {
+    // Actually, it is yydebug which is really used.
+    yydebug = l;
+  }
+#endif // ]b4_api_PREFIX[DEBUG
+
+]b4_token_ctor_if([], [b4_yytranslate_define([cc])])[
+
+]b4_token_ctor_if([], [[
+  /*---------.
+  | symbol.  |
+  `---------*/
+]b4_public_types_define([cc])])[
+]b4_namespace_close[]dnl
+b4_epilogue[]dnl
+b4_output_end
diff --git a/common/bison/skeletons/java-skel.m4 b/common/bison/skeletons/java-skel.m4
index 922f1a8..11cbc49 100644
--- a/common/bison/skeletons/java-skel.m4
+++ b/common/bison/skeletons/java-skel.m4
@@ -2,7 +2,7 @@
 
 # Java skeleton dispatching for Bison.
 
-# Copyright (C) 2007, 2009-2015, 2018-2019 Free Software Foundation,
+# Copyright (C) 2007, 2009-2015, 2018-2021 Free Software Foundation,
 # Inc.
 
 # This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 b4_glr_if(             [b4_complain([%%glr-parser not supported for Java])])
 b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for Java])])
diff --git a/common/bison/skeletons/java.m4 b/common/bison/skeletons/java.m4
index edf23a9..8b0828b 100644
--- a/common/bison/skeletons/java.m4
+++ b/common/bison/skeletons/java.m4
@@ -2,7 +2,7 @@
 
 # Java language support for Bison
 
-# Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_include(b4_skeletonsdir/[c-like.m4])
 
@@ -71,12 +71,12 @@
 # b4_identification
 # -----------------
 m4_define([b4_identification],
-[  /** Version number for the Bison executable that generated this parser.  */
-  public static final String bisonVersion = "b4_version";
+[[  /** Version number for the Bison executable that generated this parser.  */
+  public static final String bisonVersion = "]b4_version_string[";
 
   /** Name of the skeleton that generated this parser.  */
-  public static final String bisonSkeleton = b4_skeleton;
-])
+  public static final String bisonSkeleton = ]b4_skeleton[;
+]])
 
 
 ## ------------ ##
@@ -106,10 +106,13 @@
 
 # b4_typed_parser_table_define(TYPE, NAME, DATA, COMMENT)
 # -------------------------------------------------------
+# We use intermediate functions (e.g., yypact_init) to work around the
+# 64KB limit for JVM methods.  See
+# https://lists.gnu.org/r/help-bison/2008-11/msg00004.html.
 m4_define([b4_typed_parser_table_define],
 [m4_ifval([$4], [b4_comment([$4])
   ])dnl
-[private static final ]$1[ yy$2_[] = yy$2_init();
+[private static final ]$1[[] yy$2_ = yy$2_init();
   private static final ]$1[[] yy$2_init()
   {
     return new ]$1[[]
@@ -125,40 +128,158 @@
 [b4_typed_parser_table_define([b4_int_type_for([$2])], [$1], [$2], [$3])])
 
 
-## ------------------------- ##
-## Assigning token numbers.  ##
-## ------------------------- ##
+## ------------- ##
+## Token kinds.  ##
+## ------------- ##
+
 
 # b4_token_enum(TOKEN-NUM)
 # ------------------------
 # Output the definition of this token as an enum.
 m4_define([b4_token_enum],
-[b4_token_format([    /** Token number, to be returned by the scanner.  */
-    static final int %s = %s;
-], [$1])])
+[b4_token_visible_if([$1],
+    [m4_format([[    /** Token %s, to be returned by the scanner.  */
+    static final int %s = %s%s;
+]],
+               b4_symbol([$1], [tag]),
+               b4_symbol([$1], [id]),
+               b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])))])])
+
 
 # b4_token_enums
 # --------------
 # Output the definition of the tokens (if there are) as enums.
 m4_define([b4_token_enums],
-[b4_any_token_visible_if([/* Tokens.  */
+[b4_any_token_visible_if([    /* Token kinds.  */
 b4_symbol_foreach([b4_token_enum])])])
 
-# b4-case(ID, CODE)
-# -----------------
+
+
+## -------------- ##
+## Symbol kinds.  ##
+## -------------- ##
+
+
+# b4_symbol_kind(NUM)
+# -------------------
+m4_define([b4_symbol_kind],
+[SymbolKind.b4_symbol_kind_base($@)])
+
+
+# b4_symbol_enum(SYMBOL-NUM)
+# --------------------------
+# Output the definition of this symbol as an enum.
+m4_define([b4_symbol_enum],
+[m4_format([    %-30s %s],
+           m4_format([[%s(%s)%s]],
+                     b4_symbol([$1], [kind_base]),
+                     [$1],
+                     m4_if([$1], b4_last_symbol, [[;]], [[,]])),
+           [b4_symbol_tag_comment([$1])])])
+
+
+# b4_declare_symbol_enum
+# ----------------------
+# The definition of the symbol internal numbers as an enum.
+m4_define([b4_declare_symbol_enum],
+[[  public enum SymbolKind
+  {
+]b4_symbol_foreach([b4_symbol_enum])[
+
+    private final int yycode_;
+
+    SymbolKind (int n) {
+      this.yycode_ = n;
+    }
+
+    private static final SymbolKind[] values_ = {
+      ]m4_map_args_sep([b4_symbol_kind(], [)], [,
+      ], b4_symbol_numbers)[
+    };
+
+    static final SymbolKind get(int code) {
+      return values_[code];
+    }
+
+    public final int getCode() {
+      return this.yycode_;
+    }
+
+]b4_parse_error_bmatch(
+[simple\|verbose],
+[[    /* Return YYSTR after stripping away unnecessary quotes and
+       backslashes, so that it's suitable for yyerror.  The heuristic is
+       that double-quoting is unnecessary unless the string contains an
+       apostrophe, a comma, or backslash (other than backslash-backslash).
+       YYSTR is taken from yytname.  */
+    private static String yytnamerr_(String yystr)
+    {
+      if (yystr.charAt (0) == '"')
+        {
+          StringBuffer yyr = new StringBuffer();
+          strip_quotes: for (int i = 1; i < yystr.length(); i++)
+            switch (yystr.charAt(i))
+              {
+              case '\'':
+              case ',':
+                break strip_quotes;
+
+              case '\\':
+                if (yystr.charAt(++i) != '\\')
+                  break strip_quotes;
+                /* Fall through.  */
+              default:
+                yyr.append(yystr.charAt(i));
+                break;
+
+              case '"':
+                return yyr.toString();
+              }
+        }
+      return yystr;
+    }
+
+    /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+       First, the terminals, then, starting at \a YYNTOKENS_, nonterminals.  */
+    ]b4_typed_parser_table_define([String], [tname], [b4_tname])[
+
+    /* The user-facing name of this symbol.  */
+    public final String getName() {
+      return yytnamerr_(yytname_[yycode_]);
+    }
+]],
+[custom\|detailed],
+[[    /* YYNAMES_[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+       First, the terminals, then, starting at \a YYNTOKENS_, nonterminals.  */
+    ]b4_typed_parser_table_define([String], [names], [b4_symbol_names])[
+
+    /* The user-facing name of this symbol.  */
+    public final String getName() {
+      return yynames_[yycode_];
+    }]])[
+  };
+]])])
+
+
+
+# b4_case(ID, CODE, [COMMENTS])
+# -----------------------------
 # We need to fool Java's stupid unreachable code detection.
-m4_define([b4_case], [  case $1:
+m4_define([b4_case],
+[  case $1:m4_ifval([$3], [ b4_comment([$3])])
   if (yyn == $1)
     $2;
   break;
-    ])
+])
+
 
 # b4_predicate_case(LABEL, CONDITIONS)
 # ------------------------------------
-m4_define([b4_predicate_case], [  case $1:
+m4_define([b4_predicate_case],
+[  case $1:
      if (! ($2)) YYERROR;
     break;
-    ])
+])
 
 
 ## -------- ##
@@ -183,6 +304,7 @@
 
 m4_define([b4_yystype], [b4_percent_define_get([[api.value.type]])])
 b4_percent_define_default([[api.value.type]], [[Object]])
+b4_percent_define_default([[api.symbol.prefix]], [[S_]])
 
 # b4_api_prefix, b4_api_PREFIX
 # ----------------------------
@@ -222,6 +344,22 @@
 ## ----------------- ##
 
 
+# b4_symbol_translate(STRING)
+# ---------------------------
+# Used by "bison" in the array of symbol names to mark those that
+# require translation.
+m4_define([b4_symbol_translate],
+[[i18n($1)]])
+
+
+# b4_trans(STRING)
+# ----------------
+# Translate a string if i18n is enabled.  Avoid collision with b4_translate.
+m4_define([b4_trans],
+[b4_has_translations_if([i18n($1)], [$1])])
+
+
+
 # b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
 # ----------------------------------------------
 # See README.
@@ -361,4 +499,4 @@
 # -----------------------
 # Expand to either an empty string or "throws THROWS".
 m4_define([b4_maybe_throws],
-          [m4_ifval($1, [throws $1])])
+          [m4_ifval($1, [ throws $1])])
diff --git a/common/bison/skeletons/lalr1.cc b/common/bison/skeletons/lalr1.cc
index d245796..7cb69d3 100644
--- a/common/bison/skeletons/lalr1.cc
+++ b/common/bison/skeletons/lalr1.cc
@@ -1,6 +1,6 @@
 # C++ skeleton for Bison
 
-# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,22 +13,31 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_include(b4_skeletonsdir/[c++.m4])
 
 # api.value.type=variant is valid.
 m4_define([b4_value_type_setup_variant])
 
-# Check the value of %define parse.lac, where LAC stands for lookahead
-# correction.
+# parse.lac
 b4_percent_define_default([[parse.lac]], [[none]])
+b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
 b4_define_flag_if([lac])
 m4_define([b4_lac_flag],
           [m4_if(b4_percent_define_get([[parse.lac]]),
                  [none], [[0]], [[1]])])
 
 
+# b4_tname_if(TNAME-NEEDED, TNAME-NOT-NEEDED)
+# -------------------------------------------
+m4_define([b4_tname_if],
+[m4_case(b4_percent_define_get([[parse.error]]),
+         [verbose],         [$1],
+         [b4_token_table_if([$1],
+                            [$2])])])
+
+
 # b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
 # --------------------------------------------------------------
 # Declare "parser::yy<TABLE-NAME>_" whose contents is CONTENT.
@@ -49,6 +58,13 @@
   };dnl
 ])
 
+
+# b4_symbol_kind(NUM)
+# -------------------
+m4_define([b4_symbol_kind],
+[symbol_kind::b4_symbol_kind_base($@)])
+
+
 # b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
 # -------------------------------------------------
 # Same as b4_symbol_value, but used in a template method.  It makes
@@ -129,21 +145,21 @@
 ])])
 
 
-# b4_lex
-# ------
+# b4_yylex
+# --------
 # Call yylex.
-m4_define([b4_lex],
+m4_define([b4_yylex],
 [b4_token_ctor_if(
 [b4_function_call([yylex],
                   [symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))],
 [b4_function_call([yylex], [int],
-                  [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
-b4_locations_if([, [[location*], [&yyla.location]]])dnl
+                  [[value_type *], [&yyla.value]][]dnl
+b4_locations_if([, [[location_type *], [&yyla.location]]])dnl
 m4_ifdef([b4_lex_param], [, ]b4_lex_param))])])
 
 
 m4_pushdef([b4_copyright_years],
-           [2002-2015, 2018-2019])
+           [2002-2015, 2018-2021])
 
 m4_define([b4_parser_class],
           [b4_percent_define_get([[api.parser.class]])])
@@ -157,7 +173,7 @@
 
 # b4_shared_declarations(hh|cc)
 # -----------------------------
-# Declaration that might either go into the header (if --defines, $1 = hh)
+# Declaration that might either go into the header (if --header, $1 = hh)
 # or in the implementation file.
 m4_define([b4_shared_declarations],
 [b4_percent_code_get([[requires]])[
@@ -194,6 +210,13 @@
     ]b4_parser_class[ (]b4_parse_param_decl[);
     virtual ~]b4_parser_class[ ();
 
+#if 201103L <= YY_CPLUSPLUS
+    /// Non copyable.
+    ]b4_parser_class[ (const ]b4_parser_class[&) = delete;
+    /// Non copyable.
+    ]b4_parser_class[& operator= (const ]b4_parser_class[&) = delete;
+#endif
+
     /// Parse.  An alias for parse ().
     /// \returns  0 iff parsing succeeded.
     int operator() ();
@@ -224,19 +247,57 @@
     /// Report a syntax error.
     void error (const syntax_error& err);
 
+]b4_parse_error_bmatch(
+[custom\|detailed],
+[[    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static const char *symbol_name (symbol_kind_type yysymbol);]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static const char *symbol_name (symbol_kind_type yysymbol);
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[    /// The user-facing name of the symbol whose (internal) number is
+    /// YYSYMBOL.  No bounds checking.
+    static std::string symbol_name (symbol_kind_type yysymbol);]])[
+
 ]b4_token_constructor_define[
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+    class context
+    {
+    public:
+      context (const ]b4_parser_class[& yyparser, const symbol_type& yyla);
+      const symbol_type& lookahead () const YY_NOEXCEPT { return yyla_; }
+      symbol_kind_type token () const YY_NOEXCEPT { return yyla_.kind (); }]b4_locations_if([[
+      const location_type& location () const YY_NOEXCEPT { return yyla_.location; }
+]])[
+      /// Put in YYARG at most YYARGN of the expected tokens, and return the
+      /// number of tokens stored in YYARG.  If YYARG is null, return the
+      /// number of expected tokens (guaranteed to be less than YYNTOKENS).
+      int expected_tokens (symbol_kind_type yyarg[], int yyargn) const;
 
+    private:
+      const ]b4_parser_class[& yyparser_;
+      const symbol_type& yyla_;
+    };
+]])[
   private:
-    /// This class is not copyable.
+#if YY_CPLUSPLUS < 201103L
+    /// Non copyable.
     ]b4_parser_class[ (const ]b4_parser_class[&);
-    ]b4_parser_class[& operator= (const ]b4_parser_class[&);]b4_lac_if([[
-
+    /// Non copyable.
+    ]b4_parser_class[& operator= (const ]b4_parser_class[&);
+#endif
+]b4_lac_if([[
     /// Check the lookahead yytoken.
     /// \returns  true iff the token will be eventually shifted.
-    bool yy_lac_check_ (int yytoken) const;
+    bool yy_lac_check_ (symbol_kind_type yytoken) const;
     /// Establish the initial context if no initial context currently exists.
     /// \returns  true iff the token will be eventually shifted.
-    bool yy_lac_establish_ (int yytoken);
+    bool yy_lac_establish_ (symbol_kind_type yytoken);
     /// Discard any previous initial lookahead context because of event.
     /// \param event  the event which caused the lookahead to be discarded.
     ///               Only used for debbuging output.
@@ -244,13 +305,19 @@
 
     /// Stored state numbers (used for stacks).
     typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ state_type;
+]b4_parse_error_bmatch(
+[custom], [[
+    /// Report a syntax error
+    /// \param yyctx     the context in which the error occurred.
+    void report_syntax_error (const context& yyctx) const;]],
+[detailed\|verbose], [[
+    /// The arguments of the error message.
+    int yy_syntax_error_arguments_ (const context& yyctx,
+                                    symbol_kind_type yyarg[], int yyargn) const;
 
     /// Generate an error message.
-    /// \param yystate   the state where the error occurred.
-    /// \param yyla      the lookahead token.
-    virtual std::string yysyntax_error_ (state_type yystate,
-                                         const symbol_type& yyla) const;
-
+    /// \param yyctx     the context in which the error occurred.
+    virtual std::string yysyntax_error_ (const context& yyctx) const;]])[
     /// Compute post-reduction state.
     /// \param yystate   the current state
     /// \param yysym     the nonterminal to push on the stack
@@ -258,43 +325,52 @@
 
     /// Whether the given \c yypact_ value indicates a defaulted state.
     /// \param yyvalue   the value to check
-    static bool yy_pact_value_is_default_ (int yyvalue);
+    static bool yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT;
 
     /// Whether the given \c yytable_ value indicates a syntax error.
     /// \param yyvalue   the value to check
-    static bool yy_table_value_is_error_ (int yyvalue);
+    static bool yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT;
 
     static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
     static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
 
-    /// Convert a scanner token number \a t to a symbol number.
-    /// In theory \a t should be a token_type, but character literals
-    /// are valid, yet not members of the token_type enum.
-    static token_number_type yytranslate_ (int t);
+    /// Convert a scanner token kind \a t to a symbol kind.
+    /// In theory \a t should be a token_kind_type, but character literals
+    /// are valid, yet not members of the token_kind_type enum.
+    static symbol_kind_type yytranslate_ (int t) YY_NOEXCEPT;
 
-    // Tables.
-]b4_parser_tables_declare[]b4_error_verbose_if([
-
-    /// Convert the symbol name \a n to a form suitable for a diagnostic.
-    static std::string yytnamerr_ (const char *n);])[
-
-]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
+]b4_parse_error_bmatch(
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
     /// For a symbol, its name in clear.
     static const char* const yytname_[];
-]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *yystr);
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
+]])[
+
+    // Tables.
+]b4_parser_tables_declare[
+
+#if ]b4_api_PREFIX[DEBUG
 ]b4_integral_parser_table_declare([rline], [b4_rline],
      [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
     /// Report on the debug stream that the rule \a r is going to be reduced.
-    virtual void yy_reduce_print_ (int r);
+    virtual void yy_reduce_print_ (int r) const;
     /// Print the state stack on the debug stream.
-    virtual void yystack_print_ ();
+    virtual void yy_stack_print_ () const;
 
     /// Debugging level.
     int yydebug_;
     /// Debug stream.
     std::ostream* yycdebug_;
 
-    /// \brief Display a symbol type, value and location.
+    /// \brief Display a symbol kind, value and location.
     /// \param yyo    The output stream.
     /// \param yysym  The symbol.
     template <typename Base>
@@ -315,7 +391,7 @@
       /// Default constructor.
       by_state () YY_NOEXCEPT;
 
-      /// The symbol type as needed by the constructor.
+      /// The symbol kind as needed by the constructor.
       typedef state_type kind_type;
 
       /// Constructor.
@@ -327,12 +403,12 @@
       /// Record that this symbol is empty.
       void clear () YY_NOEXCEPT;
 
-      /// Steal the symbol type from \a that.
+      /// Steal the symbol kind from \a that.
       void move (by_state& that);
 
-      /// The (internal) type number (corresponding to \a state).
-      /// \a empty_symbol when empty.
-      symbol_number_type type_get () const YY_NOEXCEPT;
+      /// The symbol kind (corresponding to \a state).
+      /// \a ]b4_symbol(empty, kind)[ when empty.
+      symbol_kind_type kind () const YY_NOEXCEPT;
 
       /// The state number used to denote an empty symbol.
       /// We use the initial state, as it does not have a value.
@@ -398,64 +474,60 @@
     void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym);
 
     /// Pop \a n symbols from the stack.
-    void yypop_ (int n = 1);
-
-    /// Some specific tokens.
-    static const token_number_type yy_error_token_ = 1;
-    static const token_number_type yy_undef_token_ = ]b4_undef_token_number[;
+    void yypop_ (int n = 1) YY_NOEXCEPT;
 
     /// Constants.
     enum
     {
-      yyeof_ = 0,
       yylast_ = ]b4_last[,     ///< Last index in yytable_.
       yynnts_ = ]b4_nterms_number[,  ///< Number of nonterminal symbols.
-      yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
-      yyntokens_ = ]b4_tokens_number[  ///< Number of tokens.
+      yyfinal_ = ]b4_final_state_number[ ///< Termination state number.
     };
 
 ]b4_parse_param_vars[
+]b4_percent_code_get([[yy_bison_internal_hook]])[
   };
 
 ]b4_token_ctor_if([b4_yytranslate_define([$1])[
 ]b4_public_types_define([$1])])[
 ]b4_namespace_close[
 
-]b4_percent_define_flag_if([[global_tokens_and_yystype]],
-[b4_token_defines
-
-#ifndef ]b4_api_PREFIX[STYPE
- // Redirection for backward compatibility.
-# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class::semantic_type
-#endif
-])[
 ]b4_percent_code_get([[provides]])[
-]])
+]])[
+
 
 ## -------------- ##
 ## Output files.  ##
 ## -------------- ##
 
-b4_defines_if(
-[b4_output_begin([b4_spec_header_file])
-b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
-[
+# ------------- #
+# Header file.  #
+# ------------- #
+
+]b4_header_if([[
+]b4_output_begin([b4_spec_header_file])[
+]b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])[
+
 /**
- ** \file ]b4_spec_header_file[
+ ** \file ]b4_spec_mapped_header_file[
  ** Define the ]b4_namespace_ref[::parser class.
  */
 
 // C++ LALR(1) parser skeleton written by Akim Demaille.
 
 ]b4_disclaimer[
-]b4_cpp_guard_open([b4_spec_header_file])[
+]b4_cpp_guard_open([b4_spec_mapped_header_file])[
 ]b4_shared_declarations(hh)[
-]b4_cpp_guard_close([b4_spec_header_file])[
+]b4_cpp_guard_close([b4_spec_mapped_header_file])[
 ]b4_output_end[
-]])
+]])[
 
 
-b4_output_begin([b4_parser_file_name])[
+# --------------------- #
+# Implementation file.  #
+# --------------------- #
+
+]b4_output_begin([b4_parser_file_name])[
 ]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])[
 ]b4_disclaimer[
 ]b4_percent_code_get([[top]])[]dnl
@@ -466,7 +538,7 @@
 
 ]b4_user_pre_prologue[
 
-]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
+]b4_header_if([[#include "@basename(]b4_spec_header_file[@)"]],
                [b4_shared_declarations([cc])])[
 
 ]b4_user_post_prologue[
@@ -483,6 +555,11 @@
 #  define YY_(msgid) msgid
 # endif
 #endif
+]b4_has_translations_if([
+#ifndef N_
+# define N_(Msgid) Msgid
+#endif
+])[
 
 // Whether we are compiled with exception support.
 #ifndef YY_EXCEPTIONS
@@ -522,13 +599,13 @@
 # define YY_STACK_PRINT()               \
   do {                                  \
     if (yydebug_)                       \
-      yystack_print_ ();                \
+      yy_stack_print_ ();                \
   } while (false)
 
 #else // !]b4_api_PREFIX[DEBUG
 
 # define YYCDEBUG if (false) std::cerr
-# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE (Symbol)
+# define YY_SYMBOL_PRINT(Title, Symbol)  YY_USE (Symbol)
 # define YY_REDUCE_PRINT(Rule)           static_cast<void> (0)
 # define YY_STACK_PRINT()                static_cast<void> (0)
 
@@ -542,9 +619,623 @@
 #define YYERROR         goto yyerrorlab
 #define YYRECOVERING()  (!!yyerrstatus_)
 
-]b4_namespace_open[]b4_error_verbose_if([[
+]b4_namespace_open[
+  /// Build a parser object.
+  ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
+#if ]b4_api_PREFIX[DEBUG
+    : yydebug_ (false),
+      yycdebug_ (&std::cerr)]b4_lac_if([,], [m4_ifset([b4_parse_param], [,])])[
+#else
+]b4_lac_if([    :], [m4_ifset([b4_parse_param], [    :])])[
+#endif]b4_lac_if([[
+      yy_lac_established_ (false)]m4_ifset([b4_parse_param], [,])])[]b4_parse_param_cons[
+  {}
 
-  /* Return YYSTR after stripping away unnecessary quotes and
+  ]b4_parser_class::~b4_parser_class[ ()
+  {}
+
+  ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+  {}
+
+  /*---------.
+  | symbol.  |
+  `---------*/
+
+]b4_token_ctor_if([], [b4_public_types_define([cc])])[
+
+  // by_state.
+  ]b4_parser_class[::by_state::by_state () YY_NOEXCEPT
+    : state (empty_state)
+  {}
+
+  ]b4_parser_class[::by_state::by_state (const by_state& that) YY_NOEXCEPT
+    : state (that.state)
+  {}
+
+  void
+  ]b4_parser_class[::by_state::clear () YY_NOEXCEPT
+  {
+    state = empty_state;
+  }
+
+  void
+  ]b4_parser_class[::by_state::move (by_state& that)
+  {
+    state = that.state;
+    that.clear ();
+  }
+
+  ]b4_parser_class[::by_state::by_state (state_type s) YY_NOEXCEPT
+    : state (s)
+  {}
+
+  ]b4_parser_class[::symbol_kind_type
+  ]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
+  {
+    if (state == empty_state)
+      return ]b4_symbol(empty, kind)[;
+    else
+      return YY_CAST (symbol_kind_type, yystos_[+state]);
+  }
+
+  ]b4_parser_class[::stack_symbol_type::stack_symbol_type ()
+  {}
+
+  ]b4_parser_class[::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
+    : super_type (YY_MOVE (that.state)]b4_variant_if([], [, YY_MOVE (that.value)])b4_locations_if([, YY_MOVE (that.location)])[)
+  {]b4_variant_if([
+    b4_symbol_variant([that.kind ()],
+                      [value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[
+#if 201103L <= YY_CPLUSPLUS
+    // that is emptied.
+    that.state = empty_state;
+#endif
+  }
+
+  ]b4_parser_class[::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
+    : super_type (s]b4_variant_if([], [, YY_MOVE (that.value)])[]b4_locations_if([, YY_MOVE (that.location)])[)
+  {]b4_variant_if([
+    b4_symbol_variant([that.kind ()],
+                      [value], [move], [YY_MOVE (that.value)])])[
+    // that is emptied.
+    that.kind_ = ]b4_symbol(empty, kind)[;
+  }
+
+#if YY_CPLUSPLUS < 201103L
+  ]b4_parser_class[::stack_symbol_type&
+  ]b4_parser_class[::stack_symbol_type::operator= (const stack_symbol_type& that)
+  {
+    state = that.state;
+    ]b4_variant_if([b4_symbol_variant([that.kind ()],
+                                      [value], [copy], [that.value])],
+                   [[value = that.value;]])[]b4_locations_if([
+    location = that.location;])[
+    return *this;
+  }
+
+  ]b4_parser_class[::stack_symbol_type&
+  ]b4_parser_class[::stack_symbol_type::operator= (stack_symbol_type& that)
+  {
+    state = that.state;
+    ]b4_variant_if([b4_symbol_variant([that.kind ()],
+                                      [value], [move], [that.value])],
+                   [[value = that.value;]])[]b4_locations_if([
+    location = that.location;])[
+    // that is emptied.
+    that.state = empty_state;
+    return *this;
+  }
+#endif
+
+  template <typename Base>
+  void
+  ]b4_parser_class[::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+  {
+    if (yymsg)
+      YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
+
+    // User destructor.
+    b4_symbol_actions([destructor], [yysym.kind ()])])[
+  }
+
+#if ]b4_api_PREFIX[DEBUG
+  template <typename Base>
+  void
+  ]b4_parser_class[::yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const
+  {
+    std::ostream& yyoutput = yyo;
+    YY_USE (yyoutput);
+    if (yysym.empty ())
+      yyo << "empty symbol";
+    else
+      {
+        symbol_kind_type yykind = yysym.kind ();
+        yyo << (yykind < YYNTOKENS ? "token" : "nterm")
+            << ' ' << yysym.name () << " ("]b4_locations_if([
+            << yysym.location << ": "])[;
+        ]b4_symbol_actions([printer])[
+        yyo << ')';
+      }
+  }
+#endif
+
+  void
+  ]b4_parser_class[::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)
+  {
+    if (m)
+      YY_SYMBOL_PRINT (m, sym);
+    yystack_.push (YY_MOVE (sym));
+  }
+
+  void
+  ]b4_parser_class[::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
+  {
+#if 201103L <= YY_CPLUSPLUS
+    yypush_ (m, stack_symbol_type (s, std::move (sym)));
+#else
+    stack_symbol_type ss (s, sym);
+    yypush_ (m, ss);
+#endif
+  }
+
+  void
+  ]b4_parser_class[::yypop_ (int n) YY_NOEXCEPT
+  {
+    yystack_.pop (n);
+  }
+
+#if ]b4_api_PREFIX[DEBUG
+  std::ostream&
+  ]b4_parser_class[::debug_stream () const
+  {
+    return *yycdebug_;
+  }
+
+  void
+  ]b4_parser_class[::set_debug_stream (std::ostream& o)
+  {
+    yycdebug_ = &o;
+  }
+
+
+  ]b4_parser_class[::debug_level_type
+  ]b4_parser_class[::debug_level () const
+  {
+    return yydebug_;
+  }
+
+  void
+  ]b4_parser_class[::set_debug_level (debug_level_type l)
+  {
+    yydebug_ = l;
+  }
+#endif // ]b4_api_PREFIX[DEBUG
+
+  ]b4_parser_class[::state_type
+  ]b4_parser_class[::yy_lr_goto_state_ (state_type 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];
+  }
+
+  bool
+  ]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  bool
+  ]b4_parser_class[::yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
+  int
+  ]b4_parser_class[::operator() ()
+  {
+    return parse ();
+  }
+
+  int
+  ]b4_parser_class[::parse ()
+  {
+    int yyn;
+    /// Length of the RHS of the rule being reduced.
+    int yylen = 0;
+
+    // Error handling.
+    int yynerrs_ = 0;
+    int yyerrstatus_ = 0;
+
+    /// The lookahead symbol.
+    symbol_type yyla;]b4_locations_if([[
+
+    /// The locations where the error started and ended.
+    stack_symbol_type yyerror_range[3];]])[
+
+    /// The return value of parse ().
+    int yyresult;]b4_lac_if([[
+
+    // Discard the LAC context in case there still is one left from a
+    // previous invocation.
+    yy_lac_discard_ ("init");]])[
+
+#if YY_EXCEPTIONS
+    try
+#endif // YY_EXCEPTIONS
+      {
+    YYCDEBUG << "Starting parse\n";
+
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
+    b4_user_initial_action
+b4_dollar_popdef])[]dnl
+
+  [  /* Initialize the stack.  The initial state will be set in
+       yynewstate, since the latter expects the semantical and the
+       location values to have been already stored, initialize these
+       stacks with a primary value.  */
+    yystack_.clear ();
+    yypush_ (YY_NULLPTR, 0, YY_MOVE (yyla));
+
+  /*-----------------------------------------------.
+  | yynewstate -- push a new symbol on the stack.  |
+  `-----------------------------------------------*/
+  yynewstate:
+    YYCDEBUG << "Entering state " << int (yystack_[0].state) << '\n';
+    YY_STACK_PRINT ();
+
+    // Accept?
+    if (yystack_[0].state == yyfinal_)
+      YYACCEPT;
+
+    goto yybackup;
+
+
+  /*-----------.
+  | yybackup.  |
+  `-----------*/
+  yybackup:
+    // Try to take a decision without lookahead.
+    yyn = yypact_[+yystack_[0].state];
+    if (yy_pact_value_is_default_ (yyn))
+      goto yydefault;
+
+    // Read a lookahead token.
+    if (yyla.empty ())
+      {
+        YYCDEBUG << "Reading a token\n";
+#if YY_EXCEPTIONS
+        try
+#endif // YY_EXCEPTIONS
+          {]b4_token_ctor_if([[
+            symbol_type yylookahead (]b4_yylex[);
+            yyla.move (yylookahead);]], [[
+            yyla.kind_ = yytranslate_ (]b4_yylex[);]])[
+          }
+#if YY_EXCEPTIONS
+        catch (const syntax_error& yyexc)
+          {
+            YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
+            error (yyexc);
+            goto yyerrlab1;
+          }
+#endif // YY_EXCEPTIONS
+      }
+    YY_SYMBOL_PRINT ("Next token is", yyla);
+
+    if (yyla.kind () == ]b4_symbol(error, kind)[)
+    {
+      // The scanner already issued an error message, process directly
+      // to error recovery.  But do not keep the error token as
+      // lookahead, it is too special and may lead us to an endless
+      // loop in error recovery. */
+      yyla.kind_ = ]b4_symbol(undef, kind)[;
+      goto yyerrlab1;
+    }
+
+    /* If the proper action on seeing token YYLA.TYPE is to reduce or
+       to detect an error, take that action.  */
+    yyn += yyla.kind ();
+    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ())
+      {]b4_lac_if([[
+        if (!yy_lac_establish_ (yyla.kind ()))
+          goto yyerrlab;]])[
+        goto yydefault;
+      }
+
+    // Reduce or error.
+    yyn = yytable_[yyn];
+    if (yyn <= 0)
+      {
+        if (yy_table_value_is_error_ (yyn))
+          goto yyerrlab;]b4_lac_if([[
+        if (!yy_lac_establish_ (yyla.kind ()))
+          goto yyerrlab;
+]])[
+        yyn = -yyn;
+        goto yyreduce;
+      }
+
+    // Count tokens shifted since error; after three, turn off error status.
+    if (yyerrstatus_)
+      --yyerrstatus_;
+
+    // Shift the lookahead token.
+    yypush_ ("Shifting", state_type (yyn), YY_MOVE (yyla));]b4_lac_if([[
+    yy_lac_discard_ ("shift");]])[
+    goto yynewstate;
+
+
+  /*-----------------------------------------------------------.
+  | yydefault -- do the default action for the current state.  |
+  `-----------------------------------------------------------*/
+  yydefault:
+    yyn = yydefact_[+yystack_[0].state];
+    if (yyn == 0)
+      goto yyerrlab;
+    goto yyreduce;
+
+
+  /*-----------------------------.
+  | yyreduce -- do a reduction.  |
+  `-----------------------------*/
+  yyreduce:
+    yylen = yyr2_[yyn];
+    {
+      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([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [[
+      /* 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 = yystack_@{yylen - 1@}.value;
+      else
+        yylhs.value = yystack_@{0@}.value;]])[
+]b4_locations_if([dnl
+[
+      // Default location.
+      {
+        stack_type::slice range (yystack_, yylen);
+        YYLLOC_DEFAULT (yylhs.location, range, yylen);
+        yyerror_range[1].location = yylhs.location;
+      }]])[
+
+      // Perform the reduction.
+      YY_REDUCE_PRINT (yyn);
+#if YY_EXCEPTIONS
+      try
+#endif // YY_EXCEPTIONS
+        {
+          switch (yyn)
+            {
+]b4_user_actions[
+            default:
+              break;
+            }
+        }
+#if YY_EXCEPTIONS
+      catch (const syntax_error& yyexc)
+        {
+          YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
+          error (yyexc);
+          YYERROR;
+        }
+#endif // YY_EXCEPTIONS
+      YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+      yypop_ (yylen);
+      yylen = 0;
+
+      // Shift the result of the reduction.
+      yypush_ (YY_NULLPTR, YY_MOVE (yylhs));
+    }
+    goto yynewstate;
+
+
+  /*--------------------------------------.
+  | yyerrlab -- here on detecting error.  |
+  `--------------------------------------*/
+  yyerrlab:
+    // If not already recovering from an error, report this error.
+    if (!yyerrstatus_)
+      {
+        ++yynerrs_;]b4_parse_error_case(
+                  [simple], [[
+        std::string msg = YY_("syntax error");
+        error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]],
+                  [custom], [[
+        context yyctx (*this, yyla);
+        report_syntax_error (yyctx);]],
+                  [[
+        context yyctx (*this, yyla);
+        std::string msg = yysyntax_error_ (yyctx);
+        error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]])[
+      }
+
+]b4_locations_if([[
+    yyerror_range[1].location = yyla.location;]])[
+    if (yyerrstatus_ == 3)
+      {
+        /* If just tried and failed to reuse lookahead token after an
+           error, discard it.  */
+
+        // Return failure if at end of input.
+        if (yyla.kind () == ]b4_symbol(eof, kind)[)
+          YYABORT;
+        else if (!yyla.empty ())
+          {
+            yy_destroy_ ("Error: discarding", yyla);
+            yyla.clear ();
+          }
+      }
+
+    // Else will try to reuse lookahead token after shifting the error token.
+    goto yyerrlab1;
+
+
+  /*---------------------------------------------------.
+  | yyerrorlab -- error raised explicitly by YYERROR.  |
+  `---------------------------------------------------*/
+  yyerrorlab:
+    /* Pacify compilers when the user code never invokes YYERROR and
+       the label yyerrorlab therefore never appears in user code.  */
+    if (false)
+      YYERROR;
+
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYERROR.  */
+    yypop_ (yylen);
+    yylen = 0;
+    YY_STACK_PRINT ();
+    goto yyerrlab1;
+
+
+  /*-------------------------------------------------------------.
+  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
+  `-------------------------------------------------------------*/
+  yyerrlab1:
+    yyerrstatus_ = 3;   // Each real token shifted decrements this.
+    // Pop stack until we find a state that shifts the error token.
+    for (;;)
+      {
+        yyn = yypact_[+yystack_[0].state];
+        if (!yy_pact_value_is_default_ (yyn))
+          {
+            yyn += ]b4_symbol(error, kind)[;
+            if (0 <= yyn && yyn <= yylast_
+                && yycheck_[yyn] == ]b4_symbol(error, kind)[)
+              {
+                yyn = yytable_[yyn];
+                if (0 < yyn)
+                  break;
+              }
+          }
+
+        // Pop the current state because it cannot handle the error token.
+        if (yystack_.size () == 1)
+          YYABORT;
+]b4_locations_if([[
+        yyerror_range[1].location = yystack_[0].location;]])[
+        yy_destroy_ ("Error: popping", yystack_[0]);
+        yypop_ ();
+        YY_STACK_PRINT ();
+      }
+    {
+      stack_symbol_type error_token;
+]b4_locations_if([[
+      yyerror_range[2].location = yyla.location;
+      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);]])[
+
+      // Shift the error token.]b4_lac_if([[
+      yy_lac_discard_ ("error recovery");]])[
+      error_token.state = state_type (yyn);
+      yypush_ ("Shifting", YY_MOVE (error_token));
+    }
+    goto yynewstate;
+
+
+  /*-------------------------------------.
+  | yyacceptlab -- YYACCEPT comes here.  |
+  `-------------------------------------*/
+  yyacceptlab:
+    yyresult = 0;
+    goto yyreturn;
+
+
+  /*-----------------------------------.
+  | yyabortlab -- YYABORT comes here.  |
+  `-----------------------------------*/
+  yyabortlab:
+    yyresult = 1;
+    goto yyreturn;
+
+
+  /*-----------------------------------------------------.
+  | yyreturn -- parsing is finished, return the result.  |
+  `-----------------------------------------------------*/
+  yyreturn:
+    if (!yyla.empty ())
+      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+    /* Do not reclaim the symbols of the rule whose action triggered
+       this YYABORT or YYACCEPT.  */
+    yypop_ (yylen);
+    YY_STACK_PRINT ();
+    while (1 < yystack_.size ())
+      {
+        yy_destroy_ ("Cleanup: popping", yystack_[0]);
+        yypop_ ();
+      }
+
+    return yyresult;
+  }
+#if YY_EXCEPTIONS
+    catch (...)
+      {
+        YYCDEBUG << "Exception caught: cleaning lookahead and stack\n";
+        // Do not try to display the values of the reclaimed symbols,
+        // as their printers might throw an exception.
+        if (!yyla.empty ())
+          yy_destroy_ (YY_NULLPTR, yyla);
+
+        while (1 < yystack_.size ())
+          {
+            yy_destroy_ (YY_NULLPTR, yystack_[0]);
+            yypop_ ();
+          }
+        throw;
+      }
+#endif // YY_EXCEPTIONS
+  }
+
+  void
+  ]b4_parser_class[::error (const syntax_error& yyexc)
+  {
+    error (]b4_join(b4_locations_if([yyexc.location]),
+                    [[yyexc.what ()]])[);
+  }
+
+]b4_parse_error_bmatch([custom\|detailed],
+[[  const char *
+  ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+  {
+    static const char *const yy_sname[] =
+    {
+    ]b4_symbol_names[
+    };]b4_has_translations_if([[
+    /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+       internationalizable.  */
+    static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
+    {
+    ]b4_translatable[
+    };
+    return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
+            ? _(yy_sname[yysymbol])
+            : yy_sname[yysymbol]);]], [[
+    return yy_sname[yysymbol];]])[
+  }
+]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+  const char *
+  ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+  {
+    return yytname_[yysymbol];
+  }
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[  /* Return YYSTR after stripping away unnecessary quotes and
      backslashes, so that it's suitable for yyerror.  The heuristic is
      that double-quoting is unnecessary unless the string contains an
      apostrophe, a comma, or backslash (other than backslash-backslash).
@@ -583,582 +1274,89 @@
 
     return yystr;
   }
+
+  std::string
+  ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+  {
+    return yytnamerr_ (yytname_[yysymbol]);
+  }
 ]])[
 
-  /// Build a parser object.
-  ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
-#if ]b4_api_PREFIX[DEBUG
-    : yydebug_ (false),
-      yycdebug_ (&std::cerr)]b4_lac_if([,], [m4_ifset([b4_parse_param], [,])])[
-#else
-]b4_lac_if([    :], [m4_ifset([b4_parse_param], [    :])])[
-#endif]b4_lac_if([[
-      yy_lac_established_ (false)]m4_ifset([b4_parse_param], [,])])[]b4_parse_param_cons[
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+  // ]b4_parser_class[::context.
+  ]b4_parser_class[::context::context (const ]b4_parser_class[& yyparser, const symbol_type& yyla)
+    : yyparser_ (yyparser)
+    , yyla_ (yyla)
   {}
 
-  ]b4_parser_class::~b4_parser_class[ ()
-  {}
-
-  ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
-  {}
-
-  /*---------------.
-  | Symbol types.  |
-  `---------------*/
-
-]b4_token_ctor_if([], [b4_public_types_define([cc])])[
-
-  // by_state.
-  ]b4_parser_class[::by_state::by_state () YY_NOEXCEPT
-    : state (empty_state)
-  {}
-
-  ]b4_parser_class[::by_state::by_state (const by_state& that) YY_NOEXCEPT
-    : state (that.state)
-  {}
-
-  void
-  ]b4_parser_class[::by_state::clear () YY_NOEXCEPT
-  {
-    state = empty_state;
-  }
-
-  void
-  ]b4_parser_class[::by_state::move (by_state& that)
-  {
-    state = that.state;
-    that.clear ();
-  }
-
-  ]b4_parser_class[::by_state::by_state (state_type s) YY_NOEXCEPT
-    : state (s)
-  {}
-
-  ]b4_parser_class[::symbol_number_type
-  ]b4_parser_class[::by_state::type_get () const YY_NOEXCEPT
-  {
-    if (state == empty_state)
-      return empty_symbol;
-    else
-      return yystos_[state];
-  }
-
-  ]b4_parser_class[::stack_symbol_type::stack_symbol_type ()
-  {}
-
-  ]b4_parser_class[::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
-    : super_type (YY_MOVE (that.state)]b4_variant_if([], [, YY_MOVE (that.value)])b4_locations_if([, YY_MOVE (that.location)])[)
-  {]b4_variant_if([
-    b4_symbol_variant([that.type_get ()],
-                      [value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[
-#if 201103L <= YY_CPLUSPLUS
-    // that is emptied.
-    that.state = empty_state;
-#endif
-  }
-
-  ]b4_parser_class[::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
-    : super_type (s]b4_variant_if([], [, YY_MOVE (that.value)])[]b4_locations_if([, YY_MOVE (that.location)])[)
-  {]b4_variant_if([
-    b4_symbol_variant([that.type_get ()],
-                      [value], [move], [YY_MOVE (that.value)])])[
-    // that is emptied.
-    that.type = empty_symbol;
-  }
-
-#if YY_CPLUSPLUS < 201103L
-  ]b4_parser_class[::stack_symbol_type&
-  ]b4_parser_class[::stack_symbol_type::operator= (const stack_symbol_type& that)
-  {
-    state = that.state;
-    ]b4_variant_if([b4_symbol_variant([that.type_get ()],
-                                      [value], [copy], [that.value])],
-                   [[value = that.value;]])[]b4_locations_if([
-    location = that.location;])[
-    return *this;
-  }
-
-  ]b4_parser_class[::stack_symbol_type&
-  ]b4_parser_class[::stack_symbol_type::operator= (stack_symbol_type& that)
-  {
-    state = that.state;
-    ]b4_variant_if([b4_symbol_variant([that.type_get ()],
-                                      [value], [move], [that.value])],
-                   [[value = that.value;]])[]b4_locations_if([
-    location = that.location;])[
-    // that is emptied.
-    that.state = empty_state;
-    return *this;
-  }
-#endif
-
-  template <typename Base>
-  void
-  ]b4_parser_class[::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
-  {
-    if (yymsg)
-      YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
-
-    // User destructor.
-    b4_symbol_actions([destructor], [yysym.type_get ()])])[
-  }
-
-#if ]b4_api_PREFIX[DEBUG
-  template <typename Base>
-  void
-  ]b4_parser_class[::yy_print_ (std::ostream& yyo,
-                                     const basic_symbol<Base>& yysym) const
-  {
-    std::ostream& yyoutput = yyo;
-    YYUSE (yyoutput);
-    symbol_number_type yytype = yysym.type_get ();
-#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408
-    // Avoid a (spurious) G++ 4.8 warning about "array subscript is
-    // below array bounds".
-    if (yysym.empty ())
-      std::abort ();
-#endif
-    yyo << (yytype < yyntokens_ ? "token" : "nterm")
-        << ' ' << yytname_[yytype] << " ("]b4_locations_if([
-        << yysym.location << ": "])[;
-    ]b4_symbol_actions([printer])[
-    yyo << ')';
-  }
-#endif
-
-  void
-  ]b4_parser_class[::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)
-  {
-    if (m)
-      YY_SYMBOL_PRINT (m, sym);
-    yystack_.push (YY_MOVE (sym));
-  }
-
-  void
-  ]b4_parser_class[::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
-  {
-#if 201103L <= YY_CPLUSPLUS
-    yypush_ (m, stack_symbol_type (s, std::move (sym)));
-#else
-    stack_symbol_type ss (s, sym);
-    yypush_ (m, ss);
-#endif
-  }
-
-  void
-  ]b4_parser_class[::yypop_ (int n)
-  {
-    yystack_.pop (n);
-  }
-
-#if ]b4_api_PREFIX[DEBUG
-  std::ostream&
-  ]b4_parser_class[::debug_stream () const
-  {
-    return *yycdebug_;
-  }
-
-  void
-  ]b4_parser_class[::set_debug_stream (std::ostream& o)
-  {
-    yycdebug_ = &o;
-  }
-
-
-  ]b4_parser_class[::debug_level_type
-  ]b4_parser_class[::debug_level () const
-  {
-    return yydebug_;
-  }
-
-  void
-  ]b4_parser_class[::set_debug_level (debug_level_type l)
-  {
-    yydebug_ = l;
-  }
-#endif // ]b4_api_PREFIX[DEBUG
-
-  ]b4_parser_class[::state_type
-  ]b4_parser_class[::yy_lr_goto_state_ (state_type 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_];
-  }
-
-  bool
-  ]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue)
-  {
-    return yyvalue == yypact_ninf_;
-  }
-
-  bool
-  ]b4_parser_class[::yy_table_value_is_error_ (int yyvalue)
-  {
-    return yyvalue == yytable_ninf_;
-  }
-
   int
-  ]b4_parser_class[::operator() ()
+  ]b4_parser_class[::context::expected_tokens (symbol_kind_type yyarg[], int yyargn) const
   {
-    return parse ();
-  }
+    // Actual number of expected tokens
+    int yycount = 0;
+]b4_lac_if([[
+#if ]b4_api_PREFIX[DEBUG
+    // Execute LAC once. We don't care if it is successful, we
+    // only do it for the sake of debugging output.
+    if (!yyparser_.yy_lac_established_)
+      yyparser_.yy_lac_check_ (yyla_.kind ());
+#endif
 
-  int
-  ]b4_parser_class[::parse ()
-  {
-    int yyn;
-    /// Length of the RHS of the rule being reduced.
-    int yylen = 0;
-
-    // Error handling.
-    int yynerrs_ = 0;
-    int yyerrstatus_ = 0;
-
-    /// The lookahead symbol.
-    symbol_type yyla;]b4_locations_if([[
-
-    /// The locations where the error started and ended.
-    stack_symbol_type yyerror_range[3];]])[
-
-    /// The return value of parse ().
-    int yyresult;]b4_lac_if([[
-
-    /// Discard the LAC context in case there still is one left from a
-    /// previous invocation.
-    yy_lac_discard_ ("init");]])[
-
-#if YY_EXCEPTIONS
-    try
-#endif // YY_EXCEPTIONS
+    for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
       {
-    YYCDEBUG << "Starting parse\n";
-
-]m4_ifdef([b4_initial_action], [
-b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
-    b4_user_initial_action
-b4_dollar_popdef])[]dnl
-
-  [  /* Initialize the stack.  The initial state will be set in
-       yynewstate, since the latter expects the semantical and the
-       location values to have been already stored, initialize these
-       stacks with a primary value.  */
-    yystack_.clear ();
-    yypush_ (YY_NULLPTR, 0, YY_MOVE (yyla));
-
-  /*-----------------------------------------------.
-  | yynewstate -- push a new symbol on the stack.  |
-  `-----------------------------------------------*/
-  yynewstate:
-    YYCDEBUG << "Entering state " << int (yystack_[0].state) << '\n';
-
-    // Accept?
-    if (yystack_[0].state == yyfinal_)
-      YYACCEPT;
-
-    goto yybackup;
-
-
-  /*-----------.
-  | yybackup.  |
-  `-----------*/
-  yybackup:
-    // Try to take a decision without lookahead.
-    yyn = yypact_[yystack_[0].state];
-    if (yy_pact_value_is_default_ (yyn))
-      goto yydefault;
-
-    // Read a lookahead token.
-    if (yyla.empty ())
-      {
-        YYCDEBUG << "Reading a token: ";
-#if YY_EXCEPTIONS
-        try
-#endif // YY_EXCEPTIONS
-          {]b4_token_ctor_if([[
-            symbol_type yylookahead (]b4_lex[);
-            yyla.move (yylookahead);]], [[
-            yyla.type = yytranslate_ (]b4_lex[);]])[
-          }
-#if YY_EXCEPTIONS
-        catch (const syntax_error& yyexc)
+        symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
+        if (yysym != ]b4_symbol(error, kind)[
+            && yysym != ]b4_symbol(undef, kind)[
+            && yyparser_.yy_lac_check_ (yysym))
           {
-            YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
-            error (yyexc);
-            goto yyerrlab1;
+            if (!yyarg)
+              ++yycount;
+            else if (yycount == yyargn)
+              return 0;
+            else
+              yyarg[yycount++] = yysym;
           }
-#endif // YY_EXCEPTIONS
-      }
-    YY_SYMBOL_PRINT ("Next token is", yyla);
-
-    /* If the proper action on seeing token YYLA.TYPE is to reduce or
-       to detect an error, take that action.  */
-    yyn += yyla.type_get ();
-    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
-      {]b4_lac_if([[
-        if (!yy_lac_establish_ (yyla.type_get ()))
-           goto yyerrlab;]])[
-        goto yydefault;
-      }
-
-    // Reduce or error.
-    yyn = yytable_[yyn];
-    if (yyn <= 0)
+      }]], [[
+    const int yyn = yypact_[+yyparser_.yystack_[0].state];
+    if (!yy_pact_value_is_default_ (yyn))
       {
-        if (yy_table_value_is_error_ (yyn))
-          goto yyerrlab;]b4_lac_if([[
-        if (!yy_lac_establish_ (yyla.type_get ()))
-           goto yyerrlab;
+        /* Start YYX at -YYN if negative to avoid negative indexes in
+           YYCHECK.  In other words, skip the first -YYN actions for
+           this state because they are default actions.  */
+        const int yyxbegin = yyn < 0 ? -yyn : 0;
+        // Stay within bounds of both yycheck and yytname.
+        const int yychecklim = yylast_ - yyn + 1;
+        const int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+          if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+              && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+            {
+              if (!yyarg)
+                ++yycount;
+              else if (yycount == yyargn)
+                return 0;
+              else
+                yyarg[yycount++] = YY_CAST (symbol_kind_type, yyx);
+            }
+      }
 ]])[
-        yyn = -yyn;
-        goto yyreduce;
-      }
-
-    // Count tokens shifted since error; after three, turn off error status.
-    if (yyerrstatus_)
-      --yyerrstatus_;
-
-    // Shift the lookahead token.
-    yypush_ ("Shifting", static_cast<state_type> (yyn), YY_MOVE (yyla));]b4_lac_if([[
-    yy_lac_discard_ ("shift");]])[
-    goto yynewstate;
-
-
-  /*-----------------------------------------------------------.
-  | yydefault -- do the default action for the current state.  |
-  `-----------------------------------------------------------*/
-  yydefault:
-    yyn = yydefact_[yystack_[0].state];
-    if (yyn == 0)
-      goto yyerrlab;
-    goto yyreduce;
-
-
-  /*-----------------------------.
-  | yyreduce -- do a reduction.  |
-  `-----------------------------*/
-  yyreduce:
-    yylen = yyr2_[yyn];
-    {
-      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([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [
-      /* 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 = yystack_@{yylen - 1@}.value;
-      else
-        yylhs.value = yystack_@{0@}.value;])[
-]b4_locations_if([dnl
-[
-      // Default location.
-      {
-        stack_type::slice range (yystack_, yylen);
-        YYLLOC_DEFAULT (yylhs.location, range, yylen);
-        yyerror_range[1].location = yylhs.location;
-      }]])[
-
-      // Perform the reduction.
-      YY_REDUCE_PRINT (yyn);
-#if YY_EXCEPTIONS
-      try
-#endif // YY_EXCEPTIONS
-        {
-          switch (yyn)
-            {
-]b4_user_actions[
-            default:
-              break;
-            }
-        }
-#if YY_EXCEPTIONS
-      catch (const syntax_error& yyexc)
-        {
-          YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
-          error (yyexc);
-          YYERROR;
-        }
-#endif // YY_EXCEPTIONS
-      YY_SYMBOL_PRINT ("-> $$ =", yylhs);
-      yypop_ (yylen);
-      yylen = 0;
-      YY_STACK_PRINT ();
-
-      // Shift the result of the reduction.
-      yypush_ (YY_NULLPTR, YY_MOVE (yylhs));
-    }
-    goto yynewstate;
-
-
-  /*--------------------------------------.
-  | yyerrlab -- here on detecting error.  |
-  `--------------------------------------*/
-  yyerrlab:
-    // If not already recovering from an error, report this error.
-    if (!yyerrstatus_)
-      {
-        ++yynerrs_;
-        error (]b4_join(b4_locations_if([yyla.location]),
-                        [[yysyntax_error_ (yystack_[0].state, yyla)]])[);
-      }
-
-]b4_locations_if([[
-    yyerror_range[1].location = yyla.location;]])[
-    if (yyerrstatus_ == 3)
-      {
-        /* If just tried and failed to reuse lookahead token after an
-           error, discard it.  */
-
-        // Return failure if at end of input.
-        if (yyla.type_get () == yyeof_)
-          YYABORT;
-        else if (!yyla.empty ())
-          {
-            yy_destroy_ ("Error: discarding", yyla);
-            yyla.clear ();
-          }
-      }
-
-    // Else will try to reuse lookahead token after shifting the error token.
-    goto yyerrlab1;
-
-
-  /*---------------------------------------------------.
-  | yyerrorlab -- error raised explicitly by YYERROR.  |
-  `---------------------------------------------------*/
-  yyerrorlab:
-    /* Pacify compilers when the user code never invokes YYERROR and
-       the label yyerrorlab therefore never appears in user code.  */
-    if (false)
-      YYERROR;
-
-    /* Do not reclaim the symbols of the rule whose action triggered
-       this YYERROR.  */
-    yypop_ (yylen);
-    yylen = 0;
-    goto yyerrlab1;
-
-
-  /*-------------------------------------------------------------.
-  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
-  `-------------------------------------------------------------*/
-  yyerrlab1:
-    yyerrstatus_ = 3;   // Each real token shifted decrements this.
-    {
-      stack_symbol_type error_token;
-      for (;;)
-        {
-          yyn = yypact_[yystack_[0].state];
-          if (!yy_pact_value_is_default_ (yyn))
-            {
-              yyn += yy_error_token_;
-              if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yy_error_token_)
-                {
-                  yyn = yytable_[yyn];
-                  if (0 < yyn)
-                    break;
-                }
-            }
-
-          // Pop the current state because it cannot handle the error token.
-          if (yystack_.size () == 1)
-            YYABORT;
-]b4_locations_if([[
-          yyerror_range[1].location = yystack_[0].location;]])[
-          yy_destroy_ ("Error: popping", yystack_[0]);
-          yypop_ ();
-          YY_STACK_PRINT ();
-        }
-]b4_locations_if([[
-      yyerror_range[2].location = yyla.location;
-      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);]])[
-
-      // Shift the error token.]b4_lac_if([[
-      yy_lac_discard_ ("error recovery");]])[
-      error_token.state = static_cast<state_type> (yyn);
-      yypush_ ("Shifting", YY_MOVE (error_token));
-    }
-    goto yynewstate;
-
-
-  /*-------------------------------------.
-  | yyacceptlab -- YYACCEPT comes here.  |
-  `-------------------------------------*/
-  yyacceptlab:
-    yyresult = 0;
-    goto yyreturn;
-
-
-  /*-----------------------------------.
-  | yyabortlab -- YYABORT comes here.  |
-  `-----------------------------------*/
-  yyabortlab:
-    yyresult = 1;
-    goto yyreturn;
-
-
-  /*-----------------------------------------------------.
-  | yyreturn -- parsing is finished, return the result.  |
-  `-----------------------------------------------------*/
-  yyreturn:
-    if (!yyla.empty ())
-      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
-
-    /* Do not reclaim the symbols of the rule whose action triggered
-       this YYABORT or YYACCEPT.  */
-    yypop_ (yylen);
-    while (1 < yystack_.size ())
-      {
-        yy_destroy_ ("Cleanup: popping", yystack_[0]);
-        yypop_ ();
-      }
-
-    return yyresult;
-  }
-#if YY_EXCEPTIONS
-    catch (...)
-      {
-        YYCDEBUG << "Exception caught: cleaning lookahead and stack\n";
-        // Do not try to display the values of the reclaimed symbols,
-        // as their printers might throw an exception.
-        if (!yyla.empty ())
-          yy_destroy_ (YY_NULLPTR, yyla);
-
-        while (1 < yystack_.size ())
-          {
-            yy_destroy_ (YY_NULLPTR, yystack_[0]);
-            yypop_ ();
-          }
-        throw;
-      }
-#endif // YY_EXCEPTIONS
+    if (yyarg && yycount == 0 && 0 < yyargn)
+      yyarg[0] = ]b4_symbol(empty, kind)[;
+    return yycount;
   }
 
-  void
-  ]b4_parser_class[::error (const syntax_error& yyexc)
-  {
-    error (]b4_join(b4_locations_if([yyexc.location]),
-                    [[yyexc.what ()]])[);
-  }]b4_lac_if([[
+]])[
 
+]b4_lac_if([[
   bool
-  ]b4_parser_class[::yy_lac_check_ (int yytoken) const
+  ]b4_parser_class[::yy_lac_check_ (symbol_kind_type yytoken) const
   {
     // Logically, the yylac_stack's lifetime is confined to this function.
     // Clear it, to get rid of potential left-overs from previous call.
     yylac_stack_.clear ();
     // Reduce until we encounter a shift and thereby accept the token.
 #if ]b4_api_PREFIX[DEBUG
-    YYCDEBUG << "LAC: checking lookahead " << yytname_[yytoken] << ':';
+    YYCDEBUG << "LAC: checking lookahead " << symbol_name (yytoken) << ':';
 #endif
     std::ptrdiff_t lac_top = 0;
     while (true)
@@ -1166,13 +1364,13 @@
         state_type top_state = (yylac_stack_.empty ()
                                 ? yystack_[lac_top].state
                                 : yylac_stack_.back ());
-        int yyrule = yypact_[top_state];
+        int yyrule = yypact_[+top_state];
         if (yy_pact_value_is_default_ (yyrule)
             || (yyrule += yytoken) < 0 || yylast_ < yyrule
             || yycheck_[yyrule] != yytoken)
           {
             // Use the default action.
-            yyrule = yydefact_[top_state];
+            yyrule = yydefact_[+top_state];
             if (yyrule == 0)
               {
                 YYCDEBUG << " Err\n";
@@ -1222,14 +1420,14 @@
                      : yylac_stack_.back ());
         // Push the resulting state of the reduction.
         state_type state = yy_lr_goto_state_ (top_state, yyr1_[yyrule]);
-        YYCDEBUG << " G" << state;
+        YYCDEBUG << " G" << int (state);
         yylac_stack_.push_back (state);
       }
   }
 
   // Establish the initial context if no initial context currently exists.
   bool
-  ]b4_parser_class[::yy_lac_establish_ (int yytoken)
+  ]b4_parser_class[::yy_lac_establish_ (symbol_kind_type yytoken)
   {
     /* Establish the initial context for the current lookahead if no initial
        context is currently established.
@@ -1254,21 +1452,22 @@
        follows.  If no initial context is currently established for the
        current lookahead, then check if that lookahead can eventually be
        shifted if syntactic actions continue from the current context.  */
-    if (!yy_lac_established_)
+    if (yy_lac_established_)
+      return true;
+    else
       {
 #if ]b4_api_PREFIX[DEBUG
         YYCDEBUG << "LAC: initial context established for "
-                 << yytname_[yytoken] << '\n';
+                 << symbol_name (yytoken) << '\n';
 #endif
         yy_lac_established_ = true;
         return yy_lac_check_ (yytoken);
       }
-    return true;
   }
 
   // Discard any previous initial lookahead context.
   void
-  ]b4_parser_class[::yy_lac_discard_ (const char* evt)
+  ]b4_parser_class[::yy_lac_discard_ (const char* event)
   {
    /* Discard any previous initial lookahead context because of Event,
       which may be a lookahead change or an invalidation of the currently
@@ -1284,25 +1483,16 @@
     if (yy_lac_established_)
       {
         YYCDEBUG << "LAC: initial context discarded due to "
-                 << evt << '\n';
+                 << event << '\n';
         yy_lac_established_ = false;
       }
   }]])[
 
-  // Generate an error message.
-  std::string
-  ]b4_parser_class[::yysyntax_error_ (]dnl
-b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
-                    [state_type, const symbol_type&])[) const
-  {]b4_error_verbose_if([[
-    // Number of reported tokens (one for the "unexpected", one per
-    // "expected").
-    std::ptrdiff_t yycount = 0;
-    // Its maximum.
-    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-    // Arguments of yyformat.
-    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-
+]b4_parse_error_bmatch([detailed\|verbose], [[
+  int
+  ]b4_parser_class[::yy_syntax_error_arguments_ (const context& yyctx,
+                                                 symbol_kind_type yyarg[], int yyargn) const
+  {
     /* There are many possibilities here to consider:
        - If this state is a consistent state with a default action, then
          the only way this function was invoked is if the default action
@@ -1333,46 +1523,26 @@
          one exception: it will still contain any token that will not be
          accepted due to an error action in a later state.]])[
     */
-    if (!yyla.empty ())
+
+    if (!yyctx.lookahead ().empty ())
       {
-        symbol_number_type yytoken = yyla.type_get ();
-        yyarg[yycount++] = yytname_[yytoken];]b4_lac_if([[
-
-#if ]b4_api_PREFIX[DEBUG
-        // Execute LAC once. We don't care if it is succesful, we
-        // only do it for the sake of debugging output.
-        if (!yy_lac_established_)
-          yy_lac_check_ (yytoken);
-#endif]])[
-
-        int yyn = yypact_[yystate];
-        if (!yy_pact_value_is_default_ (yyn))
-          {]b4_lac_if([[
-            for (int yyx = 0; yyx < yyntokens_; ++yyx)
-              if (yyx != yy_error_token_ && yyx != yy_undef_token_
-                  && yy_lac_check_ (yyx))
-                {]], [[
-            /* Start YYX at -YYN if negative to avoid negative indexes in
-               YYCHECK.  In other words, skip the first -YYN actions for
-               this state because they are default actions.  */
-            int yyxbegin = yyn < 0 ? -yyn : 0;
-            // Stay within bounds of both yycheck and yytname.
-            int yychecklim = yylast_ - yyn + 1;
-            int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
-            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
-              if (yycheck_[yyx + yyn] == yyx && yyx != yy_error_token_
-                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
-                {]])[
-                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                    {
-                      yycount = 1;
-                      break;
-                    }
-                  else
-                    yyarg[yycount++] = yytname_[yyx];
-                }
-          }
+        if (yyarg)
+          yyarg[0] = yyctx.token ();
+        int yyn = yyctx.expected_tokens (yyarg ? yyarg + 1 : yyarg, yyargn - 1);
+        return yyn + 1;
       }
+    return 0;
+  }
+
+  // Generate an error message.
+  std::string
+  ]b4_parser_class[::yysyntax_error_ (const context& yyctx) const
+  {
+    // Its maximum.
+    enum { YYARGS_MAX = 5 };
+    // Arguments of yyformat.
+    symbol_kind_type yyarg[YYARGS_MAX];
+    int yycount = yy_syntax_error_arguments_ (yyctx, yyarg, YYARGS_MAX);
 
     char const* yyformat = YY_NULLPTR;
     switch (yycount)
@@ -1397,14 +1567,13 @@
     for (char const* yyp = yyformat; *yyp; ++yyp)
       if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
         {
-          yyres += yytnamerr_ (yyarg[yyi++]);
+          yyres += symbol_name (yyarg[yyi++]);
           ++yyp;
         }
       else
         yyres += *yyp;
-    return yyres;]], [[
-    return YY_("syntax error");]])[
-  }
+    return yyres;
+  }]])[
 
 
   const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class::yypact_ninf_ = b4_pact_ninf[;
@@ -1413,21 +1582,23 @@
 
 ]b4_parser_tables_define[
 
-]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
+]b4_parse_error_bmatch([simple\|verbose],
+[[#if ]b4_api_PREFIX[DEBUG]b4_tname_if([[ || 1]])[
   // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+  // First, the terminals, then, starting at \a YYNTOKENS, nonterminals.
   const char*
   const ]b4_parser_class[::yytname_[] =
   {
   ]b4_tname[
   };
+#endif
+]])[
 
-]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
+#if ]b4_api_PREFIX[DEBUG][
 ]b4_integral_parser_table_define([rline], [b4_rline])[
 
-  // Print the state stack on the debug stream.
   void
-  ]b4_parser_class[::yystack_print_ ()
+  ]b4_parser_class[::yy_stack_print_ () const
   {
     *yycdebug_ << "Stack now";
     for (stack_type::const_iterator
@@ -1438,9 +1609,8 @@
     *yycdebug_ << '\n';
   }
 
-  // Report on the debug stream that the rule \a yyrule is going to be reduced.
   void
-  ]b4_parser_class[::yy_reduce_print_ (int yyrule)
+  ]b4_parser_class[::yy_reduce_print_ (int yyrule) const
   {
     int yylno = yyrline_[yyrule];
     int yynrhs = yyr2_[yyrule];
diff --git a/common/bison/skeletons/lalr1.d b/common/bison/skeletons/lalr1.d
index 5aa2fb6..9730377 100644
--- a/common/bison/skeletons/lalr1.d
+++ b/common/bison/skeletons/lalr1.d
@@ -1,6 +1,6 @@
 # D skeleton for Bison -*- autoconf -*-
 
-# Copyright (C) 2007-2012, 2019 Free Software Foundation, Inc.
+# Copyright (C) 2007-2012, 2019-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,15 +13,56 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_include(b4_skeletonsdir/[d.m4])
 
+b4_header_if([b4_complain([%header/%defines does not make sense in D])])
 
+# parse.lac
+b4_percent_define_default([[parse.lac]], [[none]])
+b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
+b4_define_flag_if([lac])
+m4_define([b4_lac_flag],
+          [m4_if(b4_percent_define_get([[parse.lac]]),
+                 [none], [[0]], [[1]])])
+
+
+## --------------- ##
+## api.push-pull.  ##
+## --------------- ##
+
+b4_percent_define_default([[api.push-pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push-pull]],
+                                 [[pull]], [[push]], [[both]]]])
+
+# Define m4 conditional macros that encode the value
+# of the api.push-pull flag.
+b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
+b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
+m4_case(b4_percent_define_get([[api.push-pull]]),
+        [pull], [m4_define([b4_push_flag], [[0]])],
+        [push], [m4_define([b4_pull_flag], [[0]])])
+
+# Define a macro to be true when api.push-pull has the value "both".
+m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
+
+# Handle BISON_USE_PUSH_FOR_PULL for the test suite.  So that push parsing
+# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
+# behavior of Bison at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
+b4_use_push_for_pull_if([
+  b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+             [m4_define([b4_push_flag], [[1]])])])
+
+
+# Define a macro to encapsulate the parse state variables.  This
+# allows them to be defined either in parse() when doing pull parsing,
+# or as class instance variable when doing push parsing.
 b4_output_begin([b4_parser_file_name])
 b4_copyright([Skeleton implementation for Bison LALR(1) parsers in D],
-             [2007-2012, 2019])[
-
+             [2007-2012, 2019-2021])[
+]b4_disclaimer[
 ]b4_percent_define_ifdef([package], [module b4_percent_define_get([package]);
 ])[
 version(D_Version2) {
@@ -33,6 +74,29 @@
 ]b4_user_post_prologue[
 ]b4_percent_code_get([[imports]])[
 import std.format;
+import std.conv;
+
+/**
+ * Handle error message internationalisation.
+ */
+static if (!is(typeof(YY_))) {
+  version(YYENABLE_NLS)
+  {
+    version(ENABLE_NLS)
+    {
+      extern(C) char* dgettext(const char*, const char*);
+      string YY_(const char* s)
+      {
+        return to!string(dgettext("bison-runtime", s));
+      }
+    }
+  }
+  static if (!is(typeof(YY_)))
+  {
+    pragma(inline, true)
+    string YY_(string msg) { return msg; }
+  }
+}
 
 /**
  * A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>.
@@ -46,29 +110,13 @@
  * parser <tt>]b4_parser_class[</tt>.
  */
 public interface Lexer
-{]b4_locations_if([[
-  /**
-   * Method to retrieve the beginning position of the last scanned token.
-   * @@return the position at which the last scanned token starts.  */
-  @@property ]b4_position_type[ startPos ();
-
-  /**
-   * Method to retrieve the ending position of the last scanned token.
-   * @@return the first position beyond the last scanned token.  */
-  @@property ]b4_position_type[ endPos ();
-
-]])[
-  /**
-   * Method to retrieve the semantic value of the last scanned token.
-   * @@return the semantic value of the last scanned token.  */
-  @@property ]b4_yystype[ semanticVal ();
-
+{
   /**
    * Entry point for the scanner.  Returns the token identifier corresponding
    * to the next token and prepares to return the semantic value
    * ]b4_locations_if([and beginning/ending positions ])[of the token.
    * @@return the token identifier corresponding to the next token. */
-  int yylex ();
+  Symbol yylex ();
 
   /**
    * Entry point for error reporting.  Emits an error
@@ -77,16 +125,26 @@
    * @@param loc The location of the element to which the
    *                error message is related]])[
    * @@param s The string for the error message.  */
-   void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[string s);
+   void yyerror (]b4_locations_if([[const Location loc, ]])[string s);
+]b4_parse_error_bmatch([custom], [[
+  /**
+   * Build and emit a "syntax error" message in a user-defined way.
+   *
+   * @@param ctx  The context of the error.
+   */
+  void reportSyntaxError(]b4_parser_class[.Context ctx);
+]])[
 }
 
+]b4_public_types_declare[
+
 ]b4_locations_if([b4_position_type_if([[
 static assert(__traits(compiles,
-              (new ]b4_position_type[[1])[0]=(new ]b4_position_type[[1])[0]),
-              "struct/class ]b4_position_type[ must be default-constructible "
+              (new Position[1])[0]=(new Position[1])[0]),
+              "struct/class Position must be default-constructible "
               "and assignable");
-static assert(__traits(compiles, (new string[1])[0]=(new ]b4_position_type[).toString()),
-              "error: struct/class ]b4_position_type[ must have toString method");
+static assert(__traits(compiles, (new string[1])[0]=(new Position).toString()),
+              "error: struct/class Position must have toString method");
 ]], [[
   /**
    * A struct denoting a point in the input.*/
@@ -109,59 +167,65 @@
   }
 }
 ]])b4_location_type_if([[
-static assert(__traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0]))) &&
-              __traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0], (new ]b4_position_type[[1])[0]))),
-              "error: struct/class ]b4_location_type[ must have "
-              "default constructor and constructors this(]b4_position_type[) and this(]b4_position_type[, ]b4_position_type[).");
-static assert(__traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_location_type[[1])[0].begin) &&
-              __traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_location_type[[1])[0].end) &&
-              __traits(compiles, (new ]b4_location_type[[1])[0].end=(new ]b4_location_type[[1])[0].begin) &&
-              __traits(compiles, (new ]b4_location_type[[1])[0].end=(new ]b4_location_type[[1])[0].end),
-              "error: struct/class ]b4_location_type[ must have assignment-compatible "
+static assert(__traits(compiles, (new Location((new Position[1])[0]))) &&
+              __traits(compiles, (new Location((new Position[1])[0], (new Position[1])[0]))),
+              "error: struct/class Location must have "
+              "default constructor and constructors this(Position) and this(Position, Position).");
+static assert(__traits(compiles, (new Location[1])[0].begin=(new Location[1])[0].begin) &&
+              __traits(compiles, (new Location[1])[0].begin=(new Location[1])[0].end) &&
+              __traits(compiles, (new Location[1])[0].end=(new Location[1])[0].begin) &&
+              __traits(compiles, (new Location[1])[0].end=(new Location[1])[0].end),
+              "error: struct/class Location must have assignment-compatible "
               "members/properties 'begin' and 'end'.");
-static assert(__traits(compiles, (new string[1])[0]=(new ]b4_location_type[[1])[0].toString()),
-              "error: struct/class ]b4_location_type[ must have toString method.");
+static assert(__traits(compiles, (new string[1])[0]=(new Location[1])[0].toString()),
+              "error: struct/class Location must have toString method.");
 
-private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]], [[
+private immutable bool yy_location_is_class = !__traits(compiles, *(new Location((new Position[1])[0])));]], [[
 /**
- * A class defining a pair of positions.  Positions, defined by the
- * <code>]b4_position_type[</code> class, denote a point in the input.
+ * A struct defining a pair of positions.  Positions, defined by the
+ * <code>Position</code> struct, denote a point in the input.
  * Locations represent a part of the input through the beginning
  * and ending positions.  */
-public class ]b4_location_type[
+public struct ]b4_location_type[
 {
   /** The first, inclusive, position in the range.  */
-  public ]b4_position_type[ begin;
+  public Position begin;
 
   /** The first position beyond the range.  */
-  public ]b4_position_type[ end;
+  public Position end;
 
   /**
-   * Create a <code>]b4_location_type[</code> denoting an empty range located at
+   * Create a <code>Location</code> denoting an empty range located at
    * a given point.
    * @@param loc The position at which the range is anchored.  */
-  public this (]b4_position_type[ loc) {
+  public this(Position loc)
+  {
     this.begin = this.end = loc;
   }
 
-  public this () {
-  }
-
   /**
-   * Create a <code>]b4_location_type[</code> from the endpoints of the range.
+   * Create a <code>Location</code> from the endpoints of the range.
    * @@param begin The first position included in the range.
    * @@param end   The first position beyond the range.  */
-  public this (]b4_position_type[ begin, ]b4_position_type[ end)
+  public this(Position begin, Position end)
   {
     this.begin = begin;
     this.end = end;
   }
 
   /**
-   * A representation of the location. For this to be correct,
-   * <code>]b4_position_type[</code> should override the <code>toString</code>
-   * method.  */
-  public override string toString () const {
+   * Reset initial location to final location.
+   */
+  public void step()
+  {
+    this.begin = this.end;
+  }
+
+  /**
+   * A representation of the location.
+   */
+  public string toString() const
+  {
     auto end_col = 0 < end.column ? end.column - 1 : 0;
     auto res = begin.toString ();
     if (end.filename && begin.filename != end.filename)
@@ -174,32 +238,34 @@
   }
 }
 
-private immutable bool yy_location_is_class = true;
+private immutable bool yy_location_is_class = false;
 
-]])])m4_ifdef([b4_user_union_members], [private union YYSemanticType
+]])])[]b4_value_type_setup[]m4_ifdef([b4_user_union_members], [private union YYSemanticType
 {
 b4_user_union_members
 };],
 [m4_if(b4_tag_seen_flag, 0,
 [[private alias int YYSemanticType;]])])[
-]b4_token_enums(b4_tokens)[
+]b4_token_enums[
 ]b4_parser_class_declaration[
 {
   ]b4_identification[
 
+]b4_declare_symbol_enum[
+
 ]b4_locations_if([[
-  private final ]b4_location_type[ yylloc_from_stack (ref YYStack rhs, int n)
+  private final Location yylloc_from_stack (ref YYStack rhs, int n)
   {
     static if (yy_location_is_class) {
       if (n > 0)
-        return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
+        return new Location (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
       else
-        return new ]b4_location_type[ (rhs.locationAt (0).end);
+        return new Location (rhs.locationAt (0).end);
     } else {
       if (n > 0)
-        return ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
+        return Location (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
       else
-        return ]b4_location_type[ (rhs.locationAt (0).end);
+        return Location (rhs.locationAt (0).end);
     }
   }]])[
 
@@ -217,6 +283,9 @@
    * Instantiate the Bison-generated parser.
    */
   public this] (b4_parse_param_decl([b4_lex_param_decl])[) {
+]b4_percent_code_get([[init]])[]b4_lac_if([[
+    this.yylacStack = new int[];
+    this.yylacEstablished = false;]])[
     this (new YYLexer(]b4_lex_param_call[));
   }
 ]])[
@@ -231,6 +300,7 @@
 ]b4_parse_param_cons[
   }
 ]b4_parse_trace_if([[
+  import std.stdio;
   private File yyDebugStream;
 
   /**
@@ -262,18 +332,29 @@
 
   protected final void yycdebug (string s) {
     if (0 < yydebug)
+      yyDebugStream.write (s);
+  }
+
+  protected final void yycdebugln (string s) {
+    if (0 < yydebug)
       yyDebugStream.writeln (s);
   }
 ]])[
-  private final int yylex () {
+  private final ]b4_parser_class[.Symbol yylex () {
     return yylexer.yylex ();
   }
 
-  protected final void yyerror (]b4_locations_if(ref [b4_location_type[ loc, ]])[string s) {
+  protected final void yyerror (]b4_locations_if([[const Location loc, ]])[string s) {
     yylexer.yyerror (]b4_locations_if([loc, ])[s);
   }
 
   /**
+   * The number of syntax errors so far.
+   */
+  public int numberOfErrors() const { return yynerrs_; }
+  private int yynerrs_ = 0;
+
+  /**
    * Returned by a Bison action in order to stop the parsing process and
    * return success (<tt>true</tt>).  */
   public static immutable int YYACCEPT = 0;
@@ -282,6 +363,11 @@
    * Returned by a Bison action in order to stop the parsing process and
    * return failure (<tt>false</tt>).  */
   public static immutable int YYABORT = 1;
+]b4_push_if([
+  /**
+   * Returned by a Bison action in order to request a new token.
+   */
+  public static immutable int YYPUSH_MORE = 4;])[
 
   /**
    * Returned by a Bison action in order to start error recovery without
@@ -296,10 +382,43 @@
   private static immutable int YYREDUCE = 6;
   private static immutable int YYERRLAB1 = 7;
   private static immutable int YYRETURN = 8;
+]b4_push_if([[  private static immutable int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing.  */]])[
+
 ]b4_locations_if([
   private static immutable YYSemanticType yy_semantic_null;])[
   private int yyerrstatus_ = 0;
 
+  private void yyerrok()
+  {
+    yyerrstatus_ = 0;
+  }
+
+  // Lookahead symbol kind.
+  SymbolKind yytoken = ]b4_symbol(empty, kind)[;
+
+  /* State.  */
+  int yyn = 0;
+  int yylen = 0;
+  int yystate = 0;
+
+  YYStack yystack;
+
+  int label = YYNEWSTATE;
+
+  /* Error handling.  */
+]b4_locations_if([[
+  /// The location where the error started.
+  Location yyerrloc;
+
+  /// Location of the lookahead.
+  Location yylloc;
+
+  /// @@$.
+  Location yyloc;]])[
+
+  /// Semantic value of the lookahead.
+  Value yylval;
+
   /**
    * Whether error recovery is being done.  In this state, the parser
    * reads token until it reaches a known state, and then restarts normal
@@ -309,10 +428,22 @@
     return yyerrstatus_ == 0;
   }
 
+  /** Compute post-reduction state.
+   * @@param yystate   the current state
+   * @@param yysym     the nonterminal to push on the stack
+   */
+  private int yyLRGotoState(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, ref YYStack yystack, int yylen)
   {
-    ]b4_yystype[ yyval;]b4_locations_if([[
-    ]b4_location_type[ yyloc = yylloc_from_stack (yystack, yylen);]])[
+    Value yyval;]b4_locations_if([[
+    Location yyloc = yylloc_from_stack (yystack, yylen);]])[
 
     /* If YYLEN is nonzero, implement the default value of the action:
        `$$ = $1'.  Otherwise, use the top of the stack.
@@ -335,82 +466,47 @@
     }
 
 ]b4_parse_trace_if([[
-    yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);]])[
+    yy_symbol_print ("-> $$ =", to!SymbolKind (yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[
 
     yystack.pop (yylen);
     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 = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]);
     yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
     return YYNEWSTATE;
   }
 
-  /* Return YYSTR after stripping away unnecessary quotes and
-     backslashes, so that it's suitable for yyerror.  The heuristic is
-     that double-quoting is unnecessary unless the string contains an
-     apostrophe, a comma, or backslash (other than backslash-backslash).
-     YYSTR is taken from yytname.  */
-  private final string yytnamerr_ (string yystr)
-  {
-    if (yystr[0] == '"')
-      {
-        string yyr;
-      strip_quotes:
-        for (int i = 1; i < yystr.length; i++)
-          switch (yystr[i])
-            {
-            case '\'':
-            case ',':
-              break strip_quotes;
-
-            case '\\':
-              if (yystr[++i] != '\\')
-                break strip_quotes;
-              goto default;
-            default:
-              yyr ~= yystr[i];
-              break;
-
-            case '"':
-              return yyr;
-            }
-      }
-    else if (yystr == "$end")
-      return "end of input";
-
-    return yystr;
-  }
 ]b4_parse_trace_if([[
   /*--------------------------------.
   | Print this symbol on YYOUTPUT.  |
   `--------------------------------*/
 
-  private final void yy_symbol_print (string s, int yytype,
-    ref ]b4_yystype[ yyvaluep]dnl
-b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
+  private final void yy_symbol_print (string s, SymbolKind yykind,
+    ref Value yyval]b4_locations_if([, ref Location yyloc])[)
   {
     if (0 < yydebug)
     {
-      string message = s ~ (yytype < yyntokens_ ? " token " : " nterm ")
-              ~ yytname_[yytype] ~ " ("]b4_locations_if([
-              ~ yylocationp.toString() ~ ": "])[;
-      static if (__traits(compiles, message ~= yyvaluep.toString ()))
-              message ~= yyvaluep.toString ();
-      else
-              message ~= format ("%s", &yyvaluep);
-      message ~= ")";
-      yycdebug (message);
+      File yyo = yyDebugStream;
+      yyo.write(s);
+      yyo.write(yykind < yyntokens_ ? " token " : " nterm ");
+      yyo.write(format("%s", yykind));
+      yyo.write(" ("]b4_locations_if([ ~ yyloc.toString() ~ ": "])[);
+      ]b4_symbol_actions([printer])[
+      yyo.write(")\n");
     }
   }
 ]])[
+]b4_symbol_type_define[
+]b4_push_if([[
+  /**
+   * Push Parse input from external lexer
+   *
+   * @@param yyla current Symbol
+   *
+   * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
+   */
+  public int pushParse(Symbol yyla)]], [[
   /**
    * Parse input from the scanner that was specified at object construction
    * time.  Return whether the end of the input was reached successfully.
@@ -418,36 +514,23 @@
    * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
    *          imply that there were no syntax errors.
    */
-  public bool parse ()
-  {
-    /// Lookahead and lookahead in internal form.
-    int yychar = yyempty_;
-    int yytoken = 0;
+  public bool parse()]])[
+  {]b4_push_if([[
+    if (!this.pushParseInitialized)
+    {
+      pushParseInitialize();
+      yyerrstatus_ = 0;
+    }
+    else
+      label = YYGETTOKEN;
 
-    /* State.  */
-    int yyn = 0;
-    int yylen = 0;
-    int yystate = 0;
+    bool push_token_consumed = true;
+]], [[  bool yyresult;]b4_lac_if([[
+    // Discard the LAC context in case there still is one left from a
+    // previous invocation.
+    yylacDiscard("init");]])[]b4_parse_trace_if([[
 
-    YYStack yystack;
-
-    /* Error handling.  */
-    int yynerrs_ = 0;]b4_locations_if([[
-    /// The location where the error started.
-    ]b4_location_type[ yyerrloc = null;
-
-    /// ]b4_location_type[ of the lookahead.
-    ]b4_location_type[ yylloc;
-
-    /// @@$.
-    ]b4_location_type[ yyloc;]])[
-
-    /// Semantic value of the lookahead.
-    ]b4_yystype[ yylval;
-
-    int yyresult;]b4_parse_trace_if([[
-
-    yycdebug ("Starting parse\n");]])[
+    yycdebugln ("Starting parse");]])[
     yyerrstatus_ = 0;
 
 ]m4_ifdef([b4_initial_action], [
@@ -461,81 +544,107 @@
   [  /* Initialize the stack.  */
     yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
 
-    int label = YYNEWSTATE;
+    label = YYNEWSTATE;]])[
     for (;;)
       final switch (label)
       {
         /* New state.  Unlike in the C/C++ skeletons, the state is already
            pushed when we come here.  */
       case YYNEWSTATE:]b4_parse_trace_if([[
-        yycdebug (format("Entering state %d\n", yystate));
+        yycdebugln (format("Entering state %d", yystate));
         if (0 < yydebug)
           yystack.print (yyDebugStream);]])[
 
         /* Accept?  */
-        if (yystate == yyfinal_)
-          return true;
+        if (yystate == yyfinal_)]b4_push_if([[
+        {
+          label = YYACCEPT;
+          break;
+        }]], [[
+          return true;]])[
 
         /* Take a decision.  First try without lookahead.  */
         yyn = yypact_[yystate];
-        if (yy_pact_value_is_default_ (yyn))
+        if (yyPactValueIsDefault(yyn))
         {
           label = YYDEFAULT;
           break;
-        }
+        }]b4_push_if([[
+        goto case;
+
+        case YYGETTOKEN:]])[
 
         /* Read a lookahead token.  */
-        if (yychar == yyempty_)
-        {]b4_parse_trace_if([[
-          yycdebug ("Reading a token: ");]])[
-          yychar = yylex ();]b4_locations_if([[
-          static if (yy_location_is_class) {
-            yylloc = new ]b4_location_type[(yylexer.startPos, yylexer.endPos);
-          } else {
-            yylloc = ]b4_location_type[(yylexer.startPos, yylexer.endPos);
-          }]])
-          yylval = yylexer.semanticVal;[
+        if (yytoken == ]b4_symbol(empty, kind)[)
+        {]b4_push_if([[
+          if (!push_token_consumed)
+            return YYPUSH_MORE;]])[]b4_parse_trace_if([[
+          yycdebugln ("Reading a token");]])[]b4_push_if([[
+          yytoken = yyla.token;
+          yylval = yyla.value;]b4_locations_if([[
+          yylloc = yyla.location;]])[
+          push_token_consumed = false;]], [[
+          Symbol yysymbol = yylex();
+          yytoken = yysymbol.token();
+          yylval = yysymbol.value();]b4_locations_if([[
+          yylloc = yysymbol.location();]])[]])[
         }
 
-        /* Convert token to internal form.  */
-        yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
-        yy_symbol_print ("Next token is",
-                         yytoken, yylval]b4_locations_if([, yylloc])[);]])[
+        /* Token already converted to internal form.  */]b4_parse_trace_if([[
+        yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
 
-        /* If the proper action on seeing token YYTOKEN is to reduce or to
-           detect an error, take that action.  */
-        yyn += yytoken;
-        if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
-          label = YYDEFAULT;
-
-        /* <= 0 means reduce or error.  */
-        else if ((yyn = yytable_[yyn]) <= 0)
+        if (yytoken == ]b4_symbol(error, kind)[)
         {
-          if (yy_table_value_is_error_ (yyn))
-            label = YYERRLAB;
-          else
-          {
-            yyn = -yyn;
-            label = YYREDUCE;
-          }
+          // The scanner already issued an error message, process directly
+          // to error recovery.  But do not keep the error token as
+          // lookahead, it is too special and may lead us to an endless
+          // loop in error recovery. */
+          yytoken = ]b4_symbol(undef, kind)[;]b4_locations_if([[
+          yyerrloc = yylloc;]])[
+          label = YYERRLAB1;
         }
         else
         {
-          /* Shift the lookahead token.  */]b4_parse_trace_if([[
-          yy_symbol_print ("Shifting", yytoken,
-                            yylval]b4_locations_if([, yylloc])[);]])[
+          /* If the proper action on seeing token YYTOKEN is to reduce or to
+             detect an error, take that action.  */
+          yyn += yytoken;
+          if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) {]b4_lac_if([[
+            if (!yylacEstablish(yystack, yytoken))
+              label = YYERRLAB;
+            else]])[
+              label = YYDEFAULT;
+          }
+          /* <= 0 means reduce or error.  */
+          else if ((yyn = yytable_[yyn]) <= 0)
+          {
+            if (yyTableValueIsError(yyn))
+              label = YYERRLAB;]b4_lac_if([[
+            else if (!yylacEstablish(yystack, yytoken))
+              label = YYERRLAB;]])[
+            else
+            {
+              yyn = -yyn;
+              label = YYREDUCE;
+            }
+          }
+          else
+          {
+            /* Shift the lookahead token.  */]b4_parse_trace_if([[
+            yy_symbol_print ("Shifting", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
 
-          /* Discard the token being shifted.  */
-          yychar = yyempty_;
+            /* Discard the token being shifted.  */
+            yytoken = ]b4_symbol(empty, kind)[;
 
-          /* Count tokens shifted since error; after three, turn off error
-           * status.  */
-          if (yyerrstatus_ > 0)
-            --yyerrstatus_;
+            /* Count tokens shifted since error; after three, turn off error
+             * status.  */
+            if (yyerrstatus_ > 0)
+              --yyerrstatus_;
 
-          yystate = yyn;
-          yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
-          label = YYNEWSTATE;
+            yystate = yyn;
+            yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);]b4_lac_if([[
+            yylacDiscard("shift");]])[
+            label = YYNEWSTATE;
+          }
         }
         break;
 
@@ -559,33 +668,32 @@
         yystate = yystack.stateAt (0);
         break;
 
-      /*------------------------------------.
-      | yyerrlab -- here on detecting error |
-      `------------------------------------*/
+      /*--------------------------------------.
+      | yyerrlab -- here on detecting error.  |
+      `--------------------------------------*/
       case YYERRLAB:
         /* If not already recovering from an error, report this error.  */
         if (yyerrstatus_ == 0)
         {
           ++yynerrs_;
-          if (yychar == yyempty_)
-            yytoken = yyempty_;
-          yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
+          yyreportSyntaxError(new Context(]b4_lac_if([[this, ]])[yystack, yytoken]b4_locations_if([[, yylloc]])[));
         }
-
-]b4_locations_if([        yyerrloc = yylloc;])[
+]b4_locations_if([
+        yyerrloc = yylloc;])[
         if (yyerrstatus_ == 3)
         {
           /* If just tried and failed to reuse lookahead token after an
            * error, discard it.  */
 
-          if (yychar <= YYTokenType.EOF)
+          /* Return failure if at end of input.  */
+          if (yytoken == ]b4_symbol(eof, [kind])[)]b4_push_if([[
           {
-            /* Return failure if at end of input.  */
-            if (yychar == YYTokenType.EOF)
-             return false;
-          }
+            label = YYABORT;
+            break;
+          }]], [[
+          return false;]])[
           else
-            yychar = yyempty_;
+            yytoken = ]b4_symbol(empty, kind)[;
         }
 
         /* Else will try to reuse lookahead token after shifting the error
@@ -612,13 +720,14 @@
       case YYERRLAB1:
         yyerrstatus_ = 3;       /* Each real token shifted decrements this.  */
 
+        // Pop stack until we find a state that shifts the error token.
         for (;;)
         {
           yyn = yypact_[yystate];
-          if (!yy_pact_value_is_default_ (yyn))
+          if (!yyPactValueIsDefault(yyn))
           {
-            yyn += yy_error_token_;
-            if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yy_error_token_)
+            yyn += ]b4_symbol(error, kind)[;
+            if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(error, kind)[)
             {
               yyn = yytable_[yyn];
               if (0 < yyn)
@@ -627,16 +736,23 @@
           }
 
           /* Pop the current state because it cannot handle the error token.  */
-          if (yystack.height == 1)
-            return false;
+          if (yystack.height == 1)]b4_push_if([[
+          {
+            label = YYABORT;
+            break;
+          }]],[[
+            return false;]])[
 
 ]b4_locations_if([          yyerrloc = yystack.locationAt (0);])[
           yystack.pop ();
           yystate = yystack.stateAt (0);]b4_parse_trace_if([[
           if (0 < yydebug)
             yystack.print (yyDebugStream);]])[
-        }
-
+        }]b4_push_if([[
+        if (label == YYABORT)
+          /* Leave the switch.  */
+          break;
+]])[
 ]b4_locations_if([
         /* Muck with the stack to setup for yylloc.  */
         yystack.push (0, yy_semantic_null, yylloc);
@@ -644,34 +760,145 @@
         yyloc = yylloc_from_stack (yystack, 2);
         yystack.pop (2);])[
 
-        /* Shift the error token.  */]b4_parse_trace_if([[
-        yy_symbol_print ("Shifting", yystos_[yyn],
-        yylval]b4_locations_if([, yyloc])[);]])[
-
+        /* Shift the error token.  */]b4_lac_if([[
+        yylacDiscard("error recovery");]])[]b4_parse_trace_if([[
+        yy_symbol_print ("Shifting", to!SymbolKind (yystos_[yyn]), yylval]b4_locations_if([, yyloc])[);]])[
         yystate = yyn;
         yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
         label = YYNEWSTATE;
         break;
 
       /* Accept.  */
-      case YYACCEPT:
-        return true;
+      case YYACCEPT:]b4_push_if([[
+        this.pushParseInitialized = false;]b4_parse_trace_if([[
+        if (0 < yydebug)
+          yystack.print (yyDebugStream);]])[
+        return YYACCEPT;]], [[
+        yyresult = true;
+        label = YYRETURN;
+        break;]])[
 
       /* Abort.  */
-      case YYABORT:
-        return false;
+      case YYABORT:]b4_push_if([[
+        this.pushParseInitialized = false;]b4_parse_trace_if([[
+        if (0 < yydebug)
+          yystack.print (yyDebugStream);]])[
+        return YYABORT;]], [[
+        yyresult = false;
+        label = YYRETURN;
+        break;]])[
+]b4_push_if([[]], [[      ][case YYRETURN:]b4_parse_trace_if([[
+        if (0 < yydebug)
+          yystack.print (yyDebugStream);]])[
+        return yyresult;]])[
     }
+    assert(0);
   }
 
+]b4_push_if([[
+  bool pushParseInitialized = false;
+
+  /**
+   * (Re-)Initialize the state of the push parser.
+   */
+  public void pushParseInitialize()
+  {
+
+    /* Lookahead and lookahead in internal form.  */
+    this.yytoken = ]b4_symbol(empty, kind)[;
+
+    /* State.  */
+    this.yyn = 0;
+    this.yylen = 0;
+    this.yystate = 0;
+    destroy(this.yystack);
+    this.label = YYNEWSTATE;
+]b4_lac_if([[
+    destroy(this.yylacStack);
+    this.yylacEstablished = false;]])[
+
+    /* Error handling.  */
+    this.yynerrs_ = 0;
+]b4_locations_if([
+    /* The location where the error started.  */
+    this.yyerrloc = Location(Position(), Position());
+    this.yylloc = Location(Position(), Position());])[
+
+    /* Semantic value of the lookahead.  */
+    //destroy(this.yylval);
+
+    /* Initialize the stack.  */
+    yystack.push(this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
+
+    this.pushParseInitialized = true;
+  }]])[]b4_both_if([[
+  /**
+   * Parse input from the scanner that was specified at object construction
+   * time.  Return whether the end of the input was reached successfully.
+   * This version of parse() is defined only when api.push-push=both.
+   *
+   * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
+   *          imply that there were no syntax errors.
+   */
+  bool parse()
+  {
+    int status = 0;
+    do {
+      status = this.pushParse(yylex());
+    } while (status == YYPUSH_MORE);
+    return status == YYACCEPT;
+  }]])[
+
   // Generate an error message.
-  private final string yysyntax_error (int yystate, int tok)
-  {]b4_error_verbose_if([[
+  private final void yyreportSyntaxError(Context yyctx)
+  {]b4_parse_error_bmatch(
+[custom], [[
+    yylexer.reportSyntaxError(yyctx);]],
+[detailed], [[
+    if (yyctx.getToken() != ]b4_symbol(empty, kind)[)
+    {
+      // FIXME: This method of building the message is not compatible
+      // with internationalization.
+      immutable int argmax = 5;
+      SymbolKind[] yyarg = new SymbolKind[argmax];
+      int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax);
+      string res, yyformat;
+      switch (yycount)
+      {
+        case  1:
+          yyformat = YY_("syntax error, unexpected %s");
+          res = format(yyformat, yyarg[0]);
+         break;
+        case  2:
+          yyformat = YY_("syntax error, unexpected %s, expecting %s");
+          res = format(yyformat, yyarg[0], yyarg[1]);
+          break;
+        case  3:
+          yyformat = YY_("syntax error, unexpected %s, expecting %s or %s");
+          res = format(yyformat, yyarg[0], yyarg[1], yyarg[2]);
+          break;
+        case  4:
+          yyformat = YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+          res = format(yyformat, yyarg[0], yyarg[1], yyarg[2], yyarg[3]);
+          break;
+        case  5:
+          yyformat = YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+          res = format(yyformat, yyarg[0], yyarg[1], yyarg[2], yyarg[3], yyarg[4]);
+          break;
+        default:
+          res = YY_("syntax error");
+          break;
+      }
+      yyerror(]b4_locations_if([yyctx.getLocation(), ])[res);
+    }]],
+[[simple]], [[
+    yyerror(]b4_locations_if([yyctx.getLocation(), ])[YY_("syntax error"));]])[
+  }
+
+]b4_parse_error_bmatch(
+[detailed], [[
+  private int yysyntaxErrorArguments(Context yyctx, SymbolKind[] yyarg, int yyargn) {
     /* There are many possibilities here to consider:
-       - Assume YYFAIL is not used.  It's too flawed to consider.
-         See
-         <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-         for details.  YYERROR is fine as it does not invoke this
-         function.
        - If this state is a consistent state with a default action,
          then the only way this function was invoked is if the
          default action is an error action.  In that case, don't
@@ -696,15 +923,85 @@
          list is correct for canonical LR with one exception: it
          will still contain any token that will not be accepted due
          to an error action in a later state.
-      */
-    if (tok != yyempty_)
+    */
+    int yycount = 0;
+    if (yyctx.getToken() != ]b4_symbol(empty, kind)[)
+      {
+        if (yyarg !is null)
+          yyarg[yycount] = yyctx.getToken();
+        yycount += 1;
+        yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
+      }
+    return yycount;
+  }
+]])[
+
+
+  /**
+   * Information needed to get the list of expected tokens and to forge
+   * a syntax error diagnostic.
+   */
+  public static final class Context
+  {]b4_lac_if([[
+    private ]b4_parser_class[ yyparser;]])[
+    private const(YYStack) yystack;
+    private SymbolKind yytoken;]b4_locations_if([[
+    private const(Location) yylocation;]])[
+
+    this(]b4_lac_if([[]b4_parser_class[ parser, ]])[YYStack stack, SymbolKind kind]b4_locations_if([[, Location loc]])[)
+    {]b4_lac_if([[
+        yyparser = parser;]])[
+      yystack = stack;
+      yytoken = kind;]b4_locations_if([[
+      yylocation = loc;]])[
+    }
+
+    final SymbolKind getToken() const
     {
-      // FIXME: This method of building the message is not compatible
-      // with internationalization.
-      string res = "syntax error, unexpected ";
-      res ~= yytnamerr_ (yytname_[tok]);
-      int yyn = yypact_[yystate];
-      if (!yy_pact_value_is_default_ (yyn))
+      return yytoken;
+    }]b4_locations_if([[
+
+    final const(Location) getLocation() const
+    {
+      return yylocation;
+    }]])[
+    /**
+     * Put in YYARG at most YYARGN of the expected tokens given the
+     * current YYCTX, and return the number of tokens stored in YYARG.  If
+     * YYARG is null, return the number of expected tokens (guaranteed to
+     * be less than YYNTOKENS).
+     */
+    int getExpectedTokens(SymbolKind[] yyarg, int yyargn)]b4_lac_if([[]], [[ const]])[
+    {
+      return getExpectedTokens(yyarg, 0, yyargn);
+    }
+
+    int getExpectedTokens(SymbolKind[] yyarg, int yyoffset, int yyargn)]b4_lac_if([[]], [[ const]])[
+    {
+      int yycount = yyoffset;]b4_lac_if([b4_parse_trace_if([[
+      // Execute LAC once. We don't care if it is successful, we
+      // only do it for the sake of debugging output.
+
+      if (!yyparser.yylacEstablished)
+        yyparser.yylacCheck(yystack, yytoken);
+]])[
+      for (int yyx = 0; yyx < yyntokens_; ++yyx)
+        {
+          SymbolKind yysym = SymbolKind(yyx);
+          if (yysym != ]b4_symbol(error, kind)[
+              && yysym != ]b4_symbol(undef, kind)[
+              && yyparser.yylacCheck(yystack, yysym))
+            {
+              if (yyarg == null)
+                yycount += 1;
+              else if (yycount == yyargn)
+                return 0;
+              else
+                yyarg[yycount++] = yysym;
+            }
+        }]], [[
+      int yyn = yypact_[this.yystack.stateAt(0)];
+      if (!yyPactValueIsDefault(yyn))
       {
         /* Start YYX at -YYN if negative to avoid negative
            indexes in YYCHECK.  In other words, skip the first
@@ -714,33 +1011,181 @@
         /* Stay within bounds of both yycheck and yytname.  */
         int yychecklim = yylast_ - yyn + 1;
         int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
-        int count = 0;
-        for (int x = yyxbegin; x < yyxend; ++x)
-          if (yycheck_[x + yyn] == x && x != yy_error_token_
-              && !yy_table_value_is_error_ (yytable_[x + yyn]))
-             ++count;
-          if (count < 5)
+        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+          if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+              && !yyTableValueIsError(yytable_[yyx + yyn]))
           {
-             count = 0;
-             for (int x = yyxbegin; x < yyxend; ++x)
-               if (yycheck_[x + yyn] == x && x != yy_error_token_
-                   && !yy_table_value_is_error_ (yytable_[x + yyn]))
-               {
-                  res ~= count++ == 0 ? ", expecting " : " or ";
-                  res ~= yytnamerr_ (yytname_[x]);
-               }
+            if (yyarg is null)
+              ++yycount;
+            else if (yycount == yyargn)
+              return 0;
+            else
+              yyarg[yycount++] = SymbolKind(yyx);
           }
-      }
-      return res;
-    }]])[
-    return "syntax error";
+      }]])[
+      if (yyarg !is null && yycount == yyoffset && yyoffset < yyargn)
+        yyarg[yyoffset] = ]b4_symbol(empty, kind)[;
+      return yycount - yyoffset;
+    }
   }
 
+]b4_lac_if([[
+  /** Check the lookahead yytoken.
+   * \returns  true iff the token will be eventually shifted.
+   */
+  bool yylacCheck(const YYStack yystack, SymbolKind yytoken)
+  {
+    // Logically, the yylacStack's lifetime is confined to this function.
+    // Clear it, to get rid of potential left-overs from previous call.
+    destroy(yylacStack);
+    // Reduce until we encounter a shift and thereby accept the token.
+]b4_parse_trace_if([[
+    yycdebug("LAC: checking lookahead " ~ format("%s", yytoken) ~ ":");]])[
+    int lacTop = 0;
+    while (true)
+    {
+      int topState = (yylacStack.length == 0
+                      ? yystack.stateAt(lacTop)
+                      : yylacStack[$ - 1]);
+      int yyrule = yypact_[topState];
+      if (yyPactValueIsDefault(yyrule)
+          || (yyrule += yytoken) < 0 || yylast_ < yyrule
+          || yycheck_[yyrule] != yytoken)
+      {
+        // Use the default action.
+        yyrule = yydefact_[+topState];
+        if (yyrule == 0)
+        {]b4_parse_trace_if([[
+          yycdebugln(" Err");]])[
+          return false;
+        }
+      }
+      else
+      {
+        // Use the action from yytable.
+        yyrule = yytable_[yyrule];
+        if (yyTableValueIsError(yyrule))
+        {]b4_parse_trace_if([[
+          yycdebugln(" Err");]])[
+          return false;
+        }
+        if (0 < yyrule)
+        {]b4_parse_trace_if([[
+          yycdebugln(" S" ~ to!string(yyrule));]])[
+          return true;
+        }
+        yyrule = -yyrule;
+      }
+      // By now we know we have to simulate a reduce.
+]b4_parse_trace_if([[
+      yycdebug(" R" ~ to!string(yyrule - 1));]])[
+      // Pop the corresponding number of values from the stack.
+      {
+        int yylen = yyr2_[yyrule];
+        // First pop from the LAC stack as many tokens as possible.
+        int lacSize = cast (int) yylacStack.length;
+        if (yylen < lacSize)
+        {
+          yylacStack.length -= yylen;
+          yylen = 0;
+        }
+        else if (lacSize != 0)
+        {
+          destroy(yylacStack);
+          yylen -= lacSize;
+        }
+        // Only afterwards look at the main stack.
+        // We simulate popping elements by incrementing lacTop.
+        lacTop += yylen;
+      }
+      // Keep topState in sync with the updated stack.
+      topState = (yylacStack.length == 0
+                  ? yystack.stateAt(lacTop)
+                  : yylacStack[$ - 1]);
+      // Push the resulting state of the reduction.
+      int state = yyLRGotoState(topState, yyr1_[yyrule]);]b4_parse_trace_if([[
+      yycdebug(" G" ~ to!string(state));]])[
+      yylacStack.length++;
+      yylacStack[$ - 1] = state;
+    }
+  }
+
+  /** Establish the initial context if no initial context currently exists.
+   * \returns  true iff the token will be eventually shifted.
+   */
+  bool yylacEstablish(YYStack yystack, SymbolKind yytoken)
+  {
+  /* Establish the initial context for the current lookahead if no initial
+     context is currently established.
+
+     We define a context as a snapshot of the parser stacks.  We define
+     the initial context for a lookahead as the context in which the
+     parser initially examines that lookahead in order to select a
+     syntactic action.  Thus, if the lookahead eventually proves
+     syntactically unacceptable (possibly in a later context reached via a
+     series of reductions), the initial context can be used to determine
+     the exact set of tokens that would be syntactically acceptable in the
+     lookahead's place.  Moreover, it is the context after which any
+     further semantic actions would be erroneous because they would be
+     determined by a syntactically unacceptable token.
+
+     yylacEstablish should be invoked when a reduction is about to be
+     performed in an inconsistent state (which, for the purposes of LAC,
+     includes consistent states that don't know they're consistent because
+     their default reductions have been disabled).
+
+     For parse.lac=full, the implementation of yylacEstablish is as
+     follows.  If no initial context is currently established for the
+     current lookahead, then check if that lookahead can eventually be
+     shifted if syntactic actions continue from the current context.  */
+    if (yylacEstablished)
+      return true;
+    else
+    {]b4_parse_trace_if([[
+        yycdebugln("LAC: initial context established for " ~ format("%s", yytoken));]])[
+        yylacEstablished = true;
+        return yylacCheck(yystack, yytoken);
+    }
+  }
+
+  /** Discard any previous initial lookahead context because of event.
+   * \param event  the event which caused the lookahead to be discarded.
+   *               Only used for debbuging output.  */
+  void yylacDiscard(string event)
+  {
+  /* Discard any previous initial lookahead context because of Event,
+     which may be a lookahead change or an invalidation of the currently
+     established initial context for the current lookahead.
+
+     The most common example of a lookahead change is a shift.  An example
+     of both cases is syntax error recovery.  That is, a syntax error
+     occurs when the lookahead is syntactically erroneous for the
+     currently established initial context, so error recovery manipulates
+     the parser stacks to try to find a new initial context in which the
+     current lookahead is syntactically acceptable.  If it fails to find
+     such a context, it discards the lookahead.  */
+    if (yylacEstablished)
+    {]b4_parse_trace_if([[
+      yycdebugln("LAC: initial context discarded due to " ~ event);]])[
+      yylacEstablished = false;
+    }
+  }
+
+  /** The stack for LAC.
+   * Logically, the yylacStack's lifetime is confined to the function
+   * yylacCheck. We just store it as a member of this class to hold
+   * on to the memory and to avoid frequent reallocations.
+   */
+  int[] yylacStack;
+  /**  Whether an initial LAC context was established. */
+  bool yylacEstablished;
+]])[
+
   /**
    * Whether the given <code>yypact_</code> value indicates a defaulted state.
    * @@param yyvalue   the value to check
    */
-  private static bool yy_pact_value_is_default_ (int yyvalue)
+  private static bool yyPactValueIsDefault(int yyvalue)
   {
     return yyvalue == yypact_ninf_;
   }
@@ -749,7 +1194,7 @@
    * Whether the given <code>yytable_</code> value indicates a syntax error.
    * @@param yyvalue   the value to check
    */
-  private static bool yy_table_value_is_error_ (int yyvalue)
+  private static bool yyTableValueIsError(int yyvalue)
   {
     return yyvalue == yytable_ninf_;
   }
@@ -765,13 +1210,6 @@
 
   ]b4_parser_tables_define[
 
-  /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-     First, the terminals, then, starting at \a yyntokens_, nonterminals.  */
-  private static immutable string[] yytname_ =
-  @{
-  ]b4_tname[
-  @};
-
 ]b4_parse_trace_if([[
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
   private static immutable ]b4_int_type_for([b4_rline])[[] yyrline_ =
@@ -788,66 +1226,60 @@
     int yylno = yyrline_[yyrule];
     int yynrhs = yyr2_[yyrule];
     /* Print the symbols being reduced, and their result.  */
-    yycdebug (format("Reducing stack by rule %d (line %d), ",
-              yyrule - 1, yylno));
+    yycdebugln (format("Reducing stack by rule %d (line %d):",
+                yyrule - 1, yylno));
 
     /* The symbols being reduced.  */
     for (int yyi = 0; yyi < yynrhs; yyi++)
       yy_symbol_print (format("   $%d =", yyi + 1),
-                       yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
+                       to!SymbolKind (yystos_[yystack.stateAt(yynrhs - (yyi + 1))]),
                        ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
                        b4_rhs_location(yynrhs, yyi + 1)])[);
   }
 ]])[
 
-  private static token_number_type yytranslate_ (int t)
+  private static auto yytranslate_ (int t)
   {
 ]b4_api_token_raw_if(
-[[    import std.conv : to;
-    return to!byte (t);]],
+[[    return SymbolKind(t);]],
 [[    /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-    immutable token_number_type[] translate_table =
+    immutable ]b4_int_type_for([b4_translate])[[] translate_table =
     @{
   ]b4_translate[
     @};
 
-    immutable int user_token_number_max_ = ]b4_user_token_number_max[;
-    immutable token_number_type undef_token_ = ]b4_undef_token_number[;
+    // Last valid token kind.
+    immutable int code_max = ]b4_code_max[;
 
     if (t <= 0)
-      return YYTokenType.EOF;
-    else if (t <= user_token_number_max_)
-      return translate_table[t];
+      return ]b4_symbol(eof, kind)[;
+    else if (t <= code_max)
+      return SymbolKind(translate_table[t]);
     else
-      return undef_token_;]])[
+      return ]b4_symbol(undef, kind)[;]])[
   }
 
-  alias ]b4_int_type_for([b4_translate])[ token_number_type;
-
-  private static immutable token_number_type yy_error_token_ = 1;
-
   private static immutable int yylast_ = ]b4_last[;
   private static immutable int yynnts_ = ]b4_nterms_number[;
-  private static immutable int yyempty_ = -2;
   private static immutable int yyfinal_ = ]b4_final_state_number[;
   private static immutable int yyntokens_ = ]b4_tokens_number[;
 
   private final struct YYStackElement {
     int state;
-    ]b4_yystype[ value;]b4_locations_if(
+    Value value;]b4_locations_if(
     b4_location_type[[] location;])[
   }
 
   private final struct YYStack {
     private YYStackElement[] stack = [];
 
-    public final @@property ulong height()
+    public final ulong height()
     {
       return stack.length;
     }
 
-    public final void push (int state, ]b4_yystype[ value]dnl
-  b4_locations_if([, ref ]b4_location_type[ loc])[)
+    public final void push (int state, Value value]dnl
+  b4_locations_if([, ref Location loc])[)
     {
       stack ~= YYStackElement(state, value]b4_locations_if([, loc])[);
     }
@@ -862,18 +1294,18 @@
       stack.length -= num;
     }
 
-    public final int stateAt (int i)
+    public final int stateAt (int i) const
     {
       return stack[$-i-1].state;
     }
 
 ]b4_locations_if([[
-    public final ref ]b4_location_type[ locationAt (int i)
+    public final ref Location locationAt (int i)
     {
       return stack[$-i-1].location;
     }]])[
 
-    public final ref ]b4_yystype[ valueAt (int i)
+    public final ref Value valueAt (int i)
     {
       return stack[$-i-1].value;
     }
@@ -887,9 +1319,8 @@
       stream.writeln ();
     }]])[
   }
-
-  /* User implementation code.  */
 ]b4_percent_code_get[
 }
-]b4_epilogue[]dnl
+]b4_percent_code_get([[epilogue]])[]dnl
+b4_epilogue[]dnl
 b4_output_end
diff --git a/common/bison/skeletons/lalr1.java b/common/bison/skeletons/lalr1.java
index 9ec0806..1bbecca 100644
--- a/common/bison/skeletons/lalr1.java
+++ b/common/bison/skeletons/lalr1.java
@@ -1,6 +1,6 @@
-# Java skeleton for Bison                           -*- autoconf -*-
+# Java skeleton for Bison                           -*- java -*-
 
-# Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,11 +13,11 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_include(b4_skeletonsdir/[java.m4])
 
-b4_defines_if([b4_complain([%defines does not make sense in Java])])
+b4_header_if([b4_complain([%header/%defines does not make sense in Java])])
 
 m4_define([b4_symbol_no_destructor_assert],
 [b4_symbol_if([$1], [has_destructor],
@@ -25,7 +25,10 @@
                               [%destructor does not make sense in Java])])])
 b4_symbol_foreach([b4_symbol_no_destructor_assert])
 
-# Setup some macros for api.push-pull.
+## --------------- ##
+## api.push-pull.  ##
+## --------------- ##
+
 b4_percent_define_default([[api.push-pull]], [[pull]])
 b4_percent_define_check_values([[[[api.push-pull]],
                                  [[pull]], [[push]], [[both]]]])
@@ -49,13 +52,15 @@
   b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
              [m4_define([b4_push_flag], [[1]])])])
 
-# Define a macro to encapsulate the parse state variables.
-# This allows them to be defined either in parse() when doing
-# pull parsing, or as class instance variable when doing push parsing.
-m4_define([b4_define_state],[[
-    /* Lookahead and lookahead in internal form.  */
-    int yychar = yyempty_;
-    int yytoken = 0;
+# Define a macro to encapsulate the parse state variables.  This
+# allows them to be defined either in parse() when doing pull parsing,
+# or as class instance variable when doing push parsing.
+m4_define([b4_define_state],
+[[
+    /* Lookahead token kind.  */
+    int yychar = YYEMPTY_;
+    /* Lookahead symbol kind.  */
+    SymbolKind yytoken = null;
 
     /* State.  */
     int yyn = 0;
@@ -64,9 +69,8 @@
     YYStack yystack = new YYStack ();
     int label = YYNEWSTATE;
 
-    /* Error handling.  */
-    int yynerrs_ = 0;
-    ]b4_locations_if([[/* The location where the error started.  */
+]b4_locations_if([[
+    /* The location where the error started.  */
     ]b4_location_type[ yyerrloc = null;
 
     /* Location. */
@@ -74,15 +78,31 @@
 
     /* Semantic value of the lookahead.  */
     ]b4_yystype[ yylval = null;
-]])[
+]])
 
-]b4_output_begin([b4_parser_file_name])[
+# parse.lac
+b4_percent_define_default([[parse.lac]], [[none]])
+b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
+b4_define_flag_if([lac])
+m4_define([b4_lac_flag],
+          [m4_if(b4_percent_define_get([[parse.lac]]),
+                 [none], [[0]], [[1]])])
+
+
+## ------------- ##
+## Parser File.  ##
+## ------------- ##
+
+b4_output_begin([b4_parser_file_name])[
 ]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
-              [2007-2015, 2018-2019])[
-]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[
+              [2007-2015, 2018-2021])[
+]b4_disclaimer[
+]b4_percent_define_ifdef([api.package], [package b4_percent_define_get([api.package]);[
 ]])[
 ]b4_user_pre_prologue[
 ]b4_user_post_prologue[
+import java.text.MessageFormat;
+import java.util.ArrayList;
 ]b4_percent_code_get([[imports]])[
 /**
  * A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>.
@@ -91,8 +111,10 @@
  */
 ]b4_parser_class_declaration[
 {
-  ]b4_identification[
-]b4_error_verbose_if([[
+]b4_identification[
+][
+]b4_parse_error_bmatch(
+           [detailed\|verbose], [[
   /**
    * True if verbose error messages are enabled.
    */
@@ -109,16 +131,16 @@
    */
   public final void setErrorVerbose(boolean verbose)
   { yyErrorVerbose = verbose; }
-]])
+]])[
 
-b4_locations_if([[
+]b4_locations_if([[
   /**
    * A class defining a pair of positions.  Positions, defined by the
    * <code>]b4_position_type[</code> class, denote a point in the input.
    * Locations represent a part of the input through the beginning
    * and ending positions.
    */
-  public class ]b4_location_type[ {
+  public static class ]b4_location_type[ {
     /**
      * The first, inclusive, position in the range.
      */
@@ -153,52 +175,50 @@
      * <code>]b4_position_type[</code> should override the <code>equals</code>
      * method.
      */
-    public String toString () {
+    public String toString() {
       if (begin.equals (end))
-        return begin.toString ();
+        return begin.toString();
       else
-        return begin.toString () + "-" + end.toString ();
+        return begin.toString() + "-" + end.toString();
     }
   }
 
-]])[
-
-]b4_locations_if([[
-  private ]b4_location_type[ yylloc (YYStack rhs, int n)
+  private ]b4_location_type[ yylloc(YYStack rhs, int n)
   {
     if (0 < n)
-      return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
+      return new ]b4_location_type[(rhs.locationAt(n-1).begin, rhs.locationAt(0).end);
     else
-      return new ]b4_location_type[ (rhs.locationAt (0).end);
+      return new ]b4_location_type[(rhs.locationAt(0).end);
   }]])[
 
+]b4_declare_symbol_enum[
+
   /**
    * Communication interface between the scanner and the Bison-generated
    * parser <tt>]b4_parser_class[</tt>.
    */
   public interface Lexer {
-    /** Token returned by the scanner to signal the end of its input.  */
-    public static final int EOF = 0;
-
 ]b4_token_enums[
-
-    ]b4_locations_if([[/**
+    /** Deprecated, use ]b4_symbol(eof, id)[ instead.  */
+    public static final int EOF = ]b4_symbol(eof, id)[;
+]b4_pull_if([b4_locations_if([[
+    /**
      * Method to retrieve the beginning position of the last scanned token.
      * @@return the position at which the last scanned token starts.
      */
-    ]b4_position_type[ getStartPos ();
+    ]b4_position_type[ getStartPos();
 
     /**
      * Method to retrieve the ending position of the last scanned token.
      * @@return the first position beyond the last scanned token.
      */
-    ]b4_position_type[ getEndPos ();]])[
+    ]b4_position_type[ getEndPos();]])[
 
     /**
      * Method to retrieve the semantic value of the last scanned token.
      * @@return the semantic value of the last scanned token.
      */
-    ]b4_yystype[ getLVal ();
+    ]b4_yystype[ getLVal();
 
     /**
      * Entry point for the scanner.  Returns the token identifier corresponding
@@ -206,17 +226,26 @@
      * ]b4_locations_if([and beginning/ending positions ])[of the token.
      * @@return the token identifier corresponding to the next token.
      */
-    int yylex () ]b4_maybe_throws([b4_lex_throws])[;
-
+    int yylex()]b4_maybe_throws([b4_lex_throws])[;
+]])[
     /**
-     * Entry point for error reporting.  Emits an error
-     * ]b4_locations_if([referring to the given location ])[in a user-defined way.
+     * Emit an error]b4_locations_if([ referring to the given location])[in a user-defined way.
      *
-     * ]b4_locations_if([[@@param loc The location of the element to which the
-     *                error message is related]])[
+     *]b4_locations_if([[ @@param loc The location of the element to which the
+     *                error message is related.]])[
      * @@param msg The string for the error message.
      */
-     void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);
+     void yyerror(]b4_locations_if([b4_location_type[ loc, ]])[String msg);
+
+]b4_parse_error_bmatch(
+           [custom], [[
+    /**
+     * Build and emit a "syntax error" message in a user-defined way.
+     *
+     * @@param ctx  The context of the error.
+     */
+     void reportSyntaxError(Context ctx);
+]])[
   }
 
 ]b4_lexer_if([[
@@ -224,22 +253,25 @@
 ]b4_percent_code_get([[lexer]])[
   }
 
-  ]])[/**
+]])[
+  /**
    * The object doing lexical analysis for us.
    */
   private Lexer yylexer;
 
-  ]b4_parse_param_vars[
+]b4_parse_param_vars[
 
 ]b4_lexer_if([[
   /**
    * Instantiates the Bison-generated parser.
    */
-  public ]b4_parser_class (b4_parse_param_decl([b4_lex_param_decl])[) ]b4_maybe_throws([b4_init_throws])[
+  public ]b4_parser_class[(]b4_parse_param_decl([b4_lex_param_decl])[)]b4_maybe_throws([b4_init_throws])[
   {
-    ]b4_percent_code_get([[init]])[
+]b4_percent_code_get([[init]])[]b4_lac_if([[
+    this.yylacStack = new ArrayList<Integer>();
+    this.yylacEstablished = false;]])[
     this.yylexer = new YYLexer(]b4_lex_param_call[);
-    ]b4_parse_param_cons[
+]b4_parse_param_cons[
   }
 ]])[
 
@@ -247,11 +279,13 @@
    * Instantiates the Bison-generated parser.
    * @@param yylexer The scanner that will supply tokens to the parser.
    */
-  ]b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[) ]b4_maybe_throws([b4_init_throws])[
+  ]b4_lexer_if([[protected]], [[public]]) b4_parser_class[(]b4_parse_param_decl([[Lexer yylexer]])[)]b4_maybe_throws([b4_init_throws])[
   {
-    ]b4_percent_code_get([[init]])[
+]b4_percent_code_get([[init]])[]b4_lac_if([[
+    this.yylacStack = new ArrayList<Integer>();
+    this.yylacEstablished = false;]])[
     this.yylexer = yylexer;
-    ]b4_parse_param_cons[
+]b4_parse_param_cons[
   }
 
 ]b4_parse_trace_if([[
@@ -260,7 +294,7 @@
   /**
    * The <tt>PrintStream</tt> on which the debugging output is printed.
    */
-  public final java.io.PrintStream getDebugStream () { return yyDebugStream; }
+  public final java.io.PrintStream getDebugStream() { return yyDebugStream; }
 
   /**
    * Set the <tt>PrintStream</tt> on which the debug output is printed.
@@ -284,14 +318,20 @@
   public final void setDebugLevel(int level) { yydebug = level; }
 ]])[
 
+  private int yynerrs = 0;
+
+  /**
+   * The number of syntax errors so far.
+   */
+  public final int getNumberOfErrors() { return yynerrs; }
+
   /**
    * Print an error message via the lexer.
    *]b4_locations_if([[ Use a <code>null</code> location.]])[
    * @@param msg The error message.
    */
-  public final void yyerror (String msg)
-  {
-    yylexer.yyerror (]b4_locations_if([[(]b4_location_type[)null, ]])[msg);
+  public final void yyerror(String msg) {
+      yylexer.yyerror(]b4_locations_if([[(]b4_location_type[)null, ]])[msg);
   }
 ]b4_locations_if([[
   /**
@@ -299,9 +339,8 @@
    * @@param loc The location associated with the message.
    * @@param msg The error message.
    */
-  public final void yyerror (]b4_location_type[ loc, String msg)
-  {
-    yylexer.yyerror (loc, msg);
+  public final void yyerror(]b4_location_type[ loc, String msg) {
+      yylexer.yyerror(loc, msg);
   }
 
   /**
@@ -309,84 +348,85 @@
    * @@param pos The position associated with the message.
    * @@param msg The error message.
    */
-  public final void yyerror (]b4_position_type[ pos, String msg)
-  {
-    yylexer.yyerror (new ]b4_location_type[ (pos), msg);
+  public final void yyerror(]b4_position_type[ pos, String msg) {
+      yylexer.yyerror(new ]b4_location_type[ (pos), msg);
   }]])[
 ]b4_parse_trace_if([[
-  protected final void yycdebug (String s) {
+  protected final void yycdebugNnl(String s) {
     if (0 < yydebug)
-      yyDebugStream.println (s);
+      yyDebugStream.print(s);
+  }
+
+  protected final void yycdebug(String s) {
+    if (0 < yydebug)
+      yyDebugStream.println(s);
   }]])[
 
   private final class YYStack {
-    private int[] stateStack = new int[16];
-    ]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
+    private int[] stateStack = new int[16];]b4_locations_if([[
+    private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
     private ]b4_yystype[[] valueStack = new ]b4_yystype[[16];
 
     public int size = 16;
     public int height = -1;
 
-    public final void push (int state, ]b4_yystype[ value]dnl
-                            b4_locations_if([, ]b4_location_type[ loc])[) {
+    public final void push(int state, ]b4_yystype[ value]b4_locations_if([, ]b4_location_type[ loc])[) {
       height++;
-      if (size == height)
-        {
-          int[] newStateStack = new int[size * 2];
-          System.arraycopy (stateStack, 0, newStateStack, 0, height);
-          stateStack = newStateStack;
-          ]b4_locations_if([[
-          ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
-          System.arraycopy (locStack, 0, newLocStack, 0, height);
-          locStack = newLocStack;]])
+      if (size == height) {
+        int[] newStateStack = new int[size * 2];
+        System.arraycopy(stateStack, 0, newStateStack, 0, height);
+        stateStack = newStateStack;]b4_locations_if([[
+        ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
+        System.arraycopy(locStack, 0, newLocStack, 0, height);
+        locStack = newLocStack;]])
 
-          b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
-          System.arraycopy (valueStack, 0, newValueStack, 0, height);
-          valueStack = newValueStack;
+        b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
+        System.arraycopy(valueStack, 0, newValueStack, 0, height);
+        valueStack = newValueStack;
 
-          size *= 2;
-        }
+        size *= 2;
+      }
 
-      stateStack[height] = state;
-      ]b4_locations_if([[locStack[height] = loc;]])[
+      stateStack[height] = state;]b4_locations_if([[
+      locStack[height] = loc;]])[
       valueStack[height] = value;
     }
 
-    public final void pop () {
-      pop (1);
+    public final void pop() {
+      pop(1);
     }
 
-    public final void pop (int num) {
+    public final void pop(int num) {
       // Avoid memory leaks... garbage collection is a white lie!
       if (0 < num) {
-        java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
-        ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
+        java.util.Arrays.fill(valueStack, height - num + 1, height + 1, null);]b4_locations_if([[
+        java.util.Arrays.fill(locStack, height - num + 1, height + 1, null);]])[
       }
       height -= num;
     }
 
-    public final int stateAt (int i) {
+    public final int stateAt(int i) {
       return stateStack[height - i];
     }
+]b4_locations_if([[
 
-    ]b4_locations_if([[public final ]b4_location_type[ locationAt (int i) {
+    public final ]b4_location_type[ locationAt(int i) {
       return locStack[height - i];
     }
-
-    ]])[public final ]b4_yystype[ valueAt (int i) {
+]])[
+    public final ]b4_yystype[ valueAt(int i) {
       return valueStack[height - i];
     }
 
     // Print the state stack on the debug stream.
-    public void print (java.io.PrintStream out) {
+    public void print(java.io.PrintStream out) {
       out.print ("Stack now");
 
-      for (int i = 0; i <= height; i++)
-        {
-          out.print (' ');
-          out.print (stateStack[i]);
-        }
-      out.println ();
+      for (int i = 0; i <= height; i++) {
+        out.print(' ');
+        out.print(stateStack[i]);
+      }
+      out.println();
     }
   }
 
@@ -443,16 +483,15 @@
    * @@param yystate   the current state
    * @@param yysym     the nonterminal to push on the stack
    */
-  private int yyLRGotoState (int yystate, int yysym)
-  {
-    int yyr = yypgoto_[yysym - yyntokens_] + yystate;
-    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+  private int yyLRGotoState(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_];
+      return yydefgoto_[yysym - YYNTOKENS_];
   }
 
-  private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[
+  private int yyaction(int yyn, YYStack yystack, int yylen)]b4_maybe_throws([b4_throws])[
   {
     /* If YYLEN is nonzero, implement the default value of the action:
        '$$ = $1'.  Otherwise, use the top of the stack.
@@ -460,10 +499,10 @@
        Otherwise, the following line sets YYVAL to garbage.
        This behavior is undocumented and Bison
        users should not rely upon it.  */
-    ]b4_yystype[ yyval = (0 < yylen) ? yystack.valueAt (yylen - 1) : yystack.valueAt (0);
-    ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[]b4_parse_trace_if([[
+    ]b4_yystype[ yyval = (0 < yylen) ? yystack.valueAt(yylen - 1) : yystack.valueAt(0);]b4_locations_if([[
+    ]b4_location_type[ yyloc = yylloc(yystack, yylen);]])[]b4_parse_trace_if([[
 
-    yyReducePrint (yyn, yystack);]])[
+    yyReducePrint(yyn, yystack);]])[
 
     switch (yyn)
       {
@@ -471,66 +510,30 @@
         default: break;
       }]b4_parse_trace_if([[
 
-    yySymbolPrint ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);]])[
+    yySymbolPrint("-> $$ =", SymbolKind.get(yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[
 
-    yystack.pop (yylen);
+    yystack.pop(yylen);
     yylen = 0;
-
     /* Shift the result of the reduction.  */
-    int yystate = yyLRGotoState (yystack.stateAt (0), yyr1_[yyn]);
-    yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
+    int yystate = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]);
+    yystack.push(yystate, yyval]b4_locations_if([, yyloc])[);
     return YYNEWSTATE;
   }
 
-]b4_error_verbose_if([[
-  /* Return YYSTR after stripping away unnecessary quotes and
-     backslashes, so that it's suitable for yyerror.  The heuristic is
-     that double-quoting is unnecessary unless the string contains an
-     apostrophe, a comma, or backslash (other than backslash-backslash).
-     YYSTR is taken from yytname.  */
-  private final String yytnamerr_ (String yystr)
-  {
-    if (yystr.charAt (0) == '"')
-      {
-        StringBuffer yyr = new StringBuffer ();
-        strip_quotes: for (int i = 1; i < yystr.length (); i++)
-          switch (yystr.charAt (i))
-            {
-            case '\'':
-            case ',':
-              break strip_quotes;
-
-            case '\\':
-              if (yystr.charAt(++i) != '\\')
-                break strip_quotes;
-              /* Fall through.  */
-            default:
-              yyr.append (yystr.charAt (i));
-              break;
-
-            case '"':
-              return yyr.toString ();
-            }
-      }
-    else if (yystr.equals ("$end"))
-      return "end of input";
-
-    return yystr;
-  }
-]])[
 ]b4_parse_trace_if([[
   /*--------------------------------.
   | Print this symbol on YYOUTPUT.  |
   `--------------------------------*/
 
-  private void yySymbolPrint (String s, int yytype,
-                             ]b4_yystype[ yyvaluep]dnl
-                              b4_locations_if([, Object yylocationp])[)
-  {
-    yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ")
-              + yytname_[yytype] + " ("]b4_locations_if([
-              + yylocationp + ": "])[
-              + (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
+  private void yySymbolPrint(String s, SymbolKind yykind,
+                             ]b4_yystype[ yyvalue]b4_locations_if([, ]b4_location_type[ yylocation])[) {
+      if (0 < yydebug) {
+          yycdebug(s
+                   + (yykind.getCode() < YYNTOKENS_ ? " token " : " nterm ")
+                   + yykind.getName() + " ("]b4_locations_if([
+                   + yylocation + ": "])[
+                   + (yyvalue == null ? "(null)" : yyvalue.toString()) + ")");
+      }
   }]])[
 
 ]b4_push_if([],[[
@@ -541,29 +544,34 @@
    * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
    *          imply that there were no syntax errors.
    */
-  public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
+  public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
 ]b4_push_if([
   /**
    * Push Parse input from external lexer
    *
    * @@param yylextoken current token
-   * @@param yylexval current lval
-]b4_locations_if([   * @@param yylexloc current position])[
+   * @@param yylexval current lval]b4_locations_if([[
+   * @@param yylexloc current position]])[
    *
    * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
    */
-  public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))
-      b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
-  {
-    ]b4_locations_if([/* @@$.  */
-    b4_location_type yyloc;])[
+  public int push_parse(int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
+  {]b4_locations_if([[
+    /* @@$.  */
+    ]b4_location_type[ yyloc;]])[
 ]b4_push_if([],[[
-]b4_define_state[]b4_parse_trace_if([[
-    yycdebug ("Starting parse\n");]])[
+]b4_define_state[
+]b4_lac_if([[
+    // Discard the LAC context in case there still is one left from a
+    // previous invocation.
+    yylacDiscard("init");]])[
+]b4_parse_trace_if([[
+    yycdebug ("Starting parse");]])[
     yyerrstatus_ = 0;
+    yynerrs = 0;
 
     /* Initialize the stack.  */
-    yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
+    yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
 ]m4_ifdef([b4_initial_action], [
 b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
     b4_user_initial_action
@@ -579,7 +587,7 @@
     b4_user_initial_action
 b4_dollar_popdef[]dnl
 ])[]b4_parse_trace_if([[
-        yycdebug ("Starting parse\n");]])[
+        yycdebug ("Starting parse");]])[
         yyerrstatus_ = 0;
       } else
         label = YYGETTOKEN;
@@ -592,12 +600,12 @@
         /* New state.  Unlike in the C/C++ skeletons, the state is already
            pushed when we come here.  */
       case YYNEWSTATE:]b4_parse_trace_if([[
-        yycdebug ("Entering state " + yystate + "\n");
+        yycdebug ("Entering state " + yystate);
         if (0 < yydebug)
           yystack.print (yyDebugStream);]])[
 
         /* Accept?  */
-        if (yystate == yyfinal_)
+        if (yystate == YYFINAL_)
           ]b4_push_if([{label = YYACCEPT; break;}],
                       [return true;])[
 
@@ -612,64 +620,84 @@
 
       case YYGETTOKEN:])[
         /* Read a lookahead token.  */
-        if (yychar == yyempty_)
+        if (yychar == YYEMPTY_)
           {
 ]b4_push_if([[
             if (!push_token_consumed)
               return YYPUSH_MORE;]b4_parse_trace_if([[
-            yycdebug ("Reading a token: ");]])[
+            yycdebug ("Reading a token");]])[
             yychar = yylextoken;
             yylval = yylexval;]b4_locations_if([
             yylloc = yylexloc;])[
             push_token_consumed = false;]], [b4_parse_trace_if([[
-            yycdebug ("Reading a token: ");]])[
+            yycdebug ("Reading a token");]])[
             yychar = yylexer.yylex ();
-            yylval = yylexer.getLVal ();]b4_locations_if([
-            yylloc = new b4_location_type (yylexer.getStartPos (),
-                            yylexer.getEndPos ());])[
+            yylval = yylexer.getLVal();]b4_locations_if([[
+            yylloc = new ]b4_location_type[(yylexer.getStartPos(),
+                                          yylexer.getEndPos());]])[
 ]])[
           }
 
         /* Convert token to internal form.  */
         yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
-        yySymbolPrint ("Next token is", yytoken,
-                       yylval]b4_locations_if([, yylloc])[);]])[
+        yySymbolPrint("Next token is", yytoken,
+                      yylval]b4_locations_if([, yylloc])[);]])[
 
-        /* If the proper action on seeing token YYTOKEN is to reduce or to
-           detect an error, take that action.  */
-        yyn += yytoken;
-        if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
-          label = YYDEFAULT;
-
-        /* <= 0 means reduce or error.  */
-        else if ((yyn = yytable_[yyn]) <= 0)
+        if (yytoken == ]b4_symbol(error, kind)[)
           {
-            if (yyTableValueIsError (yyn))
-              label = YYERRLAB;
-            else
-              {
-                yyn = -yyn;
-                label = YYREDUCE;
-              }
+            // The scanner already issued an error message, process directly
+            // to error recovery.  But do not keep the error token as
+            // lookahead, it is too special and may lead us to an endless
+            // loop in error recovery. */
+            yychar = Lexer.]b4_symbol(undef, id)[;
+            yytoken = ]b4_symbol(undef, kind)[;]b4_locations_if([[
+            yyerrloc = yylloc;]])[
+            label = YYERRLAB1;
           }
-
         else
           {
-            /* Shift the lookahead token.  */]b4_parse_trace_if([[
-            yySymbolPrint ("Shifting", yytoken,
-                           yylval]b4_locations_if([, yylloc])[);
+            /* If the proper action on seeing token YYTOKEN is to reduce or to
+               detect an error, take that action.  */
+            yyn += yytoken.getCode();
+            if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode()) {]b4_lac_if([[
+              if (!yylacEstablish(yystack, yytoken)) {
+                label = YYERRLAB;
+              } else]])[
+              label = YYDEFAULT;
+            }
+
+            /* <= 0 means reduce or error.  */
+            else if ((yyn = yytable_[yyn]) <= 0)
+              {
+                if (yyTableValueIsError(yyn)) {
+                  label = YYERRLAB;
+                }]b4_lac_if([[ else if (!yylacEstablish(yystack, yytoken)) {
+                  label = YYERRLAB;
+                }]])[ else {
+                  yyn = -yyn;
+                  label = YYREDUCE;
+                }
+              }
+
+            else
+              {
+                /* Shift the lookahead token.  */]b4_parse_trace_if([[
+                yySymbolPrint("Shifting", yytoken,
+                              yylval]b4_locations_if([, yylloc])[);
 ]])[
-            /* Discard the token being shifted.  */
-            yychar = yyempty_;
+                /* Discard the token being shifted.  */
+                yychar = YYEMPTY_;
 
-            /* Count tokens shifted since error; after three, turn off error
-               status.  */
-            if (yyerrstatus_ > 0)
-              --yyerrstatus_;
+                /* Count tokens shifted since error; after three, turn off error
+                   status.  */
+                if (yyerrstatus_ > 0)
+                  --yyerrstatus_;
 
-            yystate = yyn;
-            yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
-            label = YYNEWSTATE;
+                yystate = yyn;
+                yystack.push(yystate, yylval]b4_locations_if([, yylloc])[);]b4_lac_if([[
+                yylacDiscard("shift");]])[
+                label = YYNEWSTATE;
+              }
           }
         break;
 
@@ -689,8 +717,8 @@
       `-----------------------------*/
       case YYREDUCE:
         yylen = yyr2_[yyn];
-        label = yyaction (yyn, yystack, yylen);
-        yystate = yystack.stateAt (0);
+        label = yyaction(yyn, yystack, yylen);
+        yystate = yystack.stateAt(0);
         break;
 
       /*------------------------------------.
@@ -700,26 +728,26 @@
         /* If not already recovering from an error, report this error.  */
         if (yyerrstatus_ == 0)
           {
-            ++yynerrs_;
-            if (yychar == yyempty_)
-              yytoken = yyempty_;
-            yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
+            ++yynerrs;
+            if (yychar == YYEMPTY_)
+              yytoken = null;
+            yyreportSyntaxError(new Context(this, yystack, yytoken]b4_locations_if([[, yylloc]])[));
           }
-
-        ]b4_locations_if([yyerrloc = yylloc;])[
+]b4_locations_if([[
+        yyerrloc = yylloc;]])[
         if (yyerrstatus_ == 3)
           {
             /* If just tried and failed to reuse lookahead token after an
                error, discard it.  */
 
-            if (yychar <= Lexer.EOF)
+            if (yychar <= Lexer.]b4_symbol(eof, id)[)
               {
                 /* Return failure if at end of input.  */
-                if (yychar == Lexer.EOF)
+                if (yychar == Lexer.]b4_symbol(eof, id)[)
                   ]b4_push_if([{label = YYABORT; break;}], [return false;])[
               }
             else
-              yychar = yyempty_;
+              yychar = YYEMPTY_;
           }
 
         /* Else will try to reuse lookahead token after shifting the error
@@ -730,13 +758,13 @@
       /*-------------------------------------------------.
       | errorlab -- error raised explicitly by YYERROR.  |
       `-------------------------------------------------*/
-      case YYERROR:
-        ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
+      case YYERROR:]b4_locations_if([[
+        yyerrloc = yystack.locationAt (yylen - 1);]])[
         /* Do not reclaim the symbols of the rule which action triggered
            this YYERROR.  */
         yystack.pop (yylen);
         yylen = 0;
-        yystate = yystack.stateAt (0);
+        yystate = yystack.stateAt(0);
         label = YYERRLAB1;
         break;
 
@@ -746,13 +774,15 @@
       case YYERRLAB1:
         yyerrstatus_ = 3;       /* Each real token shifted decrements this.  */
 
+        // Pop stack until we find a state that shifts the error token.
         for (;;)
           {
             yyn = yypact_[yystate];
             if (!yyPactValueIsDefault (yyn))
               {
-                yyn += yy_error_token_;
-                if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yy_error_token_)
+                yyn += ]b4_symbol(error, kind)[.getCode();
+                if (0 <= yyn && yyn <= YYLAST_
+                    && yycheck_[yyn] == ]b4_symbol(error, kind)[.getCode())
                   {
                     yyn = yytable_[yyn];
                     if (0 < yyn)
@@ -765,27 +795,29 @@
             if (yystack.height == 0)
               ]b4_push_if([{label = YYABORT; break;}],[return false;])[
 
-            ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
+]b4_locations_if([[
+            yyerrloc = yystack.locationAt (0);]])[
             yystack.pop ();
-            yystate = yystack.stateAt (0);]b4_parse_trace_if([[
+            yystate = yystack.stateAt(0);]b4_parse_trace_if([[
             if (0 < yydebug)
               yystack.print (yyDebugStream);]])[
           }
 
         if (label == YYABORT)
-            /* Leave the switch.  */
-            break;
+          /* Leave the switch.  */
+          break;
 
-]b4_locations_if([
+]b4_locations_if([[
         /* Muck with the stack to setup for yylloc.  */
         yystack.push (0, null, yylloc);
         yystack.push (0, null, yyerrloc);
         yyloc = yylloc (yystack, 2);
-        yystack.pop (2);])[
+        yystack.pop (2);]])[
 
-        /* Shift the error token.  */]b4_parse_trace_if([[
-        yySymbolPrint ("Shifting", yystos_[yyn],
-                       yylval]b4_locations_if([, yyloc])[);]])[
+        /* Shift the error token.  */]b4_lac_if([[
+        yylacDiscard("error recovery");]])[]b4_parse_trace_if([[
+        yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]),
+                      yylval]b4_locations_if([, yyloc])[);]])[
 
         yystate = yyn;
         yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
@@ -809,24 +841,26 @@
     /**
      * (Re-)Initialize the state of the push parser.
      */
-  public void push_parse_initialize()
+  public void push_parse_initialize ()
   {
     /* Lookahead and lookahead in internal form.  */
-    this.yychar = yyempty_;
-    this.yytoken = 0;
+    this.yychar = YYEMPTY_;
+    this.yytoken = null;
 
     /* State.  */
     this.yyn = 0;
     this.yylen = 0;
     this.yystate = 0;
-    this.yystack = new YYStack ();
+    this.yystack = new YYStack();]b4_lac_if([[
+    this.yylacStack = new ArrayList<Integer>();
+    this.yylacEstablished = false;]])[
     this.label = YYNEWSTATE;
 
     /* Error handling.  */
-    this.yynerrs_ = 0;
-    ]b4_locations_if([/* The location where the error started.  */
+    this.yynerrs = 0;]b4_locations_if([[
+    /* The location where the error started.  */
     this.yyerrloc = null;
-    this.yylloc = new b4_location_type (null, null);])[
+    this.yylloc = new ]b4_location_type[ (null, null);]])[
 
     /* Semantic value of the lookahead.  */
     this.yylval = null;
@@ -836,7 +870,7 @@
     this.push_parse_initialized = true;
 
   }
-]b4_locations_if([
+]b4_locations_if([[
   /**
    * Push parse given input from an external lexer.
    *
@@ -846,119 +880,354 @@
    *
    * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
    */
-  public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)
-      b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
-  {
-    return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
+  public int push_parse(int yylextoken, ]b4_yystype[ yylexval, ]b4_position_type[ yylexpos)]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ {
+      return push_parse(yylextoken, yylexval, new ]b4_location_type[(yylexpos));
   }
-])[]])[
+]])])[
 
 ]b4_both_if([[
   /**
    * Parse input from the scanner that was specified at object construction
    * time.  Return whether the end of the input was reached successfully.
-   * This version of parse () is defined only when api.push-push=both.
+   * This version of parse() is defined only when api.push-push=both.
    *
    * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
    *          imply that there were no syntax errors.
    */
-  public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
-  {
-    if (yylexer == null)
-      throw new NullPointerException("Null Lexer");
-    int status;
-    do {
-      int token = yylexer.yylex();
-      ]b4_yystype[ lval = yylexer.getLVal();
-]b4_locations_if([dnl
-      b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
-                                            yylexer.getEndPos ());])[
-      ]b4_locations_if([status = push_parse(token,lval,yyloc);],[
-      status = push_parse(token,lval);])[
-    } while (status == YYPUSH_MORE);
-    return (status == YYACCEPT);
+  public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ {
+      if (yylexer == null)
+          throw new NullPointerException("Null Lexer");
+      int status;
+      do {
+          int token = yylexer.yylex();
+          ]b4_yystype[ lval = yylexer.getLVal();]b4_locations_if([[
+          ]b4_location_type[ yyloc = new ]b4_location_type[(yylexer.getStartPos(), yylexer.getEndPos());
+          status = push_parse(token, lval, yyloc);]], [[
+          status = push_parse(token, lval);]])[
+      } while (status == YYPUSH_MORE);
+      return status == YYACCEPT;
   }
 ]])[
 
-  // Generate an error message.
-  private String yysyntax_error (int yystate, int tok)
-  {]b4_error_verbose_if([[
-    if (yyErrorVerbose)
-      {
-        /* There are many possibilities here to consider:
-           - If this state is a consistent state with a default action,
-             then the only way this function was invoked is if the
-             default action is an error action.  In that case, don't
-             check for expected tokens because there are none.
-           - The only way there can be no lookahead present (in tok) is
-             if this state is a consistent state with a default action.
-             Thus, detecting the absence of a lookahead is sufficient to
-             determine that there is no unexpected or expected token to
-             report.  In that case, just report a simple "syntax error".
-           - Don't assume there isn't a lookahead just because this
-             state is a consistent state with a default action.  There
-             might have been a previous inconsistent state, consistent
-             state with a non-default action, or user semantic action
-             that manipulated yychar.  (However, yychar is currently out
-             of scope during semantic actions.)
-           - Of course, the expected token list depends on states to
-             have correct lookahead information, and it depends on the
-             parser not to perform extra reductions after fetching a
-             lookahead from the scanner and before detecting a syntax
-             error.  Thus, state merging (from LALR or IELR) and default
-             reductions corrupt the expected token list.  However, the
-             list is correct for canonical LR with one exception: it
-             will still contain any token that will not be accepted due
-             to an error action in a later state.
-        */
-        if (tok != yyempty_)
-          {
-            /* FIXME: This method of building the message is not compatible
-               with internationalization.  */
-            StringBuffer res =
-              new StringBuffer ("syntax error, unexpected ");
-            res.append (yytnamerr_ (yytname_[tok]));
-            int yyn = yypact_[yystate];
-            if (!yyPactValueIsDefault (yyn))
-              {
-                /* Start YYX at -YYN if negative to avoid negative
-                   indexes in YYCHECK.  In other words, skip the first
-                   -YYN actions for this state because they are default
-                   actions.  */
-                int yyxbegin = yyn < 0 ? -yyn : 0;
-                /* Stay within bounds of both yycheck and yytname.  */
-                int yychecklim = yylast_ - yyn + 1;
-                int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
-                int count = 0;
-                for (int x = yyxbegin; x < yyxend; ++x)
-                  if (yycheck_[x + yyn] == x && x != yy_error_token_
-                      && !yyTableValueIsError (yytable_[x + yyn]))
-                    ++count;
-                if (count < 5)
-                  {
-                    count = 0;
-                    for (int x = yyxbegin; x < yyxend; ++x)
-                      if (yycheck_[x + yyn] == x && x != yy_error_token_
-                          && !yyTableValueIsError (yytable_[x + yyn]))
-                        {
-                          res.append (count++ == 0 ? ", expecting " : " or ");
-                          res.append (yytnamerr_ (yytname_[x]));
-                        }
-                  }
-              }
-            return res.toString ();
-          }
-      }
+  /**
+   * Information needed to get the list of expected tokens and to forge
+   * a syntax error diagnostic.
+   */
+  public static final class Context {
+    Context(]b4_parser_class[ parser, YYStack stack, SymbolKind token]b4_locations_if([[, ]b4_location_type[ loc]])[) {
+      yyparser = parser;
+      yystack = stack;
+      yytoken = token;]b4_locations_if([[
+      yylocation = loc;]])[
+    }
+
+    private ]b4_parser_class[ yyparser;
+    private YYStack yystack;
+
+
+    /**
+     * The symbol kind of the lookahead token.
+     */
+    public final SymbolKind getToken() {
+      return yytoken;
+    }
+
+    private SymbolKind yytoken;]b4_locations_if([[
+
+    /**
+     * The location of the lookahead.
+     */
+    public final ]b4_location_type[ getLocation() {
+      return yylocation;
+    }
+
+    private ]b4_location_type[ yylocation;]])[
+    static final int NTOKENS = ]b4_parser_class[.YYNTOKENS_;
+
+    /**
+     * Put in YYARG at most YYARGN of the expected tokens given the
+     * current YYCTX, and return the number of tokens stored in YYARG.  If
+     * YYARG is null, return the number of expected tokens (guaranteed to
+     * be less than YYNTOKENS).
+     */
+    int getExpectedTokens(SymbolKind yyarg[], int yyargn) {
+      return getExpectedTokens (yyarg, 0, yyargn);
+    }
+
+    int getExpectedTokens(SymbolKind yyarg[], int yyoffset, int yyargn) {
+      int yycount = yyoffset;]b4_lac_if([b4_parse_trace_if([[
+      // Execute LAC once. We don't care if it is successful, we
+      // only do it for the sake of debugging output.
+      if (!yyparser.yylacEstablished)
+        yyparser.yylacCheck(yystack, yytoken);
 ]])[
-    return "syntax error";
+      for (int yyx = 0; yyx < YYNTOKENS_; ++yyx)
+        {
+          SymbolKind yysym = SymbolKind.get(yyx);
+          if (yysym != ]b4_symbol(error, kind)[
+              && yysym != ]b4_symbol(undef, kind)[
+              && yyparser.yylacCheck(yystack, yysym))
+            {
+              if (yyarg == null)
+                yycount += 1;
+              else if (yycount == yyargn)
+                return 0;
+              else
+                yyarg[yycount++] = yysym;
+            }
+        }]], [[
+      int yyn = yypact_[this.yystack.stateAt(0)];
+      if (!yyPactValueIsDefault(yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative
+             indexes in YYCHECK.  In other words, skip the first
+             -YYN actions for this state because they are default
+             actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST_ - yyn + 1;
+          int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
+          for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[.getCode()
+                && !yyTableValueIsError(yytable_[yyx + yyn]))
+              {
+                if (yyarg == null)
+                  yycount += 1;
+                else if (yycount == yyargn)
+                  return 0; // FIXME: this is incorrect.
+                else
+                  yyarg[yycount++] = SymbolKind.get(yyx);
+              }
+        }]])[
+      if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
+        yyarg[yycount] = null;
+      return yycount - yyoffset;
+    }
+  }
+
+]b4_lac_if([[
+    /** Check the lookahead yytoken.
+     * \returns  true iff the token will be eventually shifted.
+     */
+    boolean yylacCheck(YYStack yystack, SymbolKind yytoken)
+    {
+      // Logically, the yylacStack's lifetime is confined to this function.
+      // Clear it, to get rid of potential left-overs from previous call.
+      yylacStack.clear();
+      // Reduce until we encounter a shift and thereby accept the token.
+      yycdebugNnl("LAC: checking lookahead " + yytoken.getName() + ":");
+      int lacTop = 0;
+      while (true)
+        {
+          int topState = (yylacStack.isEmpty()
+                          ? yystack.stateAt(lacTop)
+                          : yylacStack.get(yylacStack.size() - 1));
+          int yyrule = yypact_[topState];
+          if (yyPactValueIsDefault(yyrule)
+              || (yyrule += yytoken.getCode()) < 0 || YYLAST_ < yyrule
+              || yycheck_[yyrule] != yytoken.getCode())
+            {
+              // Use the default action.
+              yyrule = yydefact_[+topState];
+              if (yyrule == 0) {
+                yycdebug(" Err");
+                return false;
+              }
+            }
+          else
+            {
+              // Use the action from yytable.
+              yyrule = yytable_[yyrule];
+              if (yyTableValueIsError(yyrule)) {
+                yycdebug(" Err");
+                return false;
+              }
+              if (0 < yyrule) {
+                yycdebug(" S" + yyrule);
+                return true;
+              }
+              yyrule = -yyrule;
+            }
+          // By now we know we have to simulate a reduce.
+          yycdebugNnl(" R" + (yyrule - 1));
+          // Pop the corresponding number of values from the stack.
+          {
+            int yylen = yyr2_[yyrule];
+            // First pop from the LAC stack as many tokens as possible.
+            int lacSize = yylacStack.size();
+            if (yylen < lacSize) {
+              // yylacStack.setSize(lacSize - yylen);
+              for (/* Nothing */; 0 < yylen; yylen -= 1) {
+                yylacStack.remove(yylacStack.size() - 1);
+              }
+              yylen = 0;
+            } else if (lacSize != 0) {
+              yylacStack.clear();
+              yylen -= lacSize;
+            }
+            // Only afterwards look at the main stack.
+            // We simulate popping elements by incrementing lacTop.
+            lacTop += yylen;
+          }
+          // Keep topState in sync with the updated stack.
+          topState = (yylacStack.isEmpty()
+                      ? yystack.stateAt(lacTop)
+                      : yylacStack.get(yylacStack.size() - 1));
+          // Push the resulting state of the reduction.
+          int state = yyLRGotoState(topState, yyr1_[yyrule]);
+          yycdebugNnl(" G" + state);
+          yylacStack.add(state);
+        }
+    }
+
+    /** Establish the initial context if no initial context currently exists.
+     * \returns  true iff the token will be eventually shifted.
+     */
+    boolean yylacEstablish(YYStack yystack, SymbolKind yytoken) {
+      /* Establish the initial context for the current lookahead if no initial
+         context is currently established.
+
+         We define a context as a snapshot of the parser stacks.  We define
+         the initial context for a lookahead as the context in which the
+         parser initially examines that lookahead in order to select a
+         syntactic action.  Thus, if the lookahead eventually proves
+         syntactically unacceptable (possibly in a later context reached via a
+         series of reductions), the initial context can be used to determine
+         the exact set of tokens that would be syntactically acceptable in the
+         lookahead's place.  Moreover, it is the context after which any
+         further semantic actions would be erroneous because they would be
+         determined by a syntactically unacceptable token.
+
+         yylacEstablish should be invoked when a reduction is about to be
+         performed in an inconsistent state (which, for the purposes of LAC,
+         includes consistent states that don't know they're consistent because
+         their default reductions have been disabled).
+
+         For parse.lac=full, the implementation of yylacEstablish is as
+         follows.  If no initial context is currently established for the
+         current lookahead, then check if that lookahead can eventually be
+         shifted if syntactic actions continue from the current context.  */
+      if (yylacEstablished) {
+        return true;
+      } else {
+        yycdebug("LAC: initial context established for " + yytoken.getName());
+        yylacEstablished = true;
+        return yylacCheck(yystack, yytoken);
+      }
+    }
+
+    /** Discard any previous initial lookahead context because of event.
+     * \param event  the event which caused the lookahead to be discarded.
+     *               Only used for debbuging output.  */
+    void yylacDiscard(String event) {
+     /* Discard any previous initial lookahead context because of Event,
+        which may be a lookahead change or an invalidation of the currently
+        established initial context for the current lookahead.
+
+        The most common example of a lookahead change is a shift.  An example
+        of both cases is syntax error recovery.  That is, a syntax error
+        occurs when the lookahead is syntactically erroneous for the
+        currently established initial context, so error recovery manipulates
+        the parser stacks to try to find a new initial context in which the
+        current lookahead is syntactically acceptable.  If it fails to find
+        such a context, it discards the lookahead.  */
+      if (yylacEstablished) {
+        yycdebug("LAC: initial context discarded due to " + event);
+        yylacEstablished = false;
+      }
+    }
+
+    /** The stack for LAC.
+     * Logically, the yylacStack's lifetime is confined to the function
+     * yylacCheck. We just store it as a member of this class to hold
+     * on to the memory and to avoid frequent reallocations.
+     */
+    ArrayList<Integer> yylacStack;
+    /**  Whether an initial LAC context was established. */
+    boolean yylacEstablished;
+]])[
+
+]b4_parse_error_bmatch(
+[detailed\|verbose], [[
+  private int yysyntaxErrorArguments(Context yyctx, SymbolKind[] yyarg, int yyargn) {
+    /* There are many possibilities here to consider:
+       - If this state is a consistent state with a default action,
+         then the only way this function was invoked is if the
+         default action is an error action.  In that case, don't
+         check for expected tokens because there are none.
+       - The only way there can be no lookahead present (in tok) is
+         if this state is a consistent state with a default action.
+         Thus, detecting the absence of a lookahead is sufficient to
+         determine that there is no unexpected or expected token to
+         report.  In that case, just report a simple "syntax error".
+       - Don't assume there isn't a lookahead just because this
+         state is a consistent state with a default action.  There
+         might have been a previous inconsistent state, consistent
+         state with a non-default action, or user semantic action
+         that manipulated yychar.  (However, yychar is currently out
+         of scope during semantic actions.)
+       - Of course, the expected token list depends on states to
+         have correct lookahead information, and it depends on the
+         parser not to perform extra reductions after fetching a
+         lookahead from the scanner and before detecting a syntax
+         error.  Thus, state merging (from LALR or IELR) and default
+         reductions corrupt the expected token list.  However, the
+         list is correct for canonical LR with one exception: it
+         will still contain any token that will not be accepted due
+         to an error action in a later state.
+    */
+    int yycount = 0;
+    if (yyctx.getToken() != null)
+      {
+        if (yyarg != null)
+          yyarg[yycount] = yyctx.getToken();
+        yycount += 1;
+        yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
+      }
+    return yycount;
+  }
+]])[
+
+  /**
+   * Build and emit a "syntax error" message in a user-defined way.
+   *
+   * @@param ctx  The context of the error.
+   */
+  private void yyreportSyntaxError(Context yyctx) {]b4_parse_error_bmatch(
+[custom], [[
+      yylexer.reportSyntaxError(yyctx);]],
+[detailed\|verbose], [[
+      if (yyErrorVerbose) {
+          final int argmax = 5;
+          SymbolKind[] yyarg = new SymbolKind[argmax];
+          int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax);
+          String[] yystr = new String[yycount];
+          for (int yyi = 0; yyi < yycount; ++yyi) {
+              yystr[yyi] = yyarg[yyi].getName();
+          }
+          String yyformat;
+          switch (yycount) {
+              default:
+              case 0: yyformat = ]b4_trans(["syntax error"])[; break;
+              case 1: yyformat = ]b4_trans(["syntax error, unexpected {0}"])[; break;
+              case 2: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1}"])[; break;
+              case 3: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2}"])[; break;
+              case 4: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3}"])[; break;
+              case 5: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"])[; break;
+          }
+          yyerror(]b4_locations_if([[yyctx.yylocation, ]])[new MessageFormat(yyformat).format(yystr));
+      } else {
+          yyerror(]b4_locations_if([[yyctx.yylocation, ]])[]b4_trans(["syntax error"])[);
+      }]],
+[simple], [[
+      yyerror(]b4_locations_if([[yyctx.yylocation, ]])[]b4_trans(["syntax error"])[);]])[
   }
 
   /**
    * Whether the given <code>yypact_</code> value indicates a defaulted state.
    * @@param yyvalue   the value to check
    */
-  private static boolean yyPactValueIsDefault (int yyvalue)
-  {
+  private static boolean yyPactValueIsDefault(int yyvalue) {
     return yyvalue == yypact_ninf_;
   }
 
@@ -967,19 +1236,14 @@
    * value indicates a syntax error.
    * @@param yyvalue the value to check
    */
-  private static boolean yyTableValueIsError (int yyvalue)
-  {
+  private static boolean yyTableValueIsError(int yyvalue) {
     return yyvalue == yytable_ninf_;
   }
 
   private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[;
   private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[;
 
-  ]b4_parser_tables_define[
-
-  /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-     First, the terminals, then, starting at \a yyntokens_, nonterminals.  */
-  ]b4_typed_parser_table_define([String], [tname], [b4_tname])[
+]b4_parser_tables_define[
 
 ]b4_parse_trace_if([[
   ]b4_integral_parser_table_define([rline], [b4_rline],
@@ -996,50 +1260,44 @@
     int yynrhs = yyr2_[yyrule];
     /* Print the symbols being reduced, and their result.  */
     yycdebug ("Reducing stack by rule " + (yyrule - 1)
-              + " (line " + yylno + "), ");
+              + " (line " + yylno + "):");
 
     /* The symbols being reduced.  */
     for (int yyi = 0; yyi < yynrhs; yyi++)
-      yySymbolPrint ("   $" + (yyi + 1) + " =",
-                     yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
-                     ]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
-                     b4_rhs_location(yynrhs, yyi + 1)])[);
+      yySymbolPrint("   $" + (yyi + 1) + " =",
+                    SymbolKind.get(yystos_[yystack.stateAt(yynrhs - (yyi + 1))]),
+                    ]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
+                    b4_rhs_location(yynrhs, yyi + 1)])[);
   }]])[
 
   /* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
      as returned by yylex, with out-of-bounds checking.  */
-  private static final ]b4_int_type_for([b4_translate])[ yytranslate_ (int t)
+  private static final SymbolKind yytranslate_(int t)
 ]b4_api_token_raw_if(dnl
 [[  {
-    return t;
+    return SymbolKind.get(t);
   }
 ]],
 [[  {
-    int user_token_number_max_ = ]b4_user_token_number_max[;
-    ]b4_int_type_for([b4_translate])[ undef_token_ = ]b4_undef_token_number[;
-
+    // Last valid token kind.
+    int code_max = ]b4_code_max[;
     if (t <= 0)
-      return Lexer.EOF;
-    else if (t <= user_token_number_max_)
-      return yytranslate_table_[t];
+      return ]b4_symbol(eof, kind)[;
+    else if (t <= code_max)
+      return SymbolKind.get(yytranslate_table_[t]);
     else
-      return undef_token_;
+      return ]b4_symbol(undef, kind)[;
   }
   ]b4_integral_parser_table_define([translate_table], [b4_translate])[
 ]])[
 
-  private static final ]b4_int_type_for([b4_translate])[ yy_error_token_ = 1;
+  private static final int YYLAST_ = ]b4_last[;
+  private static final int YYEMPTY_ = -2;
+  private static final int YYFINAL_ = ]b4_final_state_number[;
+  private static final int YYNTOKENS_ = ]b4_tokens_number[;
 
-  private static final int yylast_ = ]b4_last[;
-  private static final int yynnts_ = ]b4_nterms_number[;
-  private static final int yyempty_ = -2;
-  private static final int yyfinal_ = ]b4_final_state_number[;
-  private static final int yyntokens_ = ]b4_tokens_number[;
-
-/* User implementation code.  */
-]b4_percent_code_get[]dnl
-
+]b4_percent_code_get[
 }
-
+]b4_percent_code_get([[epilogue]])[]dnl
 b4_epilogue[]dnl
 b4_output_end
diff --git a/common/bison/skeletons/location.cc b/common/bison/skeletons/location.cc
index 0258379..3870b2b 100644
--- a/common/bison/skeletons/location.cc
+++ b/common/bison/skeletons/location.cc
@@ -1,6 +1,6 @@
 # C++ skeleton for Bison
 
-# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,17 +13,10 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_pushdef([b4_copyright_years],
-           [2002-2015, 2018-2019])
-
-
-# b4_position_file
-# ----------------
-# Name of the file containing the position class, if we want this file.
-b4_defines_if([b4_required_version_if([302], [],
-                                      [m4_define([b4_position_file], [position.hh])])])])
+           [2002-2015, 2018-2021])
 
 
 # b4_location_file
@@ -32,7 +25,7 @@
 # if we want this file.
 b4_percent_define_check_file([b4_location_file],
                              [[api.location.file]],
-                             b4_defines_if([[location.hh]]))
+                             b4_header_if([[location.hh]]))
 
 # b4_location_include
 # -------------------
@@ -48,12 +41,22 @@
                                   ["b4_location_file"])])
  m4_define([b4_location_path],
            b4_percent_define_get([[api.location.include]],
-                                 ["b4_dir_prefix[]b4_location_file"]))
+                                 ["b4_mapped_dir_prefix[]b4_location_file"]))
  m4_define([b4_location_path],
            m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
  ])
 
 
+# b4_position_file
+# ----------------
+# Name of the file containing the position class, if we want this file.
+b4_header_if(
+  [b4_required_version_if(
+    [30200], [],
+    [m4_ifdef([b4_location_file],
+              [m4_define([b4_position_file], [position.hh])])])])
+
+
 
 # b4_location_define
 # ------------------
@@ -63,11 +66,13 @@
   class position
   {
   public:
+    /// Type for file name.
+    typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
     /// Type for line and column numbers.
     typedef int counter_type;
 ]m4_ifdef([b4_location_constructors], [[
     /// Construct a position.
-    explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
+    explicit position (filename_type* f = YY_NULLPTR,
                        counter_type l = ]b4_location_initial_line[,
                        counter_type c = ]b4_location_initial_column[)
       : filename (f)
@@ -77,7 +82,7 @@
 
 ]])[
     /// Initialization.
-    void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
+    void initialize (filename_type* fn = YY_NULLPTR,
                      counter_type l = ]b4_location_initial_line[,
                      counter_type c = ]b4_location_initial_column[)
     {
@@ -106,7 +111,7 @@
     /** \} */
 
     /// File name to which this position refers.
-    ]b4_percent_define_get([[filename_type]])[* filename;
+    filename_type* filename;
     /// Current line number.
     counter_type line;
     /// Current column number.
@@ -184,6 +189,8 @@
   class location
   {
   public:
+    /// Type for file name.
+    typedef position::filename_type filename_type;
     /// Type for line and column numbers.
     typedef position::counter_type counter_type;
 ]m4_ifdef([b4_location_constructors], [
@@ -200,7 +207,7 @@
     {}
 
     /// Construct a 0-width location in \a f, \a l, \a c.
-    explicit location (]b4_percent_define_get([[filename_type]])[* f,
+    explicit location (filename_type* f,
                        counter_type l = ]b4_location_initial_line[,
                        counter_type c = ]b4_location_initial_column[)
       : begin (f, l, c)
@@ -209,7 +216,7 @@
 
 ])[
     /// Initialization.
-    void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
+    void initialize (filename_type* f = YY_NULLPTR,
                      counter_type l = ]b4_location_initial_line[,
                      counter_type c = ]b4_location_initial_column[)
     {
diff --git a/common/bison/skeletons/stack.hh b/common/bison/skeletons/stack.hh
index cb52bcc..9891325 100644
--- a/common/bison/skeletons/stack.hh
+++ b/common/bison/skeletons/stack.hh
@@ -1,6 +1,6 @@
 # C++ skeleton for Bison
 
-# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,14 +13,14 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 
 # b4_stack_file
 # -------------
 # Name of the file containing the stack class, if we want this file.
-b4_defines_if([b4_required_version_if([302], [],
-                                      [m4_define([b4_stack_file], [stack.hh])])])
+b4_header_if([b4_required_version_if([30200], [],
+                                     [m4_define([b4_stack_file], [stack.hh])])])
 
 
 # b4_stack_define
@@ -32,15 +32,22 @@
     {
     public:
       // Hide our reversed order.
-      typedef typename S::reverse_iterator iterator;
-      typedef typename S::const_reverse_iterator const_iterator;
+      typedef typename S::iterator iterator;
+      typedef typename S::const_iterator const_iterator;
       typedef typename S::size_type size_type;
       typedef typename std::ptrdiff_t index_type;
 
-      stack (size_type n = 200)
+      stack (size_type n = 200) YY_NOEXCEPT
         : seq_ (n)
       {}
 
+#if 201103L <= YY_CPLUSPLUS
+      /// Non copyable.
+      stack (const stack&) = delete;
+      /// Non copyable.
+      stack& operator= (const stack&) = delete;
+#endif
+
       /// Random access.
       ///
       /// Index 0 returns the topmost element.
@@ -91,31 +98,25 @@
         return index_type (seq_.size ());
       }
 
-      std::ptrdiff_t
-      ssize () const YY_NOEXCEPT
-      {
-        return std::ptrdiff_t (size ());
-      }
-
       /// Iterator on top of the stack (going downwards).
       const_iterator
       begin () const YY_NOEXCEPT
       {
-        return seq_.rbegin ();
+        return seq_.begin ();
       }
 
       /// Bottom of the stack.
       const_iterator
       end () const YY_NOEXCEPT
       {
-        return seq_.rend ();
+        return seq_.end ();
       }
 
       /// Present a slice of the top of a stack.
       class slice
       {
       public:
-        slice (const stack& stack, index_type range)
+        slice (const stack& stack, index_type range) YY_NOEXCEPT
           : stack_ (stack)
           , range_ (range)
         {}
@@ -132,8 +133,12 @@
       };
 
     private:
+#if YY_CPLUSPLUS < 201103L
+      /// Non copyable.
       stack (const stack&);
+      /// Non copyable.
       stack& operator= (const stack&);
+#endif
       /// The wrapped container.
       S seq_;
     };
diff --git a/common/bison/skeletons/traceon.m4 b/common/bison/skeletons/traceon.m4
new file mode 100644
index 0000000..344d7d1
--- /dev/null
+++ b/common/bison/skeletons/traceon.m4
@@ -0,0 +1,2 @@
+dnl GNU M4 treats -dV in a position-independent manner.
+m4_debugmode(V)m4_traceon()dnl
diff --git a/common/bison/skeletons/variant.hh b/common/bison/skeletons/variant.hh
index be4a3ce..2a490e8 100644
--- a/common/bison/skeletons/variant.hh
+++ b/common/bison/skeletons/variant.hh
@@ -1,6 +1,6 @@
 # C++ skeleton for Bison
 
-# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,13 +13,20 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 
 ## --------- ##
 ## variant.  ##
 ## --------- ##
 
+# b4_assert
+# ---------
+# The name of YY_ASSERT.
+m4_define([b4_assert],
+          [b4_api_PREFIX[]_ASSERT])
+
+
 # b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
 # ------------------------------------------------
 # Run some ACTION ("build", or "destroy") on YYVAL of symbol type
@@ -71,12 +78,12 @@
 # -------------------
 # The needed includes for variants support.
 m4_define([b4_variant_includes],
-[b4_parse_assert_if([[#include <typeinfo>]])[
-#ifndef YY_ASSERT
+[b4_parse_assert_if([[#include <typeinfo>
+#ifndef ]b4_assert[
 # include <cassert>
-# define YY_ASSERT assert
+# define ]b4_assert[ assert
 #endif
-]])
+]])])
 
 
 
@@ -87,38 +94,45 @@
 
 # b4_value_type_declare
 # ---------------------
-# Define semantic_type.
+# Define value_type.
 m4_define([b4_value_type_declare],
 [[  /// A buffer to store and retrieve objects.
   ///
   /// Sort of a variant, but does not keep track of the nature
   /// of the stored data, since that knowledge is available
   /// via the current parser state.
-  class semantic_type
+  class value_type
   {
   public:
     /// Type of *this.
-    typedef semantic_type self_type;
+    typedef value_type self_type;
 
     /// Empty construction.
-    semantic_type () YY_NOEXCEPT
-      : yybuffer_ ()]b4_parse_assert_if([
+    value_type () YY_NOEXCEPT
+      : yyraw_ ()]b4_parse_assert_if([
       , yytypeid_ (YY_NULLPTR)])[
     {}
 
     /// Construct and fill.
     template <typename T>
-    semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
+    value_type (YY_RVREF (T) t)]b4_parse_assert_if([
       : yytypeid_ (&typeid (T))])[
-    {
-      YY_ASSERT (sizeof (T) <= size);
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (sizeof (T) <= size);]])[
       new (yyas_<T> ()) T (YY_MOVE (t));
     }
 
+#if 201103L <= YY_CPLUSPLUS
+    /// Non copyable.
+    value_type (const self_type&) = delete;
+    /// Non copyable.
+    self_type& operator= (const self_type&) = delete;
+#endif
+
     /// Destruction, allowed only if empty.
-    ~semantic_type () YY_NOEXCEPT
+    ~value_type () YY_NOEXCEPT
     {]b4_parse_assert_if([
-      YY_ASSERT (!yytypeid_);
+      ]b4_assert[ (!yytypeid_);
     ])[}
 
 # if 201103L <= YY_CPLUSPLUS
@@ -126,10 +140,10 @@
     template <typename T, typename... U>
     T&
     emplace (U&&... u)
-    {]b4_parse_assert_if([
-      YY_ASSERT (!yytypeid_);
-      YY_ASSERT (sizeof (T) <= size);
-      yytypeid_ = & typeid (T);])[
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (!yytypeid_);
+      ]b4_assert[ (sizeof (T) <= size);
+      yytypeid_ = & typeid (T);]])[
       return *new (yyas_<T> ()) T (std::forward <U>(u)...);
     }
 # else
@@ -137,10 +151,10 @@
     template <typename T>
     T&
     emplace ()
-    {]b4_parse_assert_if([
-      YY_ASSERT (!yytypeid_);
-      YY_ASSERT (sizeof (T) <= size);
-      yytypeid_ = & typeid (T);])[
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (!yytypeid_);
+      ]b4_assert[ (sizeof (T) <= size);
+      yytypeid_ = & typeid (T);]])[
       return *new (yyas_<T> ()) T ();
     }
 
@@ -148,10 +162,10 @@
     template <typename T>
     T&
     emplace (const T& t)
-    {]b4_parse_assert_if([
-      YY_ASSERT (!yytypeid_);
-      YY_ASSERT (sizeof (T) <= size);
-      yytypeid_ = & typeid (T);])[
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (!yytypeid_);
+      ]b4_assert[ (sizeof (T) <= size);
+      yytypeid_ = & typeid (T);]])[
       return *new (yyas_<T> ()) T (t);
     }
 # endif
@@ -178,10 +192,10 @@
     template <typename T>
     T&
     as () YY_NOEXCEPT
-    {]b4_parse_assert_if([
-      YY_ASSERT (yytypeid_);
-      YY_ASSERT (*yytypeid_ == typeid (T));
-      YY_ASSERT (sizeof (T) <= size);])[
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (yytypeid_);
+      ]b4_assert[ (*yytypeid_ == typeid (T));
+      ]b4_assert[ (sizeof (T) <= size);]])[
       return *yyas_<T> ();
     }
 
@@ -189,10 +203,10 @@
     template <typename T>
     const T&
     as () const YY_NOEXCEPT
-    {]b4_parse_assert_if([
-      YY_ASSERT (yytypeid_);
-      YY_ASSERT (*yytypeid_ == typeid (T));
-      YY_ASSERT (sizeof (T) <= size);])[
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (yytypeid_);
+      ]b4_assert[ (*yytypeid_ == typeid (T));
+      ]b4_assert[ (sizeof (T) <= size);]])[
       return *yyas_<T> ();
     }
 
@@ -207,9 +221,9 @@
     template <typename T>
     void
     swap (self_type& that) YY_NOEXCEPT
-    {]b4_parse_assert_if([
-      YY_ASSERT (yytypeid_);
-      YY_ASSERT (*yytypeid_ == *that.yytypeid_);])[
+    {]b4_parse_assert_if([[
+      ]b4_assert[ (yytypeid_);
+      ]b4_assert[ (*yytypeid_ == *that.yytypeid_);]])[
       std::swap (as<T> (), that.as<T> ());
     }
 
@@ -258,16 +272,19 @@
     }
 
   private:
-    /// Prohibit blind copies.
+#if YY_CPLUSPLUS < 201103L
+    /// Non copyable.
+    value_type (const self_type&);
+    /// Non copyable.
     self_type& operator= (const self_type&);
-    semantic_type (const self_type&);
+#endif
 
     /// Accessor to raw memory as \a T.
     template <typename T>
     T*
     yyas_ () YY_NOEXCEPT
     {
-      void *yyp = yybuffer_.yyraw;
+      void *yyp = yyraw_;
       return static_cast<T*> (yyp);
      }
 
@@ -276,7 +293,7 @@
     const T*
     yyas_ () const YY_NOEXCEPT
     {
-      const void *yyp = yybuffer_.yyraw;
+      const void *yyp = yyraw_;
       return static_cast<const T*> (yyp);
      }
 
@@ -291,10 +308,10 @@
     union
     {
       /// Strongest alignment constraints.
-      long double yyalign_me;
+      long double yyalign_me_;
       /// A buffer large enough to store any of the semantic values.
-      char yyraw[size];
-    } yybuffer_;]b4_parse_assert_if([
+      char yyraw_[size];
+    };]b4_parse_assert_if([
 
     /// Whether the content is built: if defined, the name of the stored type.
     const std::type_info *yytypeid_;])[
@@ -378,18 +395,74 @@
 ])])
 
 
-m4_define([_b4_type_clause],
-[b4_symbol_if([$1], [is_token],
-              [b4_symbol_if([$1], [has_id],
-                            [tok == token::b4_symbol([$1], [id])],
-                            [tok == b4_symbol([$1], [user_number])])])])
+# b4_token_kind(SYMBOL-NUM)
+# -------------------------
+# Some tokens don't have an ID.
+m4_define([b4_token_kind],
+[b4_symbol_if([$1], [has_id],
+              [token::b4_symbol([$1], [id])],
+              [b4_symbol([$1], [code])])])
 
 
-# _b4_token_constructor_define(SYMBOL-NUM...)
-# -------------------------------------------
-# Define a unique make_symbol for all the SYMBOL-NUM (they
+# _b4_tok_in(SYMBOL-NUM, ...)
+# ---------------------------
+# See b4_tok_in below.  The SYMBOL-NUMs... are tokens only.
+#
+# We iterate over the tokens to group them by "range" of token numbers (not
+# symbols numbers!).
+#
+# b4_fst is the start of that range.
+# b4_prev is the previous value.
+# b4_val is the current value.
+# If b4_val is the successor of b4_prev in token numbers, update the latter,
+#   otherwise emit the code for range b4_fst .. b4_prev.
+# $1 is also used as a terminator in the foreach, but it will not be printed.
+#
+m4_define([_b4_tok_in],
+[m4_pushdef([b4_prev], [$1])dnl
+m4_pushdef([b4_fst], [$1])dnl
+m4_pushdef([b4_sep], [])dnl
+m4_foreach([b4_val], m4_dquote(m4_shift($@, $1)),
+           [m4_if(b4_symbol(b4_val, [code]), m4_eval(b4_symbol(b4_prev, [code]) + 1), [],
+                  [b4_sep[]m4_if(b4_fst, b4_prev,
+                         [tok == b4_token_kind(b4_fst)],
+                         [(b4_token_kind(b4_fst) <= tok && tok <= b4_token_kind(b4_prev))])[]dnl
+m4_define([b4_fst], b4_val)dnl
+m4_define([b4_sep], [
+                   || ])])dnl
+m4_define([b4_prev], b4_val)])dnl
+m4_popdef([b4_sep])dnl
+m4_popdef([b4_fst])dnl
+m4_popdef([b4_prev])dnl
+])
+
+
+# _b4_filter_tokens(SYMBOL-NUM, ...)
+# ----------------------------------
+# Expand as the list of tokens amongst SYMBOL-NUM.
+m4_define([_b4_filter_tokens],
+[m4_pushdef([b4_sep])dnl
+m4_foreach([b4_val], [$@],
+           [b4_symbol_if(b4_val, [is_token], [b4_sep[]b4_val[]m4_define([b4_sep], [,])])])dnl
+m4_popdef([b4_sep])dnl
+])
+
+
+# b4_tok_in(SYMBOL-NUM, ...)
+# ---------------------------
+# A C++ conditional that checks that `tok` is a member of this list of symbol
+# numbers.
+m4_define([b4_tok_in],
+          [_$0(_b4_filter_tokens($@))])
+
+
+
+
+# _b4_symbol_constructor_define(SYMBOL-NUM...)
+# --------------------------------------------
+# Define a symbol_type constructor common to all the SYMBOL-NUM (they
 # have the same type).  Use at class-level.
-m4_define([_b4_token_constructor_define],
+m4_define([_b4_symbol_constructor_define],
 [m4_ifval(_b4_includes_tokens($@),
 [[#if 201103L <= YY_CPLUSPLUS
       symbol_type (]b4_join(
@@ -397,25 +470,24 @@
           b4_symbol_if([$1], [has_type],
                        [b4_symbol([$1], [type]) v]),
           b4_locations_if([location_type l]))[)
-        : super_type(]b4_join([token_type (tok)],
-                              b4_symbol_if([$1], [has_type], [std::move (v)]),
-                              b4_locations_if([std::move (l)]))[)
-      {
-        YY_ASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
-      }
+        : super_type (]b4_join([token_kind_type (tok)],
+                               b4_symbol_if([$1], [has_type], [std::move (v)]),
+                               b4_locations_if([std::move (l)]))[)
 #else
       symbol_type (]b4_join(
           [int tok],
           b4_symbol_if([$1], [has_type],
                        [const b4_symbol([$1], [type])& v]),
           b4_locations_if([const location_type& l]))[)
-        : super_type(]b4_join([token_type (tok)],
-                              b4_symbol_if([$1], [has_type], [v]),
-                              b4_locations_if([l]))[)
-      {
-        YY_ASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
-      }
+        : super_type (]b4_join([token_kind_type (tok)],
+                               b4_symbol_if([$1], [has_type], [v]),
+                               b4_locations_if([l]))[)
 #endif
+      {]b4_parse_assert_if([[
+#if !defined _MSC_VER || defined __clang__
+        ]b4_assert[ (]b4_tok_in($@)[);
+#endif
+      ]])[}
 ]])])
 
 
@@ -447,7 +519,7 @@
 
 # b4_token_constructor_define
 # ---------------------------
-# Define the overloaded versions of make_symbol for all the value types.
+# Define the overloaded versions of make_FOO for all the token kinds.
 m4_define([b4_token_constructor_define],
-[    // Implementation of make_symbol for each symbol type.
+[    // Implementation of make_symbol for each token kind.
 b4_symbol_foreach([_b4_token_maker_define])])
diff --git a/common/bison/skeletons/yacc.c b/common/bison/skeletons/yacc.c
index 2830c1d..64b9ac6 100644
--- a/common/bison/skeletons/yacc.c
+++ b/common/bison/skeletons/yacc.c
@@ -1,11 +1,11 @@
 #                                                            -*- C -*-
 # Yacc compatible skeleton for Bison
 
-# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software
+# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software
 # Foundation, Inc.
 
 m4_pushdef([b4_copyright_years],
-           [1984, 1989-1990, 2000-2015, 2018-2019])
+           [1984, 1989-1990, 2000-2015, 2018-2021])
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,10 +18,11 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 m4_include(b4_skeletonsdir/[c.m4])
 
+
 ## ---------- ##
 ## api.pure.  ##
 ## ---------- ##
@@ -48,6 +49,10 @@
 ## api.push-pull.  ##
 ## --------------- ##
 
+# b4_pull_if, b4_push_if
+# ----------------------
+# Whether the pull/push APIs are needed.  Both can be enabled.
+
 b4_percent_define_default([[api.push-pull]], [[pull]])
 b4_percent_define_check_values([[[[api.push-pull]],
                                  [[pull]], [[push]], [[both]]]])
@@ -97,6 +102,16 @@
                           [1], [m4_ifset([b4_parse_param], [$1])],
                           [2], [$1])])])
 
+# b4_yyerror_formals
+# ------------------
+m4_define([b4_yyerror_formals],
+[b4_pure_if([b4_locations_if([, [[const ]b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])[]dnl
+m4_ifdef([b4_parse_param], [, b4_parse_param])[]dnl
+,])dnl
+[[const char *msg], [msg]]])
+
+
+
 # b4_yyerror_args
 # ---------------
 # Arguments passed to yyerror: user args plus yylloc.
@@ -111,6 +126,16 @@
 ## ----------------- ##
 
 
+# b4_accept([SYMBOL-NUM])
+# -----------------------
+# Used in actions of the rules of accept, the initial symbol, to call
+# YYACCEPT.  If SYMBOL-NUM is specified, run "yyvalue->SLOT = $2;"
+# before, using the slot of SYMBOL-NUM.
+m4_define([b4_accept],
+[m4_ifval([$1],
+          [b4_symbol_value(yyimpl->yyvalue, [$1]) = b4_rhs_value(2, 1, [$1]); ]) YYACCEPT])
+
+
 # b4_lhs_value(SYMBOL-NUM, [TYPE])
 # --------------------------------
 # See README.
@@ -132,6 +157,7 @@
 # b4_lhs_location()
 # -----------------
 # Expansion of @$.
+# Overparenthetized to avoid obscure problems with "foo$$bar = foo$1bar".
 m4_define([b4_lhs_location],
 [(yyloc)])
 
@@ -140,6 +166,7 @@
 # ---------------------------------
 # Expansion of @POS, where the current rule has RULE-LENGTH symbols
 # on RHS.
+# Overparenthetized to avoid obscure problems with "foo$$bar = foo$1bar".
 m4_define([b4_rhs_location],
 [(yylsp@{b4_subtract([$2], [$1])@})])
 
@@ -148,14 +175,61 @@
 ## Declarations.  ##
 ## -------------- ##
 
+# _b4_declare_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
+# ---------------------------------------------------------------------
+# Define the return type of the parsing function for SYMBOL-NUM, and
+# declare its parsing function.
+m4_define([_b4_declare_sub_yyparse],
+[[
+// Return type when parsing one ]_b4_symbol($1, tag)[.
+typedef struct
+{]b4_symbol_if([$1], [has_type], [[
+  ]_b4_symbol($1, type)[ yyvalue;]])[
+  int yystatus;
+  int yynerrs;
+} ]b4_prefix[parse_]_b4_symbol($1, id)[_t;
+
+// Parse one ]_b4_symbol($1, tag)[.
+]b4_prefix[parse_]_b4_symbol($1, id)[_t ]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
+]])
+
+
+# _b4_first_switching_token
+# -------------------------
+m4_define([b4_first], [$1])
+m4_define([b4_second], [$2])
+m4_define([_b4_first_switching_token],
+[b4_second(b4_first(b4_start_symbols))])
+
+
+# _b4_define_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
+# --------------------------------------------------------------------
+# Define the parsing function for START-SYMBOL-NUM.
+m4_define([_b4_define_sub_yyparse],
+[[
+]b4_prefix[parse_]_b4_symbol($1, id)[_t
+]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
+{
+  ]b4_prefix[parse_]_b4_symbol($1, id)[_t yyres;
+  yy_parse_impl_t yyimpl;
+  yyres.yystatus = yy_parse_impl (]b4_symbol($2, id)[, &yyimpl]m4_ifset([b4_parse_param],
+                           [[, ]b4_args(b4_parse_param)])[);]b4_symbol_if([$1], [has_type], [[
+  yyres.yyvalue = yyimpl.yyvalue.]b4_symbol($1, slot)[;]])[
+  yyres.yynerrs = yyimpl.yynerrs;
+  return yyres;
+}
+]])
+
+
 # b4_declare_scanner_communication_variables
 # ------------------------------------------
 # Declare the variables that are global, or local to YYPARSE if
 # pure-parser.
 m4_define([b4_declare_scanner_communication_variables], [[
-/* The lookahead symbol.  */
+]m4_ifdef([b4_start_symbols], [],
+[[/* Lookahead token kind.  */
 int yychar;
-
+]])[
 ]b4_pure_if([[
 /* The semantic value of the lookahead symbol.  */
 /* Default value used for initialization, for pacifying older GCCs
@@ -174,49 +248,79 @@
 int yynerrs;]])])
 
 
-# b4_declare_parser_state_variables
-# ---------------------------------
+# b4_declare_parser_state_variables([INIT])
+# -----------------------------------------
 # Declare all the variables that are needed to maintain the parser state
 # between calls to yypush_parse.
-m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
+# If INIT is non-null, initialize these variables.
+m4_define([b4_declare_parser_state_variables],
+[b4_pure_if([[
     /* Number of syntax errors so far.  */
-    int yynerrs;
+    int yynerrs]m4_ifval([$1], [ = 0])[;
 ]])[
-    yy_state_fast_t yystate;
+    yy_state_fast_t yystate]m4_ifval([$1], [ = 0])[;
     /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
+    int yyerrstatus]m4_ifval([$1], [ = 0])[;
 
-    /* The stacks and their tools:
-       'yyss': related to states.
-       'yyvs': related to semantic values.]b4_locations_if([[
-       'yyls': related to locations.]])[
-
-       Refer to the stacks through separate pointers, to allow yyoverflow
+    /* Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
-    /* The state stack.  */
+    /* Their size.  */
+    YYPTRDIFF_T yystacksize]m4_ifval([$1], [ = YYINITDEPTH])[;
+
+    /* The state stack: array, bottom, top.  */
     yy_state_t yyssa[YYINITDEPTH];
-    yy_state_t *yyss;
-    yy_state_t *yyssp;
+    yy_state_t *yyss]m4_ifval([$1], [ = yyssa])[;
+    yy_state_t *yyssp]m4_ifval([$1], [ = yyss])[;
 
-    /* The semantic value stack.  */
+    /* The semantic value stack: array, bottom, top.  */
     YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;]b4_locations_if([[
+    YYSTYPE *yyvs]m4_ifval([$1], [ = yyvsa])[;
+    YYSTYPE *yyvsp]m4_ifval([$1], [ = yyvs])[;]b4_locations_if([[
 
-    /* The location stack.  */
+    /* The location stack: array, bottom, top.  */
     YYLTYPE yylsa[YYINITDEPTH];
-    YYLTYPE *yyls;
-    YYLTYPE *yylsp;
-
-    /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[3];]])[
-
-    YYPTRDIFF_T yystacksize;]b4_lac_if([[
+    YYLTYPE *yyls]m4_ifval([$1], [ = yylsa])[;
+    YYLTYPE *yylsp]m4_ifval([$1], [ = yyls])[;]])[]b4_lac_if([[
 
     yy_state_t yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
-    yy_state_t *yyes;
-    YYPTRDIFF_T yyes_capacity;]])])
+    yy_state_t *yyes]m4_ifval([$1], [ = yyesa])[;
+    YYPTRDIFF_T yyes_capacity][]m4_ifval([$1],
+            [m4_do([ = b4_percent_define_get([[parse.lac.es-capacity-initial]]) < YYMAXDEPTH],
+                   [ ? b4_percent_define_get([[parse.lac.es-capacity-initial]])],
+                   [ : YYMAXDEPTH])])[;]])])
+
+
+m4_define([b4_macro_define],
+[[#]define $1 $2])
+
+m4_define([b4_macro_undef],
+[[#]undef $1])
+
+m4_define([b4_pstate_macro_define],
+[b4_macro_define([$1], [yyps->$1])])
+
+# b4_parse_state_variable_macros(b4_macro_define|b4_macro_undef)
+# --------------------------------------------------------------
+m4_define([b4_parse_state_variable_macros],
+[b4_pure_if([$1([b4_prefix[]nerrs])])
+$1([yystate])
+$1([yyerrstatus])
+$1([yyssa])
+$1([yyss])
+$1([yyssp])
+$1([yyvsa])
+$1([yyvs])
+$1([yyvsp])[]b4_locations_if([
+$1([yylsa])
+$1([yyls])
+$1([yylsp])])
+$1([yystacksize])[]b4_lac_if([
+$1([yyesa])
+$1([yyes])
+$1([yyes_capacity])])])
+
+
 
 
 # _b4_declare_yyparse_push
@@ -231,27 +335,23 @@
 
 typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
 
-]b4_pull_if([b4_function_declare([b4_prefix[parse]], [[int]], b4_parse_param)
-])b4_function_declare([b4_prefix[push_parse]], [[int]],
-  [[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([,
-  [[[int pushed_char]], [[pushed_char]]],
-  [[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([,
-  [[b4_api_PREFIX[LTYPE *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [,
-  b4_parse_param]))
-b4_pull_if([b4_function_declare([b4_prefix[pull_parse]], [[int]],
-  [[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
-  b4_parse_param]))])
-b4_function_declare([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
-                    [[[void]], []])
-b4_function_declare([b4_prefix[pstate_delete]], [[void]],
-                   [[b4_prefix[pstate *ps]], [[ps]]])dnl
-])
+]b4_pull_if([[
+int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);]])[
+int ]b4_prefix[push_parse (]b4_prefix[pstate *ps]b4_pure_if([[,
+                  int pushed_char, ]b4_api_PREFIX[STYPE const *pushed_val]b4_locations_if([[, ]b4_api_PREFIX[LTYPE *pushed_loc]])])b4_user_formals[);
+]b4_pull_if([[int ]b4_prefix[pull_parse (]b4_prefix[pstate *ps]b4_user_formals[);]])[
+]b4_prefix[pstate *]b4_prefix[pstate_new (void);
+void ]b4_prefix[pstate_delete (]b4_prefix[pstate *ps);
+]])
+
 
 # _b4_declare_yyparse
 # -------------------
 # When not the push parser.
 m4_define([_b4_declare_yyparse],
-[b4_function_declare(b4_prefix[parse], [int], b4_parse_param)])
+[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
+]m4_ifdef([b4_start_symbols],
+          [m4_map([_b4_declare_sub_yyparse], m4_defn([b4_start_symbols]))])])
 
 
 # b4_declare_yyparse
@@ -262,19 +362,35 @@
 ])
 
 
+# b4_declare_yyerror_and_yylex
+# ----------------------------
+# Comply with POSIX Yacc.
+# <https://austingroupbugs.net/view.php?id=1388#c5220>
+m4_define([b4_declare_yyerror_and_yylex],
+[b4_posix_if([[#if !defined ]b4_prefix[error && !defined ]b4_api_PREFIX[ERROR_IS_DECLARED
+]b4_function_declare([b4_prefix[error]], void, b4_yyerror_formals)[
+#endif
+#if !defined ]b4_prefix[lex && !defined ]b4_api_PREFIX[LEX_IS_DECLARED
+]b4_function_declare([b4_prefix[lex]], int, b4_yylex_formals)[
+#endif
+]])dnl
+])
+
+
 # b4_shared_declarations
 # ----------------------
-# Declaration that might either go into the header (if --defines)
-# or open coded in the parser body.
+# Declarations that might either go into the header (if --header)
+# or into the implementation file.
 m4_define([b4_shared_declarations],
-[b4_cpp_guard_open([b4_spec_header_file])[
+[b4_cpp_guard_open([b4_spec_mapped_header_file])[
 ]b4_declare_yydebug[
 ]b4_percent_code_get([[requires]])[
 ]b4_token_enums_defines[
 ]b4_declare_yylstype[
+]b4_declare_yyerror_and_yylex[
 ]b4_declare_yyparse[
 ]b4_percent_code_get([[provides]])[
-]b4_cpp_guard_close([b4_spec_header_file])[]dnl
+]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
 ])
 
 
@@ -289,7 +405,7 @@
                                    [$2])],
           [$2])])
 
-m4_if(b4_spec_header_file, [[y.tab.h]],
+m4_if(b4_spec_header_file, [y.tab.h], [],
       [b4_percent_define_default([[api.header.include]],
                                  [["@basename(]b4_spec_header_file[@)"]])])
 
@@ -301,19 +417,20 @@
 ## -------------- ##
 
 
-b4_defines_if([[
+b4_header_if([[
 ]b4_output_begin([b4_spec_header_file])[
 ]b4_copyright([Bison interface for Yacc-like parsers in C])[
 ]b4_disclaimer[
 ]b4_shared_declarations[
 ]b4_output_end[
-]])# b4_defines_if
+]])# b4_header_if
 
 b4_output_begin([b4_parser_file_name])[
 ]b4_copyright([Bison implementation for Yacc-like parsers in C])[
 /* C LALR(1) parser skeleton written by Richard Stallman, by
    simplifying the original so-called "semantic" parser.  */
 
+]b4_disclaimer[
 /* All symbols defined below should begin with yy or YY, to avoid
    infringing on user name space.  This should be done even for local
    variables, as they might otherwise be expanded by user macros.
@@ -321,7 +438,6 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
-]b4_disclaimer[
 ]b4_identification[
 ]b4_percent_code_get([[top]])[]dnl
 m4_if(b4_api_prefix, [yy], [],
@@ -334,6 +450,7 @@
 #define yypush_parse    ]b4_prefix[push_parse]b4_pull_if([[
 #define yypull_parse    ]b4_prefix[pull_parse]])[
 #define yypstate_new    ]b4_prefix[pstate_new
+#define yypstate_clear  ]b4_prefix[pstate_clear
 #define yypstate_delete ]b4_prefix[pstate_delete
 #define yypstate        ]b4_prefix[pstate]])[
 #define yylex           ]b4_prefix[lex
@@ -348,65 +465,18 @@
 ]b4_cast_define[
 ]b4_null_define[
 
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
-#endif
-
 ]b4_header_include_if([[#include ]b4_percent_define_get([[api.header.include]])],
                       [m4_ifval(m4_quote(b4_spec_header_file),
                                 [/* Use api.header.include to #include this header
    instead of duplicating it here.  */
 ])b4_shared_declarations])[
+]b4_declare_symbol_enum[
 
 ]b4_user_post_prologue[
-]b4_percent_code_get[]dnl
-
-[#ifdef short
-# undef short
-#endif
-
+]b4_percent_code_get[
 ]b4_c99_int_type_define[
 
-#ifndef YYPTRDIFF_T
-# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
-#  define YYPTRDIFF_T __PTRDIFF_TYPE__
-#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
-# elif defined PTRDIFF_MAX
-#  ifndef ptrdiff_t
-#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  endif
-#  define YYPTRDIFF_T ptrdiff_t
-#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
-# else
-#  define YYPTRDIFF_T long
-#  define YYPTRDIFF_MAXIMUM LONG_MAX
-# endif
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM                                  \
-  YY_CAST (YYPTRDIFF_T,                                 \
-           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
-            ? YYPTRDIFF_MAXIMUM                         \
-            : YY_CAST (YYSIZE_T, -1)))
-
-#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+]b4_sizes_types_define[
 
 /* Stored state numbers (used for stacks). */
 typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t;
@@ -425,6 +495,11 @@
 #  define YY_(Msgid) Msgid
 # endif
 #endif
+]b4_has_translations_if([
+#ifndef N_
+# define N_(Msgid) Msgid
+#endif
+])[
 
 ]b4_attribute_define[
 
@@ -437,7 +512,7 @@
 ]],
 [[#define YY_ASSERT(E) ((void) (0 && (E)))]])[
 
-#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
+#if ]b4_lac_if([[1]], [b4_parse_error_case([simple], [[!defined yyoverflow]], [[1]])])[
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */]dnl
 b4_push_if([], [b4_lac_if([], [[
@@ -504,8 +579,7 @@
 #  endif
 # endif]b4_lac_if([[
 # define YYCOPY_NEEDED 1]])[
-#endif]b4_lac_if([], [[ /* ! defined yyoverflow || YYERROR_VERBOSE */]])[
-
+#endif /* ]b4_lac_if([[1]], [b4_parse_error_case([simple], [[!defined yyoverflow]], [[1]])])[ */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
@@ -588,16 +662,18 @@
 /* YYNSTATES -- Number of states.  */
 #define YYNSTATES  ]b4_states_number[
 
-#define YYUNDEFTOK  ]b4_undef_token_number[
-#define YYMAXUTOK   ]b4_user_token_number_max[
+/* YYMAXUTOK -- Last valid token kind.  */
+#define YYMAXUTOK   ]b4_code_max[
 
 
 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
    as returned by yylex, with out-of-bounds checking.  */
 ]b4_api_token_raw_if(dnl
-[[#define YYTRANSLATE(YYX) (YYX)]],
-[[#define YYTRANSLATE(YYX)                                                \
-  (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+[[#define YYTRANSLATE(YYX) YY_CAST (yysymbol_kind_t, YYX)]],
+[[#define YYTRANSLATE(YYX)                                \
+  (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
+   ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
+   : ]b4_symbol_prefix[YYUNDEF)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
    as returned by yylex.  */
@@ -611,23 +687,46 @@
      [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
 #endif
 
-#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+/** Accessing symbol of state STATE.  */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
+
+#if ]b4_parse_error_case([simple], [b4_api_PREFIX[DEBUG || ]b4_token_table_flag], [[1]])[
+/* The user-facing name of the symbol whose (internal) number is
+   YYSYMBOL.  No bounds checking.  */
+static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+]b4_parse_error_bmatch([simple\|verbose],
+[[/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
   ]b4_tname[
 };
-#endif
 
-# ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
-   (internal) symbol number NUM (which must be that of a token).  */
-static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
+static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
 {
-  ]b4_toknum[
-};
-# endif
+  return yytname[yysymbol];
+}]],
+[[static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+  static const char *const yy_sname[] =
+  {
+  ]b4_symbol_names[
+  };]b4_has_translations_if([[
+  /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+     internationalizable.  */
+  static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
+  {
+  ]b4_translatable[
+  };
+  return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
+          ? _(yy_sname[yysymbol])
+          : yy_sname[yysymbol]);]], [[
+  return yy_sname[yysymbol];]])[
+}]])[
+#endif
 
 #define YYPACT_NINF (]b4_pact_ninf[)
 
@@ -641,21 +740,22 @@
 
 ]b4_parser_tables_define[
 
+enum { YYENOMEM = -2 };
+
 #define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
+#define yyclearin       (yychar = ]b4_symbol(empty, id)[)
 
 #define YYACCEPT        goto yyacceptlab
 #define YYABORT         goto yyabortlab
 #define YYERROR         goto yyerrorlab
+#define YYNOMEM         goto yyexhaustedlab
 
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
 #define YYBACKUP(Token, Value)                                    \
   do                                                              \
-    if (yychar == YYEMPTY)                                        \
+    if (yychar == ]b4_symbol(empty, id)[)                                        \
       {                                                           \
         yychar = (Token);                                         \
         yylval = (Value);                                         \
@@ -671,10 +771,9 @@
       }                                                           \
   while (0)
 
-/* Error token number */
-#define YYTERROR        1
-#define YYERRCODE       256
-
+/* Backward compatibility with an undocumented macro.
+   Use ]b4_symbol(error, id)[ or ]b4_symbol(undef, id)[. */
+#define YYERRCODE ]b4_symbol(undef, id)[
 ]b4_locations_if([[
 ]b4_yylloc_default_define[
 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
@@ -694,15 +793,15 @@
     YYFPRINTF Args;                             \
 } while (0)
 
-]b4_yy_location_print_define[
+]b4_yylocation_print_define[
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                    \
 do {                                                                      \
   if (yydebug)                                                            \
     {                                                                     \
       YYFPRINTF (stderr, "%s ", Title);                                   \
       yy_symbol_print (stderr,                                            \
-                  Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
+                  Kind, Value]b4_locations_if([, Location])[]b4_user_args[); \
       YYFPRINTF (stderr, "\n");                                           \
     }                                                                     \
 } while (0)
@@ -714,9 +813,8 @@
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-]b4_function_define([yy_stack_print], [static void],
-                   [[yy_state_t *yybottom], [yybottom]],
-                   [[yy_state_t *yytop],    [yytop]])[
+static void
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -738,12 +836,9 @@
 | Report that the YYRULE is going to be reduced.  |
 `------------------------------------------------*/
 
-]b4_function_define([yy_reduce_print], [static void],
-                   [[yy_state_t *yyssp], [yyssp]],
-                   [[YYSTYPE *yyvsp], [yyvsp]],
-    b4_locations_if([[[YYLTYPE *yylsp], [yylsp]],
-                   ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
-                   b4_parse_param]))[
+static void
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,]b4_locations_if([[ YYLTYPE *yylsp,]])[
+                 int yyrule]b4_user_formals[)
 {
   int yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
@@ -755,10 +850,9 @@
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
-                       yystos[yyssp[yyi + 1 - yynrhs]],
-                       &]b4_rhs_value(yynrhs, yyi + 1)[
-                       ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
-                       b4_user_args[);
+                       YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
+                       &]b4_rhs_value(yynrhs, yyi + 1)[]b4_locations_if([,
+                       &]b4_rhs_location(yynrhs, yyi + 1))[]b4_user_args[);
       YYFPRINTF (stderr, "\n");
     }
 }
@@ -773,8 +867,8 @@
    multiple parsers can coexist.  */
 int yydebug;
 #else /* !]b4_api_PREFIX[DEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YYDPRINTF(Args) ((void) 0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
 # define YY_STACK_PRINT(Bottom, Top)
 # define YY_REDUCE_PRINT(Rule)
 #endif /* !]b4_api_PREFIX[DEBUG */
@@ -794,7 +888,18 @@
 
 #ifndef YYMAXDEPTH
 # define YYMAXDEPTH ]b4_stack_depth_max[
-#endif]b4_lac_if([[
+#endif]b4_push_if([[
+/* Parser data structure.  */
+struct yypstate
+  {]b4_declare_parser_state_variables[
+    /* Whether this instance has not started parsing yet.
+     * If 2, it corresponds to a finished parsing.  */
+    int yynew;
+  };]b4_pure_if([], [[
+
+/* Whether the only allowed instance of yypstate is allocated.  */
+static char yypstate_allocated = 0;]])])[
+]b4_lac_if([[
 
 /* Given a state stack such that *YYBOTTOM is its bottom, such that
    *YYTOP is either its top or is YYTOP_EMPTY to indicate an empty
@@ -805,7 +910,7 @@
    *YYTOP, and *YYCAPACITY to reflect the new capacity and memory
    location.  If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack
    using YYSTACK_FREE.  Return 0 if successful or if no reallocation is
-   required.  Return 1 if memory is exhausted.  */
+   required.  Return YYENOMEM if memory is exhausted.  */
 static int
 yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd,
 #if ]b4_api_PREFIX[DEBUG
@@ -830,7 +935,7 @@
         {
           YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix,
                       yydebug_suffix));
-          return 1;
+          return YYENOMEM;
         }
       if (YYMAXDEPTH < yyalloc)
         yyalloc = YYMAXDEPTH;
@@ -842,7 +947,7 @@
         {
           YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix,
                       yydebug_suffix));
-          return 1;
+          return YYENOMEM;
         }
       if (*yytop != yytop_empty)
         {
@@ -888,23 +993,22 @@
    current lookahead, then check if that lookahead can eventually be
    shifted if syntactic actions continue from the current context.
    Report a syntax error if it cannot.  */
-#define YY_LAC_ESTABLISH                                         \
-do {                                                             \
-  if (!yy_lac_established)                                       \
-    {                                                            \
-      YYDPRINTF ((stderr,                                        \
-                  "LAC: initial context established for %s\n",   \
-                  yytname[yytoken]));                            \
-      yy_lac_established = 1;                                    \
-      {                                                          \
-        int yy_lac_status =                                      \
-          yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken); \
-        if (yy_lac_status == 2)                                  \
-          goto yyexhaustedlab;                                   \
-        if (yy_lac_status == 1)                                  \
-          goto yyerrlab;                                         \
-      }                                                          \
-    }                                                            \
+#define YY_LAC_ESTABLISH                                                \
+do {                                                                    \
+  if (!yy_lac_established)                                              \
+    {                                                                   \
+      YYDPRINTF ((stderr,                                               \
+                  "LAC: initial context established for %s\n",          \
+                  yysymbol_name (yytoken)));                            \
+      yy_lac_established = 1;                                           \
+      switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken))    \
+        {                                                               \
+        case YYENOMEM:                                                  \
+          YYNOMEM;                                                      \
+        case 1:                                                         \
+          goto yyerrlab;                                                \
+        }                                                               \
+    }                                                                   \
 } while (0)
 
 /* Discard any previous initial lookahead context because of Event,
@@ -923,9 +1027,8 @@
 do {                                                                     \
   if (yy_lac_established)                                                \
     {                                                                    \
-      if (yydebug)                                                       \
-        YYFPRINTF (stderr, "LAC: initial context discarded due to "      \
-                   Event "\n");                                          \
+      YYDPRINTF ((stderr, "LAC: initial context discarded due to "       \
+                  Event "\n"));                                          \
       yy_lac_established = 0;                                            \
     }                                                                    \
 } while (0)
@@ -935,7 +1038,7 @@
 
 /* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can
    eventually (after perhaps some reductions) be shifted, return 1 if
-   not, or return 2 if memory is exhausted.  As preconditions and
+   not, or return YYENOMEM if memory is exhausted.  As preconditions and
    postconditions: *YYES_CAPACITY is the allocated size of the array to
    which *YYES points, and either *YYES = YYESA or *YYES points to an
    array allocated with YYSTACK_ALLOC.  yy_lac may overwrite the
@@ -943,24 +1046,26 @@
    any old *YYES other than YYESA.  */
 static int
 yy_lac (yy_state_t *yyesa, yy_state_t **yyes,
-        YYPTRDIFF_T *yyes_capacity, yy_state_t *yyssp, int yytoken)
+        YYPTRDIFF_T *yyes_capacity, yy_state_t *yyssp, yysymbol_kind_t yytoken)
 {
   yy_state_t *yyes_prev = yyssp;
   yy_state_t *yyesp = yyes_prev;
-  YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yytname[yytoken]));
-  if (yytoken == YYUNDEFTOK)
+  /* Reduce until we encounter a shift and thereby accept the token.  */
+  YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yysymbol_name (yytoken)));
+  if (yytoken == ]b4_symbol_prefix[YYUNDEF)
     {
       YYDPRINTF ((stderr, " Always Err\n"));
       return 1;
     }
   while (1)
     {
-      int yyrule = yypact[*yyesp];
+      int yyrule = yypact[+*yyesp];
       if (yypact_value_is_default (yyrule)
           || (yyrule += yytoken) < 0 || YYLAST < yyrule
           || yycheck[yyrule] != yytoken)
         {
-          yyrule = yydefact[*yyesp];
+          /* Use the default action.  */
+          yyrule = yydefact[+*yyesp];
           if (yyrule == 0)
             {
               YYDPRINTF ((stderr, " Err\n"));
@@ -969,6 +1074,7 @@
         }
       else
         {
+          /* Use the action from yytable.  */
           yyrule = yytable[yyrule];
           if (yytable_value_is_error (yyrule))
             {
@@ -982,9 +1088,12 @@
             }
           yyrule = -yyrule;
         }
+      /* By now we know we have to simulate a reduce.  */
+      YYDPRINTF ((stderr, " R%d", yyrule - 1));
       {
+        /* Pop the corresponding number of values from the stack.  */
         YYPTRDIFF_T yylen = yyr2[yyrule];
-        YYDPRINTF ((stderr, " R%d", yyrule - 1));
+        /* First pop from the LAC stack as many tokens as possible.  */
         if (yyesp != yyes_prev)
           {
             YYPTRDIFF_T yysize = yyesp - *yyes + 1;
@@ -995,13 +1104,15 @@
               }
             else
               {
-                yylen -= yysize;
                 yyesp = yyes_prev;
+                yylen -= yysize;
               }
           }
+        /* Only afterwards look at the main stack.  */
         if (yylen)
           yyesp = yyes_prev -= yylen;
       }
+      /* Push the resulting state of the reduction.  */
       {
         yy_state_fast_t yystate;
         {
@@ -1027,7 +1138,7 @@
                                       yyes, yyesa, &yyesp, yyes_prev))
               {
                 YYDPRINTF ((stderr, "\n"));
-                return 2;
+                return YYENOMEM;
               }
             YY_IGNORE_USELESS_CAST_BEGIN
             *++yyesp = YY_CAST (yy_state_t, yystate);
@@ -1038,33 +1149,144 @@
     }
 }]])[
 
+]b4_parse_error_case([simple], [],
+[[/* Context of a parse error.  */
+typedef struct
+{]b4_push_if([[
+  yypstate* yyps;]], [[
+  yy_state_t *yyssp;]b4_lac_if([[
+  yy_state_t *yyesa;
+  yy_state_t **yyes;
+  YYPTRDIFF_T *yyes_capacity;]])])[
+  yysymbol_kind_t yytoken;]b4_locations_if([[
+  YYLTYPE *yylloc;]])[
+} yypcontext_t;
 
-#if YYERROR_VERBOSE
+/* Put in YYARG at most YYARGN of the expected tokens given the
+   current YYCTX, and return the number of tokens stored in YYARG.  If
+   YYARG is null, return the number of expected tokens (guaranteed to
+   be less than YYNTOKENS).  Return YYENOMEM on memory exhaustion.
+   Return 0 if there are more than YYARGN expected tokens, yet fill
+   YYARG up to YYARGN. */]b4_push_if([[
+static int
+yypstate_expected_tokens (yypstate *yyps,
+                          yysymbol_kind_t yyarg[], int yyargn)]], [[
+static int
+yypcontext_expected_tokens (const yypcontext_t *yyctx,
+                            yysymbol_kind_t yyarg[], int yyargn)]])[
+{
+  /* Actual size of YYARG. */
+  int yycount = 0;
+]b4_lac_if([[
+  int yyx;
+  for (yyx = 0; yyx < YYNTOKENS; ++yyx)
+    {
+      yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx);
+      if (yysym != ]b4_symbol(error, kind)[ && yysym != ]b4_symbol_prefix[YYUNDEF)
+        switch (yy_lac (]b4_push_if([[yyps->yyesa, &yyps->yyes, &yyps->yyes_capacity, yyps->yyssp, yysym]],
+                                    [[yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym]])[))
+          {
+          case YYENOMEM:
+            return YYENOMEM;
+          case 1:
+            continue;
+          default:
+            if (!yyarg)
+              ++yycount;
+            else if (yycount == yyargn)
+              return 0;
+            else
+              yyarg[yycount++] = yysym;
+          }
+    }]],
+[[  int yyn = yypact@{+*]b4_push_if([yyps], [yyctx])[->yyssp@};
+  if (!yypact_value_is_default (yyn))
+    {
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+         YYCHECK.  In other words, skip the first -YYN actions for
+         this state because they are default actions.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yyx;
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+        if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+            && !yytable_value_is_error (yytable[yyx + yyn]))
+          {
+            if (!yyarg)
+              ++yycount;
+            else if (yycount == yyargn)
+              return 0;
+            else
+              yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
+          }
+    }]])[
+  if (yyarg && yycount == 0 && 0 < yyargn)
+    yyarg[0] = ]b4_symbol(empty, kind)[;
+  return yycount;
+}
 
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
-#  else
+]b4_push_if([[
+/* Similar to the previous function.  */
+static int
+yypcontext_expected_tokens (const yypcontext_t *yyctx,
+                            yysymbol_kind_t yyarg[], int yyargn)
+{
+  return yypstate_expected_tokens (yyctx->yyps, yyarg, yyargn);
+}]])[
+]])[
+
+]b4_parse_error_bmatch(
+         [custom],
+[[/* The kind of the lookahead of this context.  */
+static yysymbol_kind_t
+yypcontext_token (const yypcontext_t *yyctx) YY_ATTRIBUTE_UNUSED;
+
+static yysymbol_kind_t
+yypcontext_token (const yypcontext_t *yyctx)
+{
+  return yyctx->yytoken;
+}
+
+]b4_locations_if([[/* The location of the lookahead of this context.  */
+static YYLTYPE *
+yypcontext_location (const yypcontext_t *yyctx) YY_ATTRIBUTE_UNUSED;
+
+static YYLTYPE *
+yypcontext_location (const yypcontext_t *yyctx)
+{
+  return yyctx->yylloc;
+}]])[
+
+/* User defined function to report a syntax error.  */
+static int
+yyreport_syntax_error (const yypcontext_t *yyctx]b4_user_formals[);]],
+         [detailed\|verbose],
+[[#ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+#  define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
+# else
 /* Return the length of YYSTR.  */
-]b4_function_define([yystrlen], [static YYPTRDIFF_T],
-   [[const char *yystr], [yystr]])[
+static YYPTRDIFF_T
+yystrlen (const char *yystr)
 {
   YYPTRDIFF_T yylen;
   for (yylen = 0; yystr[yylen]; yylen++)
     continue;
   return yylen;
 }
-#  endif
 # endif
+#endif
 
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
+#ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#  define yystpcpy stpcpy
+# else
 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
    YYDEST.  */
-]b4_function_define([yystpcpy], [static char *],
-   [[char *yydest], [yydest]], [[const char *yysrc], [yysrc]])[
+static char *
+yystpcpy (char *yydest, const char *yysrc)
 {
   char *yyd = yydest;
   const char *yys = yysrc;
@@ -1074,10 +1296,12 @@
 
   return yyd - 1;
 }
-#  endif
 # endif
+#endif
 
-# ifndef yytnamerr
+]b4_parse_error_case(
+         [verbose],
+[[#ifndef yytnamerr
 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
    quotes and backslashes, so that it's suitable for yyerror.  The
    heuristic is that double-quoting is unnecessary unless the string
@@ -1092,7 +1316,6 @@
     {
       YYPTRDIFF_T yyn = 0;
       char const *yyp = yystr;
-
       for (;;)
         switch (*++yyp)
           {
@@ -1126,34 +1349,15 @@
   else
     return yystrlen (yystr);
 }
-# endif
+#endif
+]])[
 
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.]b4_lac_if([[  In order to see if a particular token T is a
-   valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T).]])[
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store]b4_lac_if([[ or if
-   yy_lac returned 2]])[.  */
 static int
-yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
-                ]b4_lac_if([[yy_state_t *yyesa, yy_state_t **yyes,
-                YYPTRDIFF_T *yyes_capacity, ]])[yy_state_t *yyssp, int yytoken)
+yy_syntax_error_arguments (const yypcontext_t *yyctx,
+                           yysymbol_kind_t yyarg[], int yyargn)
 {
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat: reported tokens (one for the "unexpected",
-     one per "expected"). */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
   /* Actual size of YYARG. */
   int yycount = 0;
-  /* Cumulated lengths of YYARG.  */
-  YYPTRDIFF_T yysize = 0;
-
   /* There are many possibilities here to consider:
      - If this state is a consistent state with a default action, then
        the only way this function was invoked is if the default action
@@ -1182,70 +1386,59 @@
        one exception: it will still contain any token that will not be
        accepted due to an error action in a later state.]])[
   */
-  if (yytoken != YYEMPTY)
+  if (yyctx->yytoken != ]b4_symbol(empty, kind)[)
     {
-      int yyn = yypact[*yyssp];
-      YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
-      yysize = yysize0;]b4_lac_if([[
+      int yyn;]b4_lac_if([[
       YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {]b4_lac_if([[
-          int yyx;
-
-          for (yyx = 0; yyx < YYNTOKENS; ++yyx)
-            if (yyx != YYTERROR && yyx != YYUNDEFTOK)
-              {
-                {
-                  int yy_lac_status = yy_lac (yyesa, yyes, yyes_capacity,
-                                              yyssp, yyx);
-                  if (yy_lac_status == 2)
-                    return 2;
-                  if (yy_lac_status == 1)
-                    continue;
-                }]], [[
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {]])[
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYPTRDIFF_T yysize1
-                    = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
-                    yysize = yysize1;
-                  else
-                    return 2;
-                }
-              }
-        }]b4_lac_if([[
-# if ]b4_api_PREFIX[DEBUG
-      else if (yydebug)
-        YYFPRINTF (stderr, "No expected tokens.\n");
-# endif]])[
+      if (yyarg)
+        yyarg[yycount] = yyctx->yytoken;
+      ++yycount;
+      yyn = yypcontext_expected_tokens (yyctx,
+                                        yyarg ? yyarg + 1 : yyarg, yyargn - 1);
+      if (yyn == YYENOMEM)
+        return YYENOMEM;]b4_lac_if([[
+      else if (yyn == 0)
+        YYDPRINTF ((stderr, "No expected tokens.\n"));]])[
+      else
+        yycount += yyn;
     }
+  return yycount;
+}
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.]b4_lac_if([[  In order to see if a particular token T is a
+   valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T).]])[
+
+   Return 0 if *YYMSG was successfully written.  Return -1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return YYENOMEM if the
+   required number of bytes is too large to store]b4_lac_if([[ or if
+   yy_lac returned YYENOMEM]])[.  */
+static int
+yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
+                const yypcontext_t *yyctx)
+{
+  enum { YYARGS_MAX = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat: reported tokens (one for the "unexpected",
+     one per "expected"). */
+  yysymbol_kind_t yyarg[YYARGS_MAX];
+  /* Cumulated lengths of YYARG.  */
+  YYPTRDIFF_T yysize = 0;
+
+  /* Actual size of YYARG. */
+  int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX);
+  if (yycount == YYENOMEM)
+    return YYENOMEM;
 
   switch (yycount)
     {
-# define YYCASE_(N, S)                      \
+#define YYCASE_(N, S)                       \
       case N:                               \
         yyformat = S;                       \
-      break
+        break
     default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
@@ -1253,17 +1446,25 @@
       YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
       YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
       YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
+#undef YYCASE_
     }
 
+  /* Compute error message size.  Don't count the "%s"s, but reserve
+     room for the terminator.  */
+  yysize = yystrlen (yyformat) - 2 * yycount + 1;
   {
-    /* Don't count the "%s"s in the final size, but reserve room for
-       the terminator.  */
-    YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1;
-    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
-      yysize = yysize1;
-    else
-      return 2;
+    int yyi;
+    for (yyi = 0; yyi < yycount; ++yyi)
+      {
+        YYPTRDIFF_T yysize1
+          = yysize + ]b4_parse_error_case(
+                              [verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]],
+                              [[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
+        if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+          yysize = yysize1;
+        else
+          return YYENOMEM;
+      }
   }
 
   if (*yymsg_alloc < yysize)
@@ -1272,7 +1473,7 @@
       if (! (yysize <= *yymsg_alloc
              && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
         *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
+      return -1;
     }
 
   /* Avoid sprintf, as that infringes on the user's name space.
@@ -1283,8 +1484,9 @@
     int yyi = 0;
     while ((*yyp = *yyformat) != '\0')
       if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
+        {]b4_parse_error_case([verbose], [[
+          yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]);]], [[
+          yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++]));]])[
           yyformat += 2;
         }
       else
@@ -1295,153 +1497,175 @@
   }
   return 0;
 }
-#endif /* YYERROR_VERBOSE */
+]])[
 
 ]b4_yydestruct_define[
 
-]b4_pure_if([], [
+]b4_pure_if([], [b4_declare_scanner_communication_variables])[
 
-b4_declare_scanner_communication_variables])[]b4_push_if([[
+]b4_push_if([b4_pull_if([[
 
-struct yypstate
-  {]b4_declare_parser_state_variables[
-    /* Used to determine if this is the first time this instance has
-       been used.  */
-    int yynew;
-  };]b4_pure_if([], [[
-
-static char yypstate_allocated = 0;]])b4_pull_if([
-
-b4_function_define([[yyparse]], [[int]], b4_parse_param)[
+int
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
 {
-  return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param],
-                                  [[, ]b4_args(b4_parse_param)])[);
+  yypstate *yyps = yypstate_new ();
+  if (!yyps)
+    {]b4_pure_if([b4_locations_if([[
+      static YYLTYPE yyloc_default][]b4_yyloc_default[;
+      YYLTYPE yylloc = yyloc_default;]])[
+      yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
+      if (!yypstate_allocated)
+        yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
+      return 2;
+    }
+  int yystatus = yypull_parse (yyps]b4_user_args[);
+  yypstate_delete (yyps);
+  return yystatus;
 }
 
-]b4_function_define([[yypull_parse]], [[int]],
-  [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
-  b4_parse_param]))[
-{]b4_pure_if([b4_locations_if([[
+int
+yypull_parse (yypstate *yyps]b4_user_formals[)
+{
+  YY_ASSERT (yyps);]b4_pure_if([b4_locations_if([[
   static YYLTYPE yyloc_default][]b4_yyloc_default[;
   YYLTYPE yylloc = yyloc_default;]])])[
-  yypstate *yyps_local;
-  if (yyps)
-    yyps_local = yyps;
-  else
-    {
-      yyps_local = yypstate_new ();
-      if (!yyps_local)
-        {]b4_pure_if([[
-          yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
-          if (!yypstate_allocated)
-            yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
-          return 2;
-        }
-    }
   int yystatus;
-  do {]b4_pure_if([[
-    YYSTYPE yylval;
-    int ]])[yychar = ]b4_lex[;
-    yystatus =
-      yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
+  do {
+]b4_pure_if([[    YYSTYPE yylval;
+    int ]])[yychar = ]b4_yylex[;
+    yystatus = yypush_parse (yyps]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
   } while (yystatus == YYPUSH_MORE);
-  if (!yyps)
-    yypstate_delete (yyps_local);
   return yystatus;
 }]])[
 
+]b4_parse_state_variable_macros([b4_pstate_macro_define])[
+
 /* Initialize the parser data structure.  */
-]b4_function_define([[yypstate_new]], [[yypstate *]])[
+static void
+yypstate_clear (yypstate *yyps)
+{
+  yynerrs = 0;
+  yystate = 0;
+  yyerrstatus = 0;
+
+  yyssp = yyss;
+  yyvsp = yyvs;]b4_locations_if([[
+  yylsp = yyls;]])[
+
+  /* Initialize the state stack, in case yypcontext_expected_tokens is
+     called before the first call to yyparse. */
+  *yyssp = 0;
+  yyps->yynew = 1;
+}
+
+/* Initialize the parser data structure.  */
+yypstate *
+yypstate_new (void)
 {
   yypstate *yyps;]b4_pure_if([], [[
   if (yypstate_allocated)
     return YY_NULLPTR;]])[
-  yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
+  yyps = YY_CAST (yypstate *, YYMALLOC (sizeof *yyps));
   if (!yyps)
-    return YY_NULLPTR;
-  yyps->yynew = 1;]b4_pure_if([], [[
+    return YY_NULLPTR;]b4_pure_if([], [[
   yypstate_allocated = 1;]])[
+  yystacksize = YYINITDEPTH;
+  yyss = yyssa;
+  yyvs = yyvsa;]b4_locations_if([[
+  yyls = yylsa;]])[]b4_lac_if([[
+  yyes = yyesa;
+  yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
+  if (YYMAXDEPTH < yyes_capacity)
+    yyes_capacity = YYMAXDEPTH;]])[
+  yypstate_clear (yyps);
   return yyps;
 }
 
-]b4_function_define([[yypstate_delete]], [[void]],
-                   [[[yypstate *yyps]], [[yyps]]])[
+void
+yypstate_delete (yypstate *yyps)
 {
   if (yyps)
     {
 #ifndef yyoverflow
       /* If the stack was reallocated but the parse did not complete, then the
          stack still needs to be freed.  */
-      if (!yyps->yynew && yyps->yyss != yyps->yyssa)
-        YYSTACK_FREE (yyps->yyss);
+      if (yyss != yyssa)
+        YYSTACK_FREE (yyss);
 #endif]b4_lac_if([[
-      if (!yyps->yynew && yyps->yyes != yyps->yyesa)
-        YYSTACK_FREE (yyps->yyes);]])[
-      free (yyps);]b4_pure_if([], [[
+      if (yyes != yyesa)
+        YYSTACK_FREE (yyes);]])[
+      YYFREE (yyps);]b4_pure_if([], [[
       yypstate_allocated = 0;]])[
     }
 }
-]b4_pure_if([[
-#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs]])[
-#define yystate yyps->yystate
-#define yyerrstatus yyps->yyerrstatus
-#define yyssa yyps->yyssa
-#define yyss yyps->yyss
-#define yyssp yyps->yyssp
-#define yyvsa yyps->yyvsa
-#define yyvs yyps->yyvs
-#define yyvsp yyps->yyvsp]b4_locations_if([[
-#define yylsa yyps->yylsa
-#define yyls yyps->yyls
-#define yylsp yyps->yylsp
-#define yyerror_range yyps->yyerror_range]])[
-#define yystacksize yyps->yystacksize]b4_lac_if([[
-#define yyesa yyps->yyesa
-#define yyes yyps->yyes
-#define yyes_capacity yyps->yyes_capacity]])[
+]])[
 
-
+]b4_push_if([[
 /*---------------.
 | yypush_parse.  |
 `---------------*/
 
-]b4_function_define([[yypush_parse]], [[int]],
-  [[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
-  [[[int yypushed_char]], [[yypushed_char]]],
-  [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
-  [[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
-  b4_parse_param]))], [[
-
-
+int
+yypush_parse (yypstate *yyps]b4_pure_if([[,
+              int yypushed_char, YYSTYPE const *yypushed_val]b4_locations_if([[, YYLTYPE *yypushed_loc]])])b4_user_formals[)]],
+[[
 /*----------.
 | yyparse.  |
 `----------*/
 
-]b4_function_define([yyparse], [int], b4_parse_param)])[
+]m4_ifdef([b4_start_symbols],
+[[// Extract data from the parser.
+typedef struct
+{
+  YYSTYPE yyvalue;
+  int yynerrs;
+} yy_parse_impl_t;
+
+// Run a full parse, using YYCHAR as switching token.
+static int
+yy_parse_impl (int yychar, yy_parse_impl_t *yyimpl]m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])[);
+
+]m4_map([_b4_define_sub_yyparse], m4_defn([b4_start_symbols]))[
+
+int
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
+{
+  return yy_parse_impl (]b4_symbol(_b4_first_switching_token, id)[, YY_NULLPTR]m4_ifset([b4_parse_param],
+                                                    [[, ]b4_args(b4_parse_param)])[);
+}
+
+static int
+yy_parse_impl (int yychar, yy_parse_impl_t *yyimpl]m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])[)]],
+[[int
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])])[
 {]b4_pure_if([b4_declare_scanner_communication_variables
 ])b4_push_if([b4_pure_if([], [[
   int yypushed_char = yychar;
   YYSTYPE yypushed_val = yylval;]b4_locations_if([[
   YYLTYPE yypushed_loc = yylloc;]])
 ])],
-  [b4_declare_parser_state_variables
+  [b4_declare_parser_state_variables([init])
 ])b4_lac_if([[
+  /* Whether LAC context is established.  A Boolean.  */
   int yy_lac_established = 0;]])[
   int yyn;
+  /* The return value of yyparse.  */
   int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken = 0;
+  /* Lookahead symbol kind.  */
+  yysymbol_kind_t yytoken = ]b4_symbol(empty, kind)[;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;]b4_locations_if([[
-  YYLTYPE yyloc;]])[
+  YYLTYPE yyloc;
 
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
+  /* The locations where the error started and ended.  */
+  YYLTYPE yyerror_range[3];]])[
+
+]b4_parse_error_bmatch([detailed\|verbose],
+[[  /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
   char *yymsg = yymsgbuf;
-  YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;
-#endif
+  YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;]])[
 
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
 
@@ -1449,28 +1673,25 @@
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;]b4_push_if([[
 
-  if (!yyps->yynew)
+  switch (yyps->yynew)
     {
+    case 0:
       yyn = yypact[yystate];
       goto yyread_pushed_token;
+
+    case 2:
+      yypstate_clear (yyps);
+      break;
+
+    default:
+      break;
     }]])[
 
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;]b4_locations_if([[
-  yylsp = yyls = yylsa;]])[
-  yystacksize = YYINITDEPTH;]b4_lac_if([[
-
-  yyes = yyesa;
-  yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
-  if (YYMAXDEPTH < yyes_capacity)
-    yyes_capacity = YYMAXDEPTH;]])[
-
   YYDPRINTF ((stderr, "Starting parse\n"));
 
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
+]m4_ifdef([b4_start_symbols], [],
+[[  yychar = ]b4_symbol(empty, id)[; /* Cause a token to be read.  */
+]])[
 ]m4_ifdef([b4_initial_action], [
 b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
                   [b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
@@ -1501,10 +1722,11 @@
   YY_IGNORE_USELESS_CAST_BEGIN
   *yyssp = YY_CAST (yy_state_t, yystate);
   YY_IGNORE_USELESS_CAST_END
+  YY_STACK_PRINT (yyss, yyssp);
 
   if (yyss + yystacksize - 1 <= yyssp)
 #if !defined yyoverflow && !defined YYSTACK_RELOCATE
-    goto yyexhaustedlab;
+    YYNOMEM;
 #else
     {
       /* Get the current used size of the three stacks, in elements.  */
@@ -1535,7 +1757,7 @@
 # else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-        goto yyexhaustedlab;
+        YYNOMEM;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
         yystacksize = YYMAXDEPTH;
@@ -1546,11 +1768,11 @@
           YY_CAST (union yyalloc *,
                    YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
         if (! yyptr)
-          goto yyexhaustedlab;
+          YYNOMEM;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
         YYSTACK_RELOCATE (yyls_alloc, yyls);])[
-# undef YYSTACK_RELOCATE
+#  undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
@@ -1570,8 +1792,9 @@
     }
 #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
+]m4_ifdef([b4_start_symbols], [], [[
   if (yystate == YYFINAL)
-    YYACCEPT;
+    YYACCEPT;]])[
 
   goto yybackup;
 
@@ -1590,8 +1813,8 @@
 
   /* Not known => get a lookahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
-  if (yychar == YYEMPTY)
+  /* YYCHAR is either empty, or end-of-input, or a valid lookahead.  */
+  if (yychar == ]b4_symbol(empty, id)[)
     {]b4_push_if([[
       if (!yyps->yynew)
         {]b4_use_push_for_pull_if([], [[
@@ -1607,20 +1830,32 @@
       yylval = yypushed_val;]b4_locations_if([[
       yylloc = yypushed_loc;]])])[
 yyread_pushed_token:]])[
-      YYDPRINTF ((stderr, "Reading a token: "));]b4_push_if([b4_pure_if([[
+      YYDPRINTF ((stderr, "Reading a token\n"));]b4_push_if([b4_pure_if([[
       yychar = yypushed_char;
       if (yypushed_val)
         yylval = *yypushed_val;]b4_locations_if([[
       if (yypushed_loc)
         yylloc = *yypushed_loc;]])])], [[
-      yychar = ]b4_lex[;]])[
+      yychar = ]b4_yylex[;]])[
     }
 
-  if (yychar <= YYEOF)
+  if (yychar <= ]b4_symbol(eof, [id])[)
     {
-      yychar = yytoken = YYEOF;
+      yychar = ]b4_symbol(eof, [id])[;
+      yytoken = ]b4_symbol(eof, [kind])[;
       YYDPRINTF ((stderr, "Now at end of input.\n"));
     }
+  else if (yychar == ]b4_symbol(error, [id])[)
+    {
+      /* The scanner already issued an error message, process directly
+         to error recovery.  But do not keep the error token as
+         lookahead, it is too special and may lead us to an endless
+         loop in error recovery. */
+      yychar = ]b4_symbol(undef, [id])[;
+      yytoken = ]b4_symbol(error, [kind])[;]b4_locations_if([[
+      yyerror_range[1] = yylloc;]])[
+      goto yyerrlab1;
+    }
   else
     {
       yytoken = YYTRANSLATE (yychar);
@@ -1640,9 +1875,9 @@
   if (yyn <= 0)
     {
       if (yytable_value_is_error (yyn))
-        goto yyerrlab;]b4_lac_if([[
+        goto yyerrlab;
+      yyn = -yyn;]b4_lac_if([[
       YY_LAC_ESTABLISH;]])[
-      yyn = -yyn;
       goto yyreduce;
     }
 
@@ -1660,7 +1895,7 @@
   *++yylsp = yylloc;])[
 
   /* Discard the shifted token.  */
-  yychar = YYEMPTY;]b4_lac_if([[
+  yychar = ]b4_symbol(empty, id)[;]b4_lac_if([[
   YY_LAC_DISCARD ("shift");]])[
   goto yynewstate;
 
@@ -1723,11 +1958,10 @@
      case of YYERROR or YYBACKUP, subsequent parser actions might lead
      to an incorrect destructor call or verbose syntax error message
      before the lookahead is translated.  */
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+  YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
   yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
 
   *++yyvsp = yyval;]b4_locations_if([
   *++yylsp = yyloc;])[
@@ -1752,69 +1986,76 @@
 yyerrlab:
   /* Make sure we have latest lookahead translation.  See comments at
      user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
+  yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
       ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (]b4_yyerror_args[YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \]b4_lac_if([[
-                                        yyesa, &yyes, &yyes_capacity, \]])[
-                                        yyssp, yytoken)
-      {
+]b4_parse_error_case(
+         [custom],
+[[      {
+        yypcontext_t yyctx
+          = {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};]b4_lac_if([[
+        if (yychar != ]b4_symbol(empty, id)[)
+          YY_LAC_ESTABLISH;]])[
+        if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param],
+                                   [[, ]b4_args(b4_parse_param)])[) == 2)
+          YYNOMEM;
+      }]],
+         [simple],
+[[      yyerror (]b4_yyerror_args[YY_("syntax error"));]],
+[[      {
+        yypcontext_t yyctx
+          = {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};
         char const *yymsgp = YY_("syntax error");
         int yysyntax_error_status;]b4_lac_if([[
-        if (yychar != YYEMPTY)
+        if (yychar != ]b4_symbol(empty, id)[)
           YY_LAC_ESTABLISH;]])[
-        yysyntax_error_status = YYSYNTAX_ERROR;
+        yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx);
         if (yysyntax_error_status == 0)
           yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
+        else if (yysyntax_error_status == -1)
           {
             if (yymsg != yymsgbuf)
               YYSTACK_FREE (yymsg);
-            yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc)));
-            if (!yymsg)
+            yymsg = YY_CAST (char *,
+                             YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc)));
+            if (yymsg)
               {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
+                yysyntax_error_status
+                  = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx);
+                yymsgp = yymsg;
               }
             else
               {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = YYENOMEM;
               }
           }
         yyerror (]b4_yyerror_args[yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
-      }
-# undef YYSYNTAX_ERROR
-#endif
+        if (yysyntax_error_status == YYENOMEM)
+          YYNOMEM;
+      }]])[
     }
-
-]b4_locations_if([[  yyerror_range[1] = yylloc;]])[
-
+]b4_locations_if([[
+  yyerror_range[1] = yylloc;]])[
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
          error, discard it.  */
 
-      if (yychar <= YYEOF)
+      if (yychar <= ]b4_symbol(eof, [id])[)
         {
           /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
+          if (yychar == ]b4_symbol(eof, [id])[)
             YYABORT;
         }
       else
         {
           yydestruct ("Error: discarding",
                       yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
-          yychar = YYEMPTY;
+          yychar = ]b4_symbol(empty, id)[;
         }
     }
 
@@ -1831,6 +2072,7 @@
      label yyerrorlab therefore never appears in user code.  */
   if (0)
     YYERROR;
+  ++yynerrs;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -1847,13 +2089,14 @@
 yyerrlab1:
   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
 
+  /* Pop stack until we find a state that shifts the error token.  */
   for (;;)
     {
       yyn = yypact[yystate];
       if (!yypact_value_is_default (yyn))
         {
-          yyn += YYTERROR;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+          yyn += ]b4_symbol(error, kind)[;
+          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol(error, kind)[)
             {
               yyn = yytable[yyn];
               if (0 < yyn)
@@ -1867,7 +2110,7 @@
 
 ]b4_locations_if([[      yyerror_range[1] = *yylsp;]])[
       yydestruct ("Error: popping",
-                  yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
+                  YY_ACCESSING_SYMBOL (yystate), yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
@@ -1882,13 +2125,11 @@
   YY_IGNORE_MAYBE_UNINITIALIZED_END
 ]b4_locations_if([[
   yyerror_range[2] = yylloc;
-  /* Using YYLLOC is tempting, but would change the location of
-     the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
-  *++yylsp = yyloc;]])[
+  ++yylsp;
+  YYLLOC_DEFAULT (*yylsp, yyerror_range, 2);]])[
 
   /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+  YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
 
   yystate = yyn;
   goto yynewstate;
@@ -1899,7 +2140,7 @@
 `-------------------------------------*/
 yyacceptlab:
   yyresult = 0;
-  goto yyreturn;
+  goto yyreturnlab;
 
 
 /*-----------------------------------.
@@ -1907,25 +2148,23 @@
 `-----------------------------------*/
 yyabortlab:
   yyresult = 1;
-  goto yyreturn;
+  goto yyreturnlab;
 
 
-#if ]b4_lac_if([[1]], [[!defined yyoverflow || YYERROR_VERBOSE]])[
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here.  |
+`-----------------------------------------------------------*/
 yyexhaustedlab:
   yyerror (]b4_yyerror_args[YY_("memory exhausted"));
   yyresult = 2;
-  /* Fall through.  */
-#endif
+  goto yyreturnlab;
 
 
-/*-----------------------------------------------------.
-| yyreturn -- parsing is finished, return the result.  |
-`-----------------------------------------------------*/
-yyreturn:
-  if (yychar != YYEMPTY)
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return.  |
+`----------------------------------------------------------*/
+yyreturnlab:
+  if (yychar != ]b4_symbol(empty, id)[)
     {
       /* Make sure we have latest lookahead translation.  See comments at
          user semantic actions for why this is necessary.  */
@@ -1940,27 +2179,31 @@
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
+                  YY_ACCESSING_SYMBOL (+*yyssp), yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
       YYPOPSTACK (1);
-    }
+    }]b4_push_if([[
+  yyps->yynew = 2;
+  goto yypushreturn;
+
+
+/*-------------------------.
+| yypushreturn -- return.  |
+`-------------------------*/
+yypushreturn:]], [[
 #ifndef yyoverflow
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
 #endif]b4_lac_if([[
   if (yyes != yyesa)
-    YYSTACK_FREE (yyes);]])b4_push_if([[
-  yyps->yynew = 1;
-
-
-/*-----------------------------------------.
-| yypushreturn -- ask for the next token.  |
-`-----------------------------------------*/
-yypushreturn:]])[
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
+    YYSTACK_FREE (yyes);]])])[
+]b4_parse_error_bmatch([detailed\|verbose],
+[[  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);]])[]m4_ifdef([b4_start_symbols], [[
+  if (yyimpl)
+    yyimpl->yynerrs = yynerrs;]])[
   return yyresult;
 }
-]b4_epilogue[]dnl
+]b4_push_if([b4_parse_state_variable_macros([b4_macro_undef])])[
+]b4_percent_code_get([[epilogue]])[]dnl
+b4_epilogue[]dnl
 b4_output_end
diff --git a/common/bison/xslt/bison.xsl b/common/bison/xslt/bison.xsl
index 5c1a358..989a343 100644
--- a/common/bison/xslt/bison.xsl
+++ b/common/bison/xslt/bison.xsl
@@ -3,7 +3,7 @@
 <!--
     bison.xsl - common templates for Bison XSLT.
 
-    Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
+    Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
 
     This file is part of Bison, the GNU Compiler Compiler.
 
@@ -18,12 +18,12 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
   -->
 
 <xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-  xmlns:bison="http://www.gnu.org/software/bison/">
+  xmlns:bison="https://www.gnu.org/software/bison/">
 
 <xsl:key
   name="bison:symbolByName"
diff --git a/common/bison/xslt/xml2dot.xsl b/common/bison/xslt/xml2dot.xsl
index 0a7419f..7715d1a 100644
--- a/common/bison/xslt/xml2dot.xsl
+++ b/common/bison/xslt/xml2dot.xsl
@@ -3,7 +3,7 @@
 <!--
     xml2dot.xsl - transform Bison XML Report into DOT.
 
-    Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
+    Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
 
     This file is part of Bison, the GNU Compiler Compiler.
 
@@ -18,14 +18,14 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
     Written by Wojciech Polak <polak@gnu.org>.
   -->
 
 <xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-  xmlns:bison="http://www.gnu.org/software/bison/">
+  xmlns:bison="https://www.gnu.org/software/bison/">
 
 <xsl:import href="bison.xsl"/>
 <xsl:output method="text" encoding="UTF-8" indent="no"/>
@@ -159,7 +159,7 @@
   <xsl:param name="prev-rule-number"
     select="preceding-sibling::item[1]/@rule-number"/>
   <xsl:apply-templates select="key('bison:ruleByNumber', @rule-number)">
-    <xsl:with-param name="point" select="@point"/>
+    <xsl:with-param name="dot" select="@dot"/>
     <xsl:with-param name="num" select="@rule-number"/>
     <xsl:with-param name="prev-lhs"
       select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
@@ -169,7 +169,7 @@
 </xsl:template>
 
 <xsl:template match="rule">
-  <xsl:param name="point"/>
+  <xsl:param name="dot"/>
   <xsl:param name="num"/>
   <xsl:param name="prev-lhs"/>
   <xsl:text>&#10;</xsl:text>
@@ -198,14 +198,14 @@
       <xsl:text>:</xsl:text>
     </xsl:otherwise>
   </xsl:choose>
-  <xsl:if test="$point = 0">
+  <xsl:if test="$dot = 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()">
+    <xsl:if test="$dot = position()">
       <xsl:text> .</xsl:text>
     </xsl:if>
   </xsl:for-each>
diff --git a/common/bison/xslt/xml2text.xsl b/common/bison/xslt/xml2text.xsl
index 72b56e7..1fc5731 100644
--- a/common/bison/xslt/xml2text.xsl
+++ b/common/bison/xslt/xml2text.xsl
@@ -3,7 +3,7 @@
 <!--
     xml2text.xsl - transform Bison XML Report into plain text.
 
-    Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
+    Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
 
     This file is part of Bison, the GNU Compiler Compiler.
 
@@ -18,14 +18,14 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
     Written by Wojciech Polak <polak@gnu.org>.
   -->
 
 <xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-  xmlns:bison="http://www.gnu.org/software/bison/">
+  xmlns:bison="https://www.gnu.org/software/bison/">
 
 <xsl:import href="bison.xsl"/>
 <xsl:output method="text" encoding="UTF-8" indent="no"/>
@@ -52,7 +52,7 @@
   <xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
     <xsl:text>Nonterminals useless in grammar&#10;&#10;</xsl:text>
     <xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
-      <xsl:text>   </xsl:text>
+      <xsl:text>    </xsl:text>
       <xsl:value-of select="@name"/>
       <xsl:text>&#10;</xsl:text>
     </xsl:for-each>
@@ -65,7 +65,7 @@
     <xsl:text>Terminals unused in grammar&#10;&#10;</xsl:text>
     <xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
       <xsl:sort select="@symbol-number" data-type="number"/>
-      <xsl:text>   </xsl:text>
+      <xsl:text>    </xsl:text>
       <xsl:value-of select="@name"/>
       <xsl:text>&#10;</xsl:text>
     </xsl:for-each>
@@ -136,6 +136,7 @@
 </xsl:template>
 
 <xsl:template match="terminal">
+  <xsl:text>    </xsl:text>
   <xsl:value-of select="@name"/>
   <xsl:call-template name="line-wrap">
     <xsl:with-param name="first-line-length">
@@ -148,6 +149,9 @@
     </xsl:with-param>
     <xsl:with-param name="line-length" select="66" />
     <xsl:with-param name="text">
+      <xsl:if test="string-length(@type) != 0">
+        <xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
+      </xsl:if>
       <xsl:value-of select="concat(' (', @token-number, ')')"/>
       <xsl:for-each select="key('bison:ruleByRhs', @name)">
         <xsl:value-of select="concat(' ', @number)"/>
@@ -157,14 +161,18 @@
 </xsl:template>
 
 <xsl:template match="nonterminal">
+  <xsl:text>    </xsl:text>
   <xsl:value-of select="@name"/>
+  <xsl:if test="string-length(@type) != 0">
+    <xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
+  </xsl:if>
   <xsl:value-of select="concat(' (', @symbol-number, ')')"/>
   <xsl:text>&#10;</xsl:text>
   <xsl:variable name="output">
     <xsl:call-template name="line-wrap">
       <xsl:with-param name="line-length" select="66" />
       <xsl:with-param name="text">
-        <xsl:text>    </xsl:text>
+        <xsl:text>        </xsl:text>
         <xsl:if test="key('bison:ruleByLhs', @name)">
           <xsl:text>on@left:</xsl:text>
           <xsl:for-each select="key('bison:ruleByLhs', @name)">
@@ -173,7 +181,7 @@
         </xsl:if>
         <xsl:if test="key('bison:ruleByRhs', @name)">
           <xsl:if test="key('bison:ruleByLhs', @name)">
-            <xsl:text>, </xsl:text>
+            <xsl:text>&#10;        </xsl:text>
           </xsl:if>
           <xsl:text>on@right:</xsl:text>
           <xsl:for-each select="key('bison:ruleByRhs', @name)">
@@ -300,7 +308,7 @@
       name="prev-lhs"
       select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
    />
-    <xsl:with-param name="point" select="@point"/>
+    <xsl:with-param name="dot" select="@dot"/>
     <xsl:with-param name="lookaheads">
       <xsl:apply-templates select="lookaheads"/>
     </xsl:with-param>
@@ -311,7 +319,7 @@
   <xsl:param name="itemset"/>
   <xsl:param name="pad"/>
   <xsl:param name="prev-lhs"/>
-  <xsl:param name="point"/>
+  <xsl:param name="dot"/>
   <xsl:param name="lookaheads"/>
 
   <xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
@@ -347,12 +355,12 @@
 
   <!-- RHS -->
   <xsl:for-each select="rhs/*">
-    <xsl:if test="position() = $point + 1">
-      <xsl:text> .</xsl:text>
+    <xsl:if test="position() = $dot + 1">
+      <xsl:text> •</xsl:text>
     </xsl:if>
     <xsl:apply-templates select="."/>
-    <xsl:if test="position() = last() and position() = $point">
-      <xsl:text> .</xsl:text>
+    <xsl:if test="position() = last() and position() = $dot">
+      <xsl:text> •</xsl:text>
     </xsl:if>
   </xsl:for-each>
   <xsl:if test="$lookaheads">
diff --git a/common/bison/xslt/xml2xhtml.xsl b/common/bison/xslt/xml2xhtml.xsl
index 087b035..aaa5dba 100644
--- a/common/bison/xslt/xml2xhtml.xsl
+++ b/common/bison/xslt/xml2xhtml.xsl
@@ -3,7 +3,7 @@
 <!--
     xml2html.xsl - transform Bison XML Report into XHTML.
 
-    Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
+    Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
 
     This file is part of Bison, the GNU Compiler Compiler.
 
@@ -18,7 +18,7 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
     Written by Wojciech Polak <polak@gnu.org>.
   -->
@@ -26,7 +26,7 @@
 <xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:bison="http://www.gnu.org/software/bison/">
+  xmlns:bison="https://www.gnu.org/software/bison/">
 
 <xsl:import href="bison.xsl"/>
 
@@ -75,7 +75,7 @@
       ol.lower-alpha {
         list-style-type: lower-alpha;
       }
-      .point {
+      .dot {
         color: #cc0000;
       }
       #footer {
@@ -88,7 +88,7 @@
       <xsl:apply-templates select="bison-xml-report"/>
       <xsl:text>&#10;&#10;</xsl:text>
       <div id="footer"><hr />This document was generated using
-      <a href="http://www.gnu.org/software/bison/" title="GNU Bison">
+      <a href="https://www.gnu.org/software/bison/" title="GNU Bison">
       GNU Bison <xsl:value-of select="/bison-xml-report/@version"/></a>
       XML Automaton Report.<br />
       <!-- default copying notice -->
@@ -227,6 +227,7 @@
   <xsl:text>&#10;</xsl:text>
   <p class="pre">
     <xsl:call-template name="style-rule-set">
+      <xsl:with-param name="anchor" select="'true'" />
       <xsl:with-param
         name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
       />
@@ -238,9 +239,11 @@
 </xsl:template>
 
 <xsl:template name="style-rule-set">
+  <xsl:param name="anchor"/>
   <xsl:param name="rule-set"/>
   <xsl:for-each select="$rule-set">
     <xsl:apply-templates select=".">
+      <xsl:with-param name="anchor" select="$anchor"/>
       <xsl:with-param name="pad" select="'3'"/>
       <xsl:with-param name="prev-lhs">
         <xsl:if test="position()>1">
@@ -306,9 +309,10 @@
     <xsl:text> Terminals, with rules where they appear</xsl:text>
   </h3>
   <xsl:text>&#10;&#10;</xsl:text>
-  <p class="pre">
+  <ul>
+    <xsl:text>&#10;</xsl:text>
     <xsl:apply-templates select="terminal"/>
-  </p>
+  </ul>
   <xsl:text>&#10;&#10;</xsl:text>
 </xsl:template>
 
@@ -318,41 +322,64 @@
     <xsl:text> Nonterminals, with rules where they appear</xsl:text>
   </h3>
   <xsl:text>&#10;&#10;</xsl:text>
-  <p class="pre">
+  <ul>
+    <xsl:text>&#10;</xsl:text>
     <xsl:apply-templates
       select="nonterminal[@usefulness!='useless-in-grammar']"
     />
-  </p>
+  </ul>
 </xsl:template>
 
 <xsl:template match="terminal">
-  <b><xsl:value-of select="@name"/></b>
-  <xsl:value-of select="concat(' (', @token-number, ')')"/>
-  <xsl:for-each select="key('bison:ruleByRhs', @name)">
-    <xsl:apply-templates select="." mode="number-link"/>
-  </xsl:for-each>
+  <xsl:text>  </xsl:text>
+  <li>
+    <b><xsl:value-of select="@name"/></b>
+    <xsl:if test="string-length(@type) != 0">
+      <xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
+    </xsl:if>
+    <xsl:value-of select="concat(' (', @token-number, ')')"/>
+    <xsl:for-each select="key('bison:ruleByRhs', @name)">
+      <xsl:apply-templates select="." mode="number-link"/>
+    </xsl:for-each>
+  </li>
   <xsl:text>&#10;</xsl:text>
 </xsl:template>
 
 <xsl:template match="nonterminal">
-  <b><xsl:value-of select="@name"/></b>
-  <xsl:value-of select="concat(' (', @symbol-number, ')')"/>
-  <xsl:text>&#10;    </xsl:text>
-  <xsl:if test="key('bison:ruleByLhs', @name)">
-    <xsl:text>on left:</xsl:text>
-    <xsl:for-each select="key('bison:ruleByLhs', @name)">
-      <xsl:apply-templates select="." mode="number-link"/>
-    </xsl:for-each>
-  </xsl:if>
-  <xsl:if test="key('bison:ruleByRhs', @name)">
-    <xsl:if test="key('bison:ruleByLhs', @name)">
-      <xsl:text>&#10;    </xsl:text>
+  <xsl:text>  </xsl:text>
+  <li>
+    <b><xsl:value-of select="@name"/></b>
+    <xsl:if test="string-length(@type) != 0">
+      <xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
     </xsl:if>
-    <xsl:text>on right:</xsl:text>
-    <xsl:for-each select="key('bison:ruleByRhs', @name)">
-      <xsl:apply-templates select="." mode="number-link"/>
-    </xsl:for-each>
-  </xsl:if>
+    <xsl:value-of select="concat(' (', @symbol-number, ')')"/>
+    <xsl:text>&#10;    </xsl:text>
+    <ul>
+      <xsl:text>&#10;</xsl:text>
+      <xsl:if test="key('bison:ruleByLhs', @name)">
+        <xsl:text>      </xsl:text>
+        <li>
+          <xsl:text>on left:</xsl:text>
+          <xsl:for-each select="key('bison:ruleByLhs', @name)">
+            <xsl:apply-templates select="." mode="number-link"/>
+          </xsl:for-each>
+        </li>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:if>
+      <xsl:if test="key('bison:ruleByRhs', @name)">
+        <xsl:text>      </xsl:text>
+        <li>
+          <xsl:text>on right:</xsl:text>
+          <xsl:for-each select="key('bison:ruleByRhs', @name)">
+            <xsl:apply-templates select="." mode="number-link"/>
+          </xsl:for-each>
+        </li>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:if>
+    <xsl:text>    </xsl:text>
+    </ul>
+    <xsl:text>&#10;  </xsl:text>
+  </li>
   <xsl:text>&#10;</xsl:text>
 </xsl:template>
 
@@ -385,7 +412,7 @@
         <xsl:value-of select="concat('state_', @number)"/>
       </xsl:attribute>
     </a>
-    <xsl:text>state </xsl:text>
+    <xsl:text>State </xsl:text>
     <xsl:value-of select="@number"/>
   </h3>
   <xsl:text>&#10;&#10;</xsl:text>
@@ -457,35 +484,44 @@
     <xsl:with-param name="prev-lhs"
       select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
    />
-    <xsl:with-param name="point" select="@point"/>
+    <xsl:with-param name="dot" select="@dot"/>
     <xsl:with-param name="lookaheads">
       <xsl:apply-templates select="lookaheads"/>
     </xsl:with-param>
   </xsl:apply-templates>
 </xsl:template>
 
+<!--
+anchor = 'true': define as an <a> anchor.
+itemset = 'true': show the items.
+ -->
 <xsl:template match="rule">
+  <xsl:param name="anchor"/>
   <xsl:param name="itemset"/>
   <xsl:param name="pad"/>
   <xsl:param name="prev-lhs"/>
-  <xsl:param name="point"/>
+  <xsl:param name="dot"/>
   <xsl:param name="lookaheads"/>
 
   <xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
     <xsl:text>&#10;</xsl:text>
   </xsl:if>
 
-  <xsl:if test="$itemset != 'true'">
-    <a>
-      <xsl:attribute name="name">
-        <xsl:value-of select="concat('rule_', @number)"/>
-      </xsl:attribute>
-    </a>
-  </xsl:if>
   <xsl:text>  </xsl:text>
 
   <xsl:choose>
-    <xsl:when test="$itemset = 'true'">
+    <xsl:when test="$anchor = 'true'">
+      <a>
+        <xsl:attribute name="name">
+          <xsl:value-of select="concat('rule_', @number)"/>
+        </xsl:attribute>
+        <xsl:call-template name="lpad">
+          <xsl:with-param name="str" select="string(@number)"/>
+          <xsl:with-param name="pad" select="number($pad)"/>
+        </xsl:call-template>
+      </a>
+    </xsl:when>
+    <xsl:otherwise>
       <a>
         <xsl:attribute name="href">
           <xsl:value-of select="concat('#rule_', @number)"/>
@@ -495,25 +531,13 @@
           <xsl:with-param name="pad" select="number($pad)"/>
         </xsl:call-template>
       </a>
-    </xsl:when>
-    <xsl:otherwise>
-      <xsl:call-template name="lpad">
-        <xsl:with-param name="str" select="string(@number)"/>
-        <xsl:with-param name="pad" select="number($pad)"/>
-      </xsl:call-template>
     </xsl:otherwise>
   </xsl:choose>
   <xsl:text> </xsl:text>
 
   <!-- LHS -->
   <xsl:choose>
-    <xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
-      <xsl:call-template name="lpad">
-        <xsl:with-param name="str" select="'|'"/>
-        <xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
-      </xsl:call-template>
-    </xsl:when>
-    <xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
+    <xsl:when test="$prev-lhs = lhs[text()]">
       <xsl:call-template name="lpad">
         <xsl:with-param name="str" select="'|'"/>
         <xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
@@ -529,14 +553,14 @@
 
   <!-- RHS -->
   <xsl:for-each select="rhs/*">
-    <xsl:if test="position() = $point + 1">
+    <xsl:if test="position() = $dot + 1">
       <xsl:text> </xsl:text>
-      <span class="point">.</span>
+      <span class="dot">&#x2022;</span>
     </xsl:if>
     <xsl:apply-templates select="."/>
-    <xsl:if test="position() = last() and position() = $point">
+    <xsl:if test="position() = last() and position() = $dot">
       <xsl:text> </xsl:text>
-      <span class="point">.</span>
+      <span class="dot">&#x2022;</span>
     </xsl:if>
   </xsl:for-each>
   <xsl:if test="$lookaheads">
diff --git a/darwin-x86/bin/acp b/darwin-x86/bin/acp
index 1c69843..d891a8e 100755
--- a/darwin-x86/bin/acp
+++ b/darwin-x86/bin/acp
Binary files differ
diff --git a/darwin-x86/bin/aidl b/darwin-x86/bin/aidl
index 9efd4c3..9e15b8f 100755
--- a/darwin-x86/bin/aidl
+++ b/darwin-x86/bin/aidl
Binary files differ
diff --git a/darwin-x86/bin/bison b/darwin-x86/bin/bison
index 013bbf1..acadff2 100755
--- a/darwin-x86/bin/bison
+++ b/darwin-x86/bin/bison
Binary files differ
diff --git a/darwin-x86/bin/bloaty b/darwin-x86/bin/bloaty
index 102e3b6..2bd6818 100755
--- a/darwin-x86/bin/bloaty
+++ b/darwin-x86/bin/bloaty
Binary files differ
diff --git a/darwin-x86/bin/bzip2 b/darwin-x86/bin/bzip2
index d540d2c..cc890b7 100755
--- a/darwin-x86/bin/bzip2
+++ b/darwin-x86/bin/bzip2
Binary files differ
diff --git a/darwin-x86/bin/ckati b/darwin-x86/bin/ckati
index 6d058ed..7fb74fa 100755
--- a/darwin-x86/bin/ckati
+++ b/darwin-x86/bin/ckati
Binary files differ
diff --git a/darwin-x86/bin/ckati_stamp_dump b/darwin-x86/bin/ckati_stamp_dump
index b198b36..f9ff480 100755
--- a/darwin-x86/bin/ckati_stamp_dump
+++ b/darwin-x86/bin/ckati_stamp_dump
Binary files differ
diff --git a/darwin-x86/bin/flex b/darwin-x86/bin/flex
index 1c33a73..e0b7d5c 100755
--- a/darwin-x86/bin/flex
+++ b/darwin-x86/bin/flex
Binary files differ
diff --git a/darwin-x86/bin/gavinhoward-bc b/darwin-x86/bin/gavinhoward-bc
index f3ea8f8..b503581 100755
--- a/darwin-x86/bin/gavinhoward-bc
+++ b/darwin-x86/bin/gavinhoward-bc
Binary files differ
diff --git a/darwin-x86/bin/hidl-gen b/darwin-x86/bin/hidl-gen
index 917aaf8..e394cc8 100755
--- a/darwin-x86/bin/hidl-gen
+++ b/darwin-x86/bin/hidl-gen
Binary files differ
diff --git a/darwin-x86/bin/hidl-lint b/darwin-x86/bin/hidl-lint
index 2d60765..3596168 100755
--- a/darwin-x86/bin/hidl-lint
+++ b/darwin-x86/bin/hidl-lint
Binary files differ
diff --git a/darwin-x86/bin/m4 b/darwin-x86/bin/m4
index 7f05ebd..3f468aa 100755
--- a/darwin-x86/bin/m4
+++ b/darwin-x86/bin/m4
Binary files differ
diff --git a/darwin-x86/bin/make b/darwin-x86/bin/make
index d8c2a3c..ca86fee 100755
--- a/darwin-x86/bin/make
+++ b/darwin-x86/bin/make
Binary files differ
diff --git a/darwin-x86/bin/ninja b/darwin-x86/bin/ninja
index 1cbe036..f002507 100755
--- a/darwin-x86/bin/ninja
+++ b/darwin-x86/bin/ninja
Binary files differ
diff --git a/darwin-x86/bin/one-true-awk b/darwin-x86/bin/one-true-awk
index b9d1990..f940e9e 100755
--- a/darwin-x86/bin/one-true-awk
+++ b/darwin-x86/bin/one-true-awk
Binary files differ
diff --git a/darwin-x86/bin/openssl b/darwin-x86/bin/openssl
index bb81a57..e68304a 100755
--- a/darwin-x86/bin/openssl
+++ b/darwin-x86/bin/openssl
Binary files differ
diff --git a/darwin-x86/bin/py2-cmd b/darwin-x86/bin/py2-cmd
index c98dbe2..ec3092f 100755
--- a/darwin-x86/bin/py2-cmd
+++ b/darwin-x86/bin/py2-cmd
Binary files differ
diff --git a/darwin-x86/bin/py3-cmd b/darwin-x86/bin/py3-cmd
index 0f64784..64d519c 100755
--- a/darwin-x86/bin/py3-cmd
+++ b/darwin-x86/bin/py3-cmd
Binary files differ
diff --git a/darwin-x86/bin/py3-launcher-autorun64 b/darwin-x86/bin/py3-launcher-autorun64
index 748d463..71af69b 100755
--- a/darwin-x86/bin/py3-launcher-autorun64
+++ b/darwin-x86/bin/py3-launcher-autorun64
Binary files differ
diff --git a/darwin-x86/bin/py3-launcher64 b/darwin-x86/bin/py3-launcher64
index 2f1fbcd..1379592 100755
--- a/darwin-x86/bin/py3-launcher64
+++ b/darwin-x86/bin/py3-launcher64
Binary files differ
diff --git a/darwin-x86/bin/toybox b/darwin-x86/bin/toybox
index c00509e..5b2eb3c 100755
--- a/darwin-x86/bin/toybox
+++ b/darwin-x86/bin/toybox
Binary files differ
diff --git a/darwin-x86/bin/xz b/darwin-x86/bin/xz
index 114f888..e5f4df6 100755
--- a/darwin-x86/bin/xz
+++ b/darwin-x86/bin/xz
Binary files differ
diff --git a/darwin-x86/bin/zipalign b/darwin-x86/bin/zipalign
index a817928..7cde13a 100755
--- a/darwin-x86/bin/zipalign
+++ b/darwin-x86/bin/zipalign
Binary files differ
diff --git a/darwin-x86/bin/ziptime b/darwin-x86/bin/ziptime
index 915a659..fb62c95 100755
--- a/darwin-x86/bin/ziptime
+++ b/darwin-x86/bin/ziptime
Binary files differ
diff --git a/darwin-x86/bin/ziptool b/darwin-x86/bin/ziptool
index 3c71260..21903d7 100755
--- a/darwin-x86/bin/ziptool
+++ b/darwin-x86/bin/ziptool
Binary files differ
diff --git a/darwin-x86/lib64/libbase.dylib b/darwin-x86/lib64/libbase.dylib
index 4b405c7..472034f 100755
--- a/darwin-x86/lib64/libbase.dylib
+++ b/darwin-x86/lib64/libbase.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libc++.dylib b/darwin-x86/lib64/libc++.dylib
index 9121ca8..345bdd1 100755
--- a/darwin-x86/lib64/libc++.dylib
+++ b/darwin-x86/lib64/libc++.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libcrypto-host.dylib b/darwin-x86/lib64/libcrypto-host.dylib
index 4d04110..6545040 100755
--- a/darwin-x86/lib64/libcrypto-host.dylib
+++ b/darwin-x86/lib64/libcrypto-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libicui18n-host.dylib b/darwin-x86/lib64/libicui18n-host.dylib
index 2344f7b..de58921 100755
--- a/darwin-x86/lib64/libicui18n-host.dylib
+++ b/darwin-x86/lib64/libicui18n-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libicuuc-host.dylib b/darwin-x86/lib64/libicuuc-host.dylib
index d63cdc0..3839a74 100755
--- a/darwin-x86/lib64/libicuuc-host.dylib
+++ b/darwin-x86/lib64/libicuuc-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/liblog.dylib b/darwin-x86/lib64/liblog.dylib
index 9f0f1b1..520818c 100755
--- a/darwin-x86/lib64/liblog.dylib
+++ b/darwin-x86/lib64/liblog.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libsqlite.dylib b/darwin-x86/lib64/libsqlite.dylib
index f52abce..3560cc6 100755
--- a/darwin-x86/lib64/libsqlite.dylib
+++ b/darwin-x86/lib64/libsqlite.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libz-host.dylib b/darwin-x86/lib64/libz-host.dylib
index ee1b38f..d0448ad 100755
--- a/darwin-x86/lib64/libz-host.dylib
+++ b/darwin-x86/lib64/libz-host.dylib
Binary files differ
diff --git a/darwin-x86/lib64/libziparchive.dylib b/darwin-x86/lib64/libziparchive.dylib
index 41d1c41..ab2bbd6 100755
--- a/darwin-x86/lib64/libziparchive.dylib
+++ b/darwin-x86/lib64/libziparchive.dylib
Binary files differ
diff --git a/linux-x86/asan/bin/acp b/linux-x86/asan/bin/acp
index 3366d1f..69e0ce2 100755
--- a/linux-x86/asan/bin/acp
+++ b/linux-x86/asan/bin/acp
Binary files differ
diff --git a/linux-x86/asan/bin/aidl b/linux-x86/asan/bin/aidl
index a583a03..1babb92 100755
--- a/linux-x86/asan/bin/aidl
+++ b/linux-x86/asan/bin/aidl
Binary files differ
diff --git a/linux-x86/asan/bin/ckati b/linux-x86/asan/bin/ckati
index 03dc93b..7fd3a33 100755
--- a/linux-x86/asan/bin/ckati
+++ b/linux-x86/asan/bin/ckati
Binary files differ
diff --git a/linux-x86/asan/bin/gavinhoward-bc b/linux-x86/asan/bin/gavinhoward-bc
index 79a20eb..aab6c96 100755
--- a/linux-x86/asan/bin/gavinhoward-bc
+++ b/linux-x86/asan/bin/gavinhoward-bc
Binary files differ
diff --git a/linux-x86/asan/bin/ninja b/linux-x86/asan/bin/ninja
index fd27185..f9833db 100755
--- a/linux-x86/asan/bin/ninja
+++ b/linux-x86/asan/bin/ninja
Binary files differ
diff --git a/linux-x86/asan/bin/toybox b/linux-x86/asan/bin/toybox
index 68297a4..5522cda 100755
--- a/linux-x86/asan/bin/toybox
+++ b/linux-x86/asan/bin/toybox
Binary files differ
diff --git a/linux-x86/asan/bin/zipalign b/linux-x86/asan/bin/zipalign
index acf3d57..baef64e 100755
--- a/linux-x86/asan/bin/zipalign
+++ b/linux-x86/asan/bin/zipalign
Binary files differ
diff --git a/linux-x86/asan/bin/ziptime b/linux-x86/asan/bin/ziptime
index 02cdffa..b2094bf 100755
--- a/linux-x86/asan/bin/ziptime
+++ b/linux-x86/asan/bin/ziptime
Binary files differ
diff --git a/linux-x86/asan/bin/ziptool b/linux-x86/asan/bin/ziptool
index d8be5b0..ec9e6ee 100755
--- a/linux-x86/asan/bin/ziptool
+++ b/linux-x86/asan/bin/ziptool
Binary files differ
diff --git a/linux-x86/asan/lib64/libbase.so b/linux-x86/asan/lib64/libbase.so
index da4db9d..49387b2 100755
--- a/linux-x86/asan/lib64/libbase.so
+++ b/linux-x86/asan/lib64/libbase.so
Binary files differ
diff --git a/linux-x86/asan/lib64/libc++.so b/linux-x86/asan/lib64/libc++.so
index 22e34db..cd48320 100755
--- a/linux-x86/asan/lib64/libc++.so
+++ b/linux-x86/asan/lib64/libc++.so
Binary files differ
diff --git a/linux-x86/asan/lib64/libcrypto-host.so b/linux-x86/asan/lib64/libcrypto-host.so
index f8c4e41..f02c02b 100755
--- a/linux-x86/asan/lib64/libcrypto-host.so
+++ b/linux-x86/asan/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux-x86/asan/lib64/libjemalloc5.so b/linux-x86/asan/lib64/libjemalloc5.so
index 2dd72d8..19e7f04 100755
--- a/linux-x86/asan/lib64/libjemalloc5.so
+++ b/linux-x86/asan/lib64/libjemalloc5.so
Binary files differ
diff --git a/linux-x86/asan/lib64/liblog.so b/linux-x86/asan/lib64/liblog.so
index ff93721..86bd5e4 100755
--- a/linux-x86/asan/lib64/liblog.so
+++ b/linux-x86/asan/lib64/liblog.so
Binary files differ
diff --git a/linux-x86/asan/lib64/libz-host.so b/linux-x86/asan/lib64/libz-host.so
index 3881406..a20bff9 100755
--- a/linux-x86/asan/lib64/libz-host.so
+++ b/linux-x86/asan/lib64/libz-host.so
Binary files differ
diff --git a/linux-x86/asan/lib64/libziparchive.so b/linux-x86/asan/lib64/libziparchive.so
index 0ebb85c..74cc38a 100755
--- a/linux-x86/asan/lib64/libziparchive.so
+++ b/linux-x86/asan/lib64/libziparchive.so
Binary files differ
diff --git a/linux-x86/bin/acp b/linux-x86/bin/acp
index 0051c80..be8b230 100755
--- a/linux-x86/bin/acp
+++ b/linux-x86/bin/acp
Binary files differ
diff --git a/linux-x86/bin/aidl b/linux-x86/bin/aidl
index 6d31a2d..02fb779 100755
--- a/linux-x86/bin/aidl
+++ b/linux-x86/bin/aidl
Binary files differ
diff --git a/linux-x86/bin/bison b/linux-x86/bin/bison
index dff701c..a6242cb 100755
--- a/linux-x86/bin/bison
+++ b/linux-x86/bin/bison
Binary files differ
diff --git a/linux-x86/bin/bloaty b/linux-x86/bin/bloaty
index 1c2cb05..10de301 100755
--- a/linux-x86/bin/bloaty
+++ b/linux-x86/bin/bloaty
Binary files differ
diff --git a/linux-x86/bin/bzip2 b/linux-x86/bin/bzip2
index 0debfe5..b0f216e 100755
--- a/linux-x86/bin/bzip2
+++ b/linux-x86/bin/bzip2
Binary files differ
diff --git a/linux-x86/bin/ckati b/linux-x86/bin/ckati
index f404f55..48c08d2 100755
--- a/linux-x86/bin/ckati
+++ b/linux-x86/bin/ckati
Binary files differ
diff --git a/linux-x86/bin/ckati_stamp_dump b/linux-x86/bin/ckati_stamp_dump
index 76457fc..0d97177 100755
--- a/linux-x86/bin/ckati_stamp_dump
+++ b/linux-x86/bin/ckati_stamp_dump
Binary files differ
diff --git a/linux-x86/bin/create_minidebuginfo b/linux-x86/bin/create_minidebuginfo
index f9a354e..99dc10c 100755
--- a/linux-x86/bin/create_minidebuginfo
+++ b/linux-x86/bin/create_minidebuginfo
Binary files differ
diff --git a/linux-x86/bin/flex b/linux-x86/bin/flex
index 5caef46..8e7afde 100755
--- a/linux-x86/bin/flex
+++ b/linux-x86/bin/flex
Binary files differ
diff --git a/linux-x86/bin/gavinhoward-bc b/linux-x86/bin/gavinhoward-bc
index e5cdc51..657fbf8 100755
--- a/linux-x86/bin/gavinhoward-bc
+++ b/linux-x86/bin/gavinhoward-bc
Binary files differ
diff --git a/linux-x86/bin/hidl-gen b/linux-x86/bin/hidl-gen
index 24914e0..7b3b137 100755
--- a/linux-x86/bin/hidl-gen
+++ b/linux-x86/bin/hidl-gen
Binary files differ
diff --git a/linux-x86/bin/hidl-lint b/linux-x86/bin/hidl-lint
index 81bf260..8e0327c 100755
--- a/linux-x86/bin/hidl-lint
+++ b/linux-x86/bin/hidl-lint
Binary files differ
diff --git a/linux-x86/bin/m4 b/linux-x86/bin/m4
index e97ae15..07b42c8 100755
--- a/linux-x86/bin/m4
+++ b/linux-x86/bin/m4
Binary files differ
diff --git a/linux-x86/bin/make b/linux-x86/bin/make
index 6a17969..d7a0d6a 100755
--- a/linux-x86/bin/make
+++ b/linux-x86/bin/make
Binary files differ
diff --git a/linux-x86/bin/ninja b/linux-x86/bin/ninja
index e1461bf..f83ed92 100755
--- a/linux-x86/bin/ninja
+++ b/linux-x86/bin/ninja
Binary files differ
diff --git a/linux-x86/bin/nsjail b/linux-x86/bin/nsjail
index 4773679..fe38f17 100755
--- a/linux-x86/bin/nsjail
+++ b/linux-x86/bin/nsjail
Binary files differ
diff --git a/linux-x86/bin/one-true-awk b/linux-x86/bin/one-true-awk
index c8c546b..f462aac 100755
--- a/linux-x86/bin/one-true-awk
+++ b/linux-x86/bin/one-true-awk
Binary files differ
diff --git a/linux-x86/bin/openssl b/linux-x86/bin/openssl
index 39d259a..6f5b5b2 100755
--- a/linux-x86/bin/openssl
+++ b/linux-x86/bin/openssl
Binary files differ
diff --git a/linux-x86/bin/py2-cmd b/linux-x86/bin/py2-cmd
index c625eb5..33d09db 100755
--- a/linux-x86/bin/py2-cmd
+++ b/linux-x86/bin/py2-cmd
Binary files differ
diff --git a/linux-x86/bin/py3-cmd b/linux-x86/bin/py3-cmd
index 5451cc9..53e21c4 100755
--- a/linux-x86/bin/py3-cmd
+++ b/linux-x86/bin/py3-cmd
Binary files differ
diff --git a/linux-x86/bin/py3-launcher-autorun64 b/linux-x86/bin/py3-launcher-autorun64
index 996c034..1a324f2 100755
--- a/linux-x86/bin/py3-launcher-autorun64
+++ b/linux-x86/bin/py3-launcher-autorun64
Binary files differ
diff --git a/linux-x86/bin/py3-launcher64 b/linux-x86/bin/py3-launcher64
index af07028..cb62b83 100755
--- a/linux-x86/bin/py3-launcher64
+++ b/linux-x86/bin/py3-launcher64
Binary files differ
diff --git a/linux-x86/bin/toybox b/linux-x86/bin/toybox
index 59e9b56..1c34b73 100755
--- a/linux-x86/bin/toybox
+++ b/linux-x86/bin/toybox
Binary files differ
diff --git a/linux-x86/bin/xz b/linux-x86/bin/xz
index 6f5461b..d71e3c5 100755
--- a/linux-x86/bin/xz
+++ b/linux-x86/bin/xz
Binary files differ
diff --git a/linux-x86/bin/zipalign b/linux-x86/bin/zipalign
index e83aeb0..7deaa45 100755
--- a/linux-x86/bin/zipalign
+++ b/linux-x86/bin/zipalign
Binary files differ
diff --git a/linux-x86/bin/ziptime b/linux-x86/bin/ziptime
index e0a198a..08a3b23 100755
--- a/linux-x86/bin/ziptime
+++ b/linux-x86/bin/ziptime
Binary files differ
diff --git a/linux-x86/bin/ziptool b/linux-x86/bin/ziptool
index 169b8bf..e9b2e8a 100755
--- a/linux-x86/bin/ziptool
+++ b/linux-x86/bin/ziptool
Binary files differ
diff --git a/linux-x86/lib64/libbase.so b/linux-x86/lib64/libbase.so
index d4529e2..6b7af65 100755
--- a/linux-x86/lib64/libbase.so
+++ b/linux-x86/lib64/libbase.so
Binary files differ
diff --git a/linux-x86/lib64/libc++.so b/linux-x86/lib64/libc++.so
index 17b14c9..e22c3b1 100755
--- a/linux-x86/lib64/libc++.so
+++ b/linux-x86/lib64/libc++.so
Binary files differ
diff --git a/linux-x86/lib64/libcrypto-host.so b/linux-x86/lib64/libcrypto-host.so
index cc60f1a..68db0b3 100755
--- a/linux-x86/lib64/libcrypto-host.so
+++ b/linux-x86/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux-x86/lib64/libicui18n-host.so b/linux-x86/lib64/libicui18n-host.so
index 3f1fb13..cc89f7a 100755
--- a/linux-x86/lib64/libicui18n-host.so
+++ b/linux-x86/lib64/libicui18n-host.so
Binary files differ
diff --git a/linux-x86/lib64/libicuuc-host.so b/linux-x86/lib64/libicuuc-host.so
index d0e83fd..278cef3 100755
--- a/linux-x86/lib64/libicuuc-host.so
+++ b/linux-x86/lib64/libicuuc-host.so
Binary files differ
diff --git a/linux-x86/lib64/libjemalloc5.so b/linux-x86/lib64/libjemalloc5.so
index c85b8a4..3697338 100755
--- a/linux-x86/lib64/libjemalloc5.so
+++ b/linux-x86/lib64/libjemalloc5.so
Binary files differ
diff --git a/linux-x86/lib64/liblog.so b/linux-x86/lib64/liblog.so
index eaf85b2..fd8498a 100755
--- a/linux-x86/lib64/liblog.so
+++ b/linux-x86/lib64/liblog.so
Binary files differ
diff --git a/linux-x86/lib64/libnl.so b/linux-x86/lib64/libnl.so
index 4df2a47..7c73cc6 100755
--- a/linux-x86/lib64/libnl.so
+++ b/linux-x86/lib64/libnl.so
Binary files differ
diff --git a/linux-x86/lib64/libprotobuf-cpp-full.so b/linux-x86/lib64/libprotobuf-cpp-full.so
index 3b5b9ba..b693784 100755
--- a/linux-x86/lib64/libprotobuf-cpp-full.so
+++ b/linux-x86/lib64/libprotobuf-cpp-full.so
Binary files differ
diff --git a/linux-x86/lib64/libsqlite.so b/linux-x86/lib64/libsqlite.so
index 7db8697..3fae08e 100755
--- a/linux-x86/lib64/libsqlite.so
+++ b/linux-x86/lib64/libsqlite.so
Binary files differ
diff --git a/linux-x86/lib64/libz-host.so b/linux-x86/lib64/libz-host.so
index ea62227..e29e1ec 100755
--- a/linux-x86/lib64/libz-host.so
+++ b/linux-x86/lib64/libz-host.so
Binary files differ
diff --git a/linux-x86/lib64/libziparchive.so b/linux-x86/lib64/libziparchive.so
index aca2b7b..bd1ffeb 100755
--- a/linux-x86/lib64/libziparchive.so
+++ b/linux-x86/lib64/libziparchive.so
Binary files differ
diff --git a/linux_musl-x86/asan/bin/acp b/linux_musl-x86/asan/bin/acp
index 3366d1f..69e0ce2 100755
--- a/linux_musl-x86/asan/bin/acp
+++ b/linux_musl-x86/asan/bin/acp
Binary files differ
diff --git a/linux_musl-x86/asan/bin/aidl b/linux_musl-x86/asan/bin/aidl
index a583a03..1babb92 100755
--- a/linux_musl-x86/asan/bin/aidl
+++ b/linux_musl-x86/asan/bin/aidl
Binary files differ
diff --git a/linux_musl-x86/asan/bin/ckati b/linux_musl-x86/asan/bin/ckati
index 03dc93b..7fd3a33 100755
--- a/linux_musl-x86/asan/bin/ckati
+++ b/linux_musl-x86/asan/bin/ckati
Binary files differ
diff --git a/linux_musl-x86/asan/bin/gavinhoward-bc b/linux_musl-x86/asan/bin/gavinhoward-bc
index 79a20eb..aab6c96 100755
--- a/linux_musl-x86/asan/bin/gavinhoward-bc
+++ b/linux_musl-x86/asan/bin/gavinhoward-bc
Binary files differ
diff --git a/linux_musl-x86/asan/bin/ninja b/linux_musl-x86/asan/bin/ninja
index fd27185..f9833db 100755
--- a/linux_musl-x86/asan/bin/ninja
+++ b/linux_musl-x86/asan/bin/ninja
Binary files differ
diff --git a/linux_musl-x86/asan/bin/toybox b/linux_musl-x86/asan/bin/toybox
index 68297a4..5522cda 100755
--- a/linux_musl-x86/asan/bin/toybox
+++ b/linux_musl-x86/asan/bin/toybox
Binary files differ
diff --git a/linux_musl-x86/asan/bin/zipalign b/linux_musl-x86/asan/bin/zipalign
index acf3d57..baef64e 100755
--- a/linux_musl-x86/asan/bin/zipalign
+++ b/linux_musl-x86/asan/bin/zipalign
Binary files differ
diff --git a/linux_musl-x86/asan/bin/ziptime b/linux_musl-x86/asan/bin/ziptime
index 02cdffa..b2094bf 100755
--- a/linux_musl-x86/asan/bin/ziptime
+++ b/linux_musl-x86/asan/bin/ziptime
Binary files differ
diff --git a/linux_musl-x86/asan/bin/ziptool b/linux_musl-x86/asan/bin/ziptool
index d8be5b0..ec9e6ee 100755
--- a/linux_musl-x86/asan/bin/ziptool
+++ b/linux_musl-x86/asan/bin/ziptool
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libbase.so b/linux_musl-x86/asan/lib64/libbase.so
index da4db9d..49387b2 100755
--- a/linux_musl-x86/asan/lib64/libbase.so
+++ b/linux_musl-x86/asan/lib64/libbase.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libc++.so b/linux_musl-x86/asan/lib64/libc++.so
index 22e34db..cd48320 100755
--- a/linux_musl-x86/asan/lib64/libc++.so
+++ b/linux_musl-x86/asan/lib64/libc++.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libcrypto-host.so b/linux_musl-x86/asan/lib64/libcrypto-host.so
index f8c4e41..f02c02b 100755
--- a/linux_musl-x86/asan/lib64/libcrypto-host.so
+++ b/linux_musl-x86/asan/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libjemalloc5.so b/linux_musl-x86/asan/lib64/libjemalloc5.so
index 2dd72d8..19e7f04 100755
--- a/linux_musl-x86/asan/lib64/libjemalloc5.so
+++ b/linux_musl-x86/asan/lib64/libjemalloc5.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/liblog.so b/linux_musl-x86/asan/lib64/liblog.so
index ff93721..86bd5e4 100755
--- a/linux_musl-x86/asan/lib64/liblog.so
+++ b/linux_musl-x86/asan/lib64/liblog.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libz-host.so b/linux_musl-x86/asan/lib64/libz-host.so
index 3881406..a20bff9 100755
--- a/linux_musl-x86/asan/lib64/libz-host.so
+++ b/linux_musl-x86/asan/lib64/libz-host.so
Binary files differ
diff --git a/linux_musl-x86/asan/lib64/libziparchive.so b/linux_musl-x86/asan/lib64/libziparchive.so
index 0ebb85c..74cc38a 100755
--- a/linux_musl-x86/asan/lib64/libziparchive.so
+++ b/linux_musl-x86/asan/lib64/libziparchive.so
Binary files differ
diff --git a/linux_musl-x86/bin/acp b/linux_musl-x86/bin/acp
index 59ea459..5c16c4e 100755
--- a/linux_musl-x86/bin/acp
+++ b/linux_musl-x86/bin/acp
Binary files differ
diff --git a/linux_musl-x86/bin/aidl b/linux_musl-x86/bin/aidl
index 37da92d..41fb69d 100755
--- a/linux_musl-x86/bin/aidl
+++ b/linux_musl-x86/bin/aidl
Binary files differ
diff --git a/linux_musl-x86/bin/bison b/linux_musl-x86/bin/bison
index a86b84c..e4bd0d7 100755
--- a/linux_musl-x86/bin/bison
+++ b/linux_musl-x86/bin/bison
Binary files differ
diff --git a/linux_musl-x86/bin/bloaty b/linux_musl-x86/bin/bloaty
index cbcc70d..bef7195 100755
--- a/linux_musl-x86/bin/bloaty
+++ b/linux_musl-x86/bin/bloaty
Binary files differ
diff --git a/linux_musl-x86/bin/bzip2 b/linux_musl-x86/bin/bzip2
index 6f24cbd..4b56168 100755
--- a/linux_musl-x86/bin/bzip2
+++ b/linux_musl-x86/bin/bzip2
Binary files differ
diff --git a/linux_musl-x86/bin/ckati b/linux_musl-x86/bin/ckati
index e09bf25..80cc079 100755
--- a/linux_musl-x86/bin/ckati
+++ b/linux_musl-x86/bin/ckati
Binary files differ
diff --git a/linux_musl-x86/bin/ckati_stamp_dump b/linux_musl-x86/bin/ckati_stamp_dump
index f59bb1c..4a379ef 100755
--- a/linux_musl-x86/bin/ckati_stamp_dump
+++ b/linux_musl-x86/bin/ckati_stamp_dump
Binary files differ
diff --git a/linux_musl-x86/bin/create_minidebuginfo b/linux_musl-x86/bin/create_minidebuginfo
index 2687185..c3feb00 100755
--- a/linux_musl-x86/bin/create_minidebuginfo
+++ b/linux_musl-x86/bin/create_minidebuginfo
Binary files differ
diff --git a/linux_musl-x86/bin/flex b/linux_musl-x86/bin/flex
index 9effa62..1a0fc6c 100755
--- a/linux_musl-x86/bin/flex
+++ b/linux_musl-x86/bin/flex
Binary files differ
diff --git a/linux_musl-x86/bin/gavinhoward-bc b/linux_musl-x86/bin/gavinhoward-bc
index aaf8803..813a594 100755
--- a/linux_musl-x86/bin/gavinhoward-bc
+++ b/linux_musl-x86/bin/gavinhoward-bc
Binary files differ
diff --git a/linux_musl-x86/bin/hidl-gen b/linux_musl-x86/bin/hidl-gen
index 3a8fd31..5239d14 100755
--- a/linux_musl-x86/bin/hidl-gen
+++ b/linux_musl-x86/bin/hidl-gen
Binary files differ
diff --git a/linux_musl-x86/bin/hidl-lint b/linux_musl-x86/bin/hidl-lint
index bbba576..964c28e 100755
--- a/linux_musl-x86/bin/hidl-lint
+++ b/linux_musl-x86/bin/hidl-lint
Binary files differ
diff --git a/linux_musl-x86/bin/m4 b/linux_musl-x86/bin/m4
index 7cad0eb..4506be9 100755
--- a/linux_musl-x86/bin/m4
+++ b/linux_musl-x86/bin/m4
Binary files differ
diff --git a/linux_musl-x86/bin/make b/linux_musl-x86/bin/make
index d6e60d6..9f405d3 100755
--- a/linux_musl-x86/bin/make
+++ b/linux_musl-x86/bin/make
Binary files differ
diff --git a/linux_musl-x86/bin/ninja b/linux_musl-x86/bin/ninja
index 59d2ccf..eddfeff 100755
--- a/linux_musl-x86/bin/ninja
+++ b/linux_musl-x86/bin/ninja
Binary files differ
diff --git a/linux_musl-x86/bin/nsjail b/linux_musl-x86/bin/nsjail
index 2fceca2..9fb7d66 100755
--- a/linux_musl-x86/bin/nsjail
+++ b/linux_musl-x86/bin/nsjail
Binary files differ
diff --git a/linux_musl-x86/bin/one-true-awk b/linux_musl-x86/bin/one-true-awk
index 90a39d8..7e8c3ef 100755
--- a/linux_musl-x86/bin/one-true-awk
+++ b/linux_musl-x86/bin/one-true-awk
Binary files differ
diff --git a/linux_musl-x86/bin/openssl b/linux_musl-x86/bin/openssl
index 43cd826..16f73f0 100755
--- a/linux_musl-x86/bin/openssl
+++ b/linux_musl-x86/bin/openssl
Binary files differ
diff --git a/linux_musl-x86/bin/py2-cmd b/linux_musl-x86/bin/py2-cmd
index 262f8a4..60bafb1 100755
--- a/linux_musl-x86/bin/py2-cmd
+++ b/linux_musl-x86/bin/py2-cmd
Binary files differ
diff --git a/linux_musl-x86/bin/py3-cmd b/linux_musl-x86/bin/py3-cmd
index 469f237..b60e0d4 100755
--- a/linux_musl-x86/bin/py3-cmd
+++ b/linux_musl-x86/bin/py3-cmd
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher-autorun-static64 b/linux_musl-x86/bin/py3-launcher-autorun-static64
index b9dbb5b..a3271ac 100755
--- a/linux_musl-x86/bin/py3-launcher-autorun-static64
+++ b/linux_musl-x86/bin/py3-launcher-autorun-static64
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher-autorun64 b/linux_musl-x86/bin/py3-launcher-autorun64
index 6ddb171..d928b05 100755
--- a/linux_musl-x86/bin/py3-launcher-autorun64
+++ b/linux_musl-x86/bin/py3-launcher-autorun64
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher-static64 b/linux_musl-x86/bin/py3-launcher-static64
index dc37783..f1cf47c 100755
--- a/linux_musl-x86/bin/py3-launcher-static64
+++ b/linux_musl-x86/bin/py3-launcher-static64
Binary files differ
diff --git a/linux_musl-x86/bin/py3-launcher64 b/linux_musl-x86/bin/py3-launcher64
index dddd671..9bb7f6c 100755
--- a/linux_musl-x86/bin/py3-launcher64
+++ b/linux_musl-x86/bin/py3-launcher64
Binary files differ
diff --git a/linux_musl-x86/bin/toybox b/linux_musl-x86/bin/toybox
index edf6da2..33aa047 100755
--- a/linux_musl-x86/bin/toybox
+++ b/linux_musl-x86/bin/toybox
Binary files differ
diff --git a/linux_musl-x86/bin/xz b/linux_musl-x86/bin/xz
index d4be008..03e2cbc 100755
--- a/linux_musl-x86/bin/xz
+++ b/linux_musl-x86/bin/xz
Binary files differ
diff --git a/linux_musl-x86/bin/zipalign b/linux_musl-x86/bin/zipalign
index acd7147..c312946 100755
--- a/linux_musl-x86/bin/zipalign
+++ b/linux_musl-x86/bin/zipalign
Binary files differ
diff --git a/linux_musl-x86/bin/ziptime b/linux_musl-x86/bin/ziptime
index b8238c4..50a9e9f 100755
--- a/linux_musl-x86/bin/ziptime
+++ b/linux_musl-x86/bin/ziptime
Binary files differ
diff --git a/linux_musl-x86/bin/ziptool b/linux_musl-x86/bin/ziptool
index 247e902..abe09d0 100755
--- a/linux_musl-x86/bin/ziptool
+++ b/linux_musl-x86/bin/ziptool
Binary files differ
diff --git a/linux_musl-x86/lib64/libbase.so b/linux_musl-x86/lib64/libbase.so
index 0d700b7..22d7fea 100755
--- a/linux_musl-x86/lib64/libbase.so
+++ b/linux_musl-x86/lib64/libbase.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libc++.so b/linux_musl-x86/lib64/libc++.so
index 212292b..6b265ab 100755
--- a/linux_musl-x86/lib64/libc++.so
+++ b/linux_musl-x86/lib64/libc++.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libc_musl.so b/linux_musl-x86/lib64/libc_musl.so
index fcf6794..ba6025f 100755
--- a/linux_musl-x86/lib64/libc_musl.so
+++ b/linux_musl-x86/lib64/libc_musl.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libcrypto-host.so b/linux_musl-x86/lib64/libcrypto-host.so
index 25c63f9..e3b4477 100755
--- a/linux_musl-x86/lib64/libcrypto-host.so
+++ b/linux_musl-x86/lib64/libcrypto-host.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libicui18n-host.so b/linux_musl-x86/lib64/libicui18n-host.so
index e5938c4..15a9705 100755
--- a/linux_musl-x86/lib64/libicui18n-host.so
+++ b/linux_musl-x86/lib64/libicui18n-host.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libicuuc-host.so b/linux_musl-x86/lib64/libicuuc-host.so
index d954908..1b73916 100755
--- a/linux_musl-x86/lib64/libicuuc-host.so
+++ b/linux_musl-x86/lib64/libicuuc-host.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libjemalloc5.so b/linux_musl-x86/lib64/libjemalloc5.so
index 806168d..b9e2a46 100755
--- a/linux_musl-x86/lib64/libjemalloc5.so
+++ b/linux_musl-x86/lib64/libjemalloc5.so
Binary files differ
diff --git a/linux_musl-x86/lib64/liblog.so b/linux_musl-x86/lib64/liblog.so
index 34df19d..c57784c 100755
--- a/linux_musl-x86/lib64/liblog.so
+++ b/linux_musl-x86/lib64/liblog.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libnl.so b/linux_musl-x86/lib64/libnl.so
index 648772a..192daee 100755
--- a/linux_musl-x86/lib64/libnl.so
+++ b/linux_musl-x86/lib64/libnl.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libprotobuf-cpp-full.so b/linux_musl-x86/lib64/libprotobuf-cpp-full.so
index a2d1ecf..c0cf24e 100755
--- a/linux_musl-x86/lib64/libprotobuf-cpp-full.so
+++ b/linux_musl-x86/lib64/libprotobuf-cpp-full.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libsqlite.so b/linux_musl-x86/lib64/libsqlite.so
index 4f3d8f6..92fd373 100755
--- a/linux_musl-x86/lib64/libsqlite.so
+++ b/linux_musl-x86/lib64/libsqlite.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libz-host.so b/linux_musl-x86/lib64/libz-host.so
index 013a5b2..dcd6bc0 100755
--- a/linux_musl-x86/lib64/libz-host.so
+++ b/linux_musl-x86/lib64/libz-host.so
Binary files differ
diff --git a/linux_musl-x86/lib64/libziparchive.so b/linux_musl-x86/lib64/libziparchive.so
index 015fc25..60949a9 100755
--- a/linux_musl-x86/lib64/libziparchive.so
+++ b/linux_musl-x86/lib64/libziparchive.so
Binary files differ
diff --git a/manifest.xml b/manifest.xml
index 026382f..056749e 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -5,13 +5,13 @@
 
   <default remote="aosp" revision="build-tools-release" sync-j="4" />
 
-  <project name="platform/build" path="build/make" revision="a732827c69b1f0bed6346505700acbe673df4f45" upstream="build-tools-release">
+  <project name="platform/build" path="build/make" revision="8ae3c37912d77453e0cfcba55da1a34992932078" upstream="build-tools-release">
     <linkfile dest="build/tools" src="tools" />
 </project>
 
-  <project name="platform/build/blueprint" path="build/blueprint" revision="534ae5cc77676e734f9a6658f48f6b55357c29fa" upstream="build-tools-release" />
+  <project name="platform/build/blueprint" path="build/blueprint" revision="8c59bccaf2bf9588bb6c73ab4db6da201f1e3e8d" upstream="build-tools-release" />
 
-  <project name="platform/build/soong" path="build/soong" revision="51efa0bc413bcf22cbaedf627421947077d0d19f" upstream="build-tools-release">
+  <project name="platform/build/soong" path="build/soong" revision="35ca50c367fa1bb5ecc8f68807af08478fe5a9fe" upstream="build-tools-release">
     <linkfile dest="Android.bp" src="root.bp" />
 
     <linkfile dest="bootstrap.bash" src="bootstrap.bash" />
@@ -19,11 +19,11 @@
 
   <project name="platform/external/golang-protobuf" path="external/golang-protobuf" revision="1d4a1b807962dbec87fc593e68b0ed20619504ce" upstream="build-tools-release" />
 
-  <project clone-depth="1" name="platform/prebuilts/build-tools" path="prebuilts/build-tools" revision="4c35c8228a5caa4a46b7ff9b3cb3bb5664b7b186" upstream="build-tools-release" />
+  <project clone-depth="1" name="platform/prebuilts/build-tools" path="prebuilts/build-tools" revision="5faa472fd90a6f8b74009f10c48d6870f7a9cd94" upstream="build-tools-release" />
 
   <project clone-depth="1" groups="pdk" name="platform/prebuilts/remoteexecution-client" path="prebuilts/remoteexecution-client" revision="5dcada3170c979d617c46192c44c55a7762aabdb" upstream="build-tools-release" />
 
-  <project clone-depth="1" groups="linux" name="platform/prebuilts/clang/host/linux-x86" path="prebuilts/clang/host/linux-x86" revision="e9ac327a18797eff95f581f8868990b63fede493" upstream="build-tools-release" />
+  <project clone-depth="1" groups="linux" name="platform/prebuilts/clang/host/linux-x86" path="prebuilts/clang/host/linux-x86" revision="9aa4d140eb5f95f761107f7408cee1c563ac34a1" upstream="build-tools-release" />
 
   <project clone-depth="1" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8" revision="7454fb3d3249c268b7e61a6551e4a17dfd031ea9" upstream="build-tools-release" />
 
@@ -35,7 +35,7 @@
 
   <project clone-depth="1" groups="linux" name="platform/prebuilts/ninja/linux-x86" path="prebuilts/ninja/linux-x86" revision="cfaa2ca50f534ec2945c2587ffa119519268efad" upstream="build-tools-release" />
 
-  <project clone-depth="1" groups="darwin" name="platform/prebuilts/clang/host/darwin-x86" path="prebuilts/clang/host/darwin-x86" revision="23822d84a740a310cbb90bc6e3aa4397022a6409" upstream="build-tools-release" />
+  <project clone-depth="1" groups="darwin" name="platform/prebuilts/clang/host/darwin-x86" path="prebuilts/clang/host/darwin-x86" revision="68442395633f4adb1dda46287af789fe699c2c75" upstream="build-tools-release" />
 
   <project clone-depth="1" groups="darwin" name="platform/prebuilts/gcc/darwin-x86/host/headers" path="prebuilts/gcc/darwin-x86/host/headers" revision="4ac4f7cc41cf3c9e36fc3d6cf37fd1cfa9587a68" upstream="build-tools-release" />
 
@@ -61,9 +61,9 @@
 
   <project clone-depth="1" groups="pdk,tools" name="platform/prebuilts/tools" path="prebuilts/tools" revision="c3c160abf40cad1f0b12ae8ecba5acecb99e9674" upstream="build-tools-release" />
 
-  <project name="platform/bionic" path="bionic" revision="bcdc1834b5d812ce22456f8e0ff10cab3ecc8a86" upstream="build-tools-release" />
+  <project name="platform/bionic" path="bionic" revision="c093e0919f6d48f404d8d9b7b45963c030ad1924" upstream="build-tools-release" />
 
-  <project name="platform/development" path="development" revision="5fa095a623ae1102d81487c9b34a3e8b20fada11" upstream="build-tools-release" />
+  <project name="platform/development" path="development" revision="75d8d84d594e6d0de29151552ae4d9a33f61d31a" upstream="build-tools-release" />
 
   <project name="platform/external/arm-optimized-routines" path="external/arm-optimized-routines" revision="1c9813378c5dd9770241459eb61a4a039e026c6b" upstream="build-tools-release" />
 
@@ -111,7 +111,7 @@
 
   <project name="platform/external/guava" path="external/guava" revision="cea8b35c5ef589dc9ceff02bc8e85f6e8b721fb9" upstream="build-tools-release" />
 
-  <project name="platform/external/icu" path="external/icu" revision="64da1a181fb00b6b376e9a640dffd3ab6a89c095" upstream="build-tools-release" />
+  <project name="platform/external/icu" path="external/icu" revision="2fe8eaded815eebf7c309435224140af71b37dc2" upstream="build-tools-release" />
 
   <project name="platform/external/javapoet" path="external/javapoet" revision="d274ed4f3e04713ec752625c446b9f59daaa80bb" upstream="build-tools-release" />
 
@@ -147,17 +147,17 @@
 
   <project name="platform/external/safe-iop" path="external/safe-iop" revision="b805514f31a231a0e78a18f296c0454fcadead1a" upstream="build-tools-release" />
 
-  <project name="platform/external/selinux" path="external/selinux" revision="d77195538b0f4e28e444f7d3b98a6382d9f9c69d" upstream="build-tools-release" />
+  <project name="platform/external/selinux" path="external/selinux" revision="2fe4fad491aa904a84e093f44a807931fed46625" upstream="build-tools-release" />
 
   <project name="platform/external/sqlite" path="external/sqlite" revision="dec725a9d4d6a4da79ccf554bda224a461eeded5" upstream="build-tools-release" />
 
   <project name="platform/external/starlark-go" path="external/starlark-go" revision="dfe047847e867d4b297b4524a129e169484d8c42" upstream="build-tools-release" />
 
-  <project name="platform/external/zlib" path="external/zlib" revision="813594e30898f98ccc7bfc87b7d9819ce9665b72" upstream="build-tools-release" />
+  <project name="platform/external/zlib" path="external/zlib" revision="de355433d43a3449a3e77f63b074a10c9197aaec" upstream="build-tools-release" />
 
   <project name="platform/external/zopfli" path="external/zopfli" revision="cf3f34689a36a959d4578e82adb46532e38c2eaa" upstream="build-tools-release" />
 
-  <project name="platform/system/core" path="system/core" revision="1e74fb535906d47e59ec05b91e18bbad46de1680" upstream="build-tools-release" />
+  <project name="platform/system/core" path="system/core" revision="212844d1fe146b6d8dd8a89e33a729ae4f81ac8a" upstream="build-tools-release" />
 
   <project name="platform/system/libbase" path="system/libbase" revision="a6c75ad3b52211a9368fda383b535c30f5c5ca58" upstream="build-tools-release" />
 
@@ -173,7 +173,7 @@
 
   <project name="platform/test/app_compat/csuite" path="test/app_compat/csuite" revision="5387d15c213eb1a3366bae2545ad8d3f790643d3" upstream="build-tools-release" />
 
-  <project name="platform/art" path="art" revision="b40387e8d4dcaf13c8b4b5037988546b9c8129cd" upstream="build-tools-release" />
+  <project name="platform/art" path="art" revision="a493a590502347420215c22ee9f2e70592c36e7f" upstream="build-tools-release" />
 
   <project name="platform/build/kati" path="build/kati" revision="6ad4268491b968b4cb257aeeb8c6a605ea8af8bf" upstream="build-tools-release" />
 
@@ -181,7 +181,7 @@
 
   <project name="platform/external/bc" path="external/bc" revision="830c78bfc070f6f019571b2682c7892604561cba" upstream="build-tools-release" />
 
-  <project name="platform/external/bison" path="external/bison" revision="661d941d054e51ed48d0683a643f5842051f4bba" upstream="build-tools-release" />
+  <project name="platform/external/bison" path="external/bison" revision="d868ebf0b94600d99735f2bd4a77bc9245ce11c4" upstream="build-tools-release" />
 
   <project name="platform/external/bloaty" path="external/bloaty" revision="4e97ca09798800c00d8887d6b63992669fb1a631" upstream="build-tools-release" />
 
@@ -207,9 +207,9 @@
 
   <project name="platform/external/turbine" path="external/turbine" revision="097e956e80b1ae0668ea105618d71087159f4647" upstream="build-tools-release" />
 
-  <project name="platform/system/tools/aidl" path="system/tools/aidl" revision="46c272b63d5ba1d952b3cef1defcfe0128a91b40" upstream="build-tools-release" />
+  <project name="platform/system/tools/aidl" path="system/tools/aidl" revision="ec2a6e39f6a40e5c51c5aead3b953dda77cd33ea" upstream="build-tools-release" />
 
-  <project name="platform/system/tools/hidl" path="system/tools/hidl" revision="3de18409b3f9d3cff57b4b7875cf80160a78ce83" upstream="build-tools-release" />
+  <project name="platform/system/tools/hidl" path="system/tools/hidl" revision="66102d7eeaf4f1206d8f3b81071b9e76736a0097" upstream="build-tools-release" />
 
   <project name="toolchain/go" revision="01b90271bfe5ae1e2766f2c8f1272e6458f3918e" upstream="build-tools-release" />
 
diff --git a/sysroots/i686-linux-musl/lib/Scrt1-real.o b/sysroots/i686-linux-musl/lib/Scrt1-real.o
index ab5abc4..0b924ce 100644
--- a/sysroots/i686-linux-musl/lib/Scrt1-real.o
+++ b/sysroots/i686-linux-musl/lib/Scrt1-real.o
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/crt1.o b/sysroots/i686-linux-musl/lib/crt1.o
index caff96e..85b7f9b 100644
--- a/sysroots/i686-linux-musl/lib/crt1.o
+++ b/sysroots/i686-linux-musl/lib/crt1.o
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/crti.o b/sysroots/i686-linux-musl/lib/crti.o
index abe46e3..463d185 100644
--- a/sysroots/i686-linux-musl/lib/crti.o
+++ b/sysroots/i686-linux-musl/lib/crti.o
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/crtn.o b/sysroots/i686-linux-musl/lib/crtn.o
index bdab425..23f14a8 100644
--- a/sysroots/i686-linux-musl/lib/crtn.o
+++ b/sysroots/i686-linux-musl/lib/crtn.o
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/libc++.so b/sysroots/i686-linux-musl/lib/libc++.so
index a532cd9..a2930c6 100755
--- a/sysroots/i686-linux-musl/lib/libc++.so
+++ b/sysroots/i686-linux-musl/lib/libc++.so
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/libc++abi.a b/sysroots/i686-linux-musl/lib/libc++abi.a
index e2d459a..ce740ec 100644
--- a/sysroots/i686-linux-musl/lib/libc++abi.a
+++ b/sysroots/i686-linux-musl/lib/libc++abi.a
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/libc.a b/sysroots/i686-linux-musl/lib/libc.a
index 080cd09..84fd5f6 100644
--- a/sysroots/i686-linux-musl/lib/libc.a
+++ b/sysroots/i686-linux-musl/lib/libc.a
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/libc_musl.so b/sysroots/i686-linux-musl/lib/libc_musl.so
index 8d8677d..0d4cc8b 100755
--- a/sysroots/i686-linux-musl/lib/libc_musl.so
+++ b/sysroots/i686-linux-musl/lib/libc_musl.so
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/libc_musl_linker_object.o b/sysroots/i686-linux-musl/lib/libc_musl_linker_object.o
index ef58116..f15d60a 100644
--- a/sysroots/i686-linux-musl/lib/libc_musl_linker_object.o
+++ b/sysroots/i686-linux-musl/lib/libc_musl_linker_object.o
Binary files differ
diff --git a/sysroots/i686-linux-musl/lib/linker.script b/sysroots/i686-linux-musl/lib/linker.script
index 03bb310..5e42d51 100755
--- a/sysroots/i686-linux-musl/lib/linker.script
+++ b/sysroots/i686-linux-musl/lib/linker.script
@@ -6,10 +6,10 @@
   .linker_rx 0x48aa0 : {
     KEEP(*(.linker_rx));
   }
-  .linker_rw 0x124450 : {
+  .linker_rw 0x124570 : {
     KEEP(*(.linker_rw));
   }
-  .linker_rw2 0x1258b0 : {
+  .linker_rw2 0x1259d0 : {
     KEEP(*(.linker_rw2));
   }
   /DISCARD/ : { *(.interp) }
diff --git a/sysroots/i686-linux-musl/lib/rcrt1.o b/sysroots/i686-linux-musl/lib/rcrt1.o
index 4f52e92..d851a77 100644
--- a/sysroots/i686-linux-musl/lib/rcrt1.o
+++ b/sysroots/i686-linux-musl/lib/rcrt1.o
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/Scrt1-real.o b/sysroots/x86_64-linux-musl/lib/Scrt1-real.o
index 17e6a60..513deaf 100644
--- a/sysroots/x86_64-linux-musl/lib/Scrt1-real.o
+++ b/sysroots/x86_64-linux-musl/lib/Scrt1-real.o
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/crt1.o b/sysroots/x86_64-linux-musl/lib/crt1.o
index 99b5f7d..4b30451 100644
--- a/sysroots/x86_64-linux-musl/lib/crt1.o
+++ b/sysroots/x86_64-linux-musl/lib/crt1.o
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/crti.o b/sysroots/x86_64-linux-musl/lib/crti.o
index ad6a291..55a4ffc 100644
--- a/sysroots/x86_64-linux-musl/lib/crti.o
+++ b/sysroots/x86_64-linux-musl/lib/crti.o
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/crtn.o b/sysroots/x86_64-linux-musl/lib/crtn.o
index b397495..af02170 100644
--- a/sysroots/x86_64-linux-musl/lib/crtn.o
+++ b/sysroots/x86_64-linux-musl/lib/crtn.o
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/libc++.so b/sysroots/x86_64-linux-musl/lib/libc++.so
index 212292b..6b265ab 100755
--- a/sysroots/x86_64-linux-musl/lib/libc++.so
+++ b/sysroots/x86_64-linux-musl/lib/libc++.so
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/libc++abi.a b/sysroots/x86_64-linux-musl/lib/libc++abi.a
index 84c1384..2747b58 100644
--- a/sysroots/x86_64-linux-musl/lib/libc++abi.a
+++ b/sysroots/x86_64-linux-musl/lib/libc++abi.a
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/libc.a b/sysroots/x86_64-linux-musl/lib/libc.a
index aefcc39..3b5f525 100644
--- a/sysroots/x86_64-linux-musl/lib/libc.a
+++ b/sysroots/x86_64-linux-musl/lib/libc.a
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/libc_musl.so b/sysroots/x86_64-linux-musl/lib/libc_musl.so
index fcf6794..ba6025f 100755
--- a/sysroots/x86_64-linux-musl/lib/libc_musl.so
+++ b/sysroots/x86_64-linux-musl/lib/libc_musl.so
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/libc_musl_linker_object.o b/sysroots/x86_64-linux-musl/lib/libc_musl_linker_object.o
index 4104f6c..1cef9c0 100644
--- a/sysroots/x86_64-linux-musl/lib/libc_musl_linker_object.o
+++ b/sysroots/x86_64-linux-musl/lib/libc_musl_linker_object.o
Binary files differ
diff --git a/sysroots/x86_64-linux-musl/lib/linker.script b/sysroots/x86_64-linux-musl/lib/linker.script
index 1680ee3..f57d833 100755
--- a/sysroots/x86_64-linux-musl/lib/linker.script
+++ b/sysroots/x86_64-linux-musl/lib/linker.script
@@ -6,10 +6,10 @@
   .linker_rx 0x4df44 : {
     KEEP(*(.linker_rx));
   }
-  .linker_rw 0x116eb0 : {
+  .linker_rw 0x116f50 : {
     KEEP(*(.linker_rw));
   }
-  .linker_rw2 0x118580 : {
+  .linker_rw2 0x118620 : {
     KEEP(*(.linker_rw2));
   }
   /DISCARD/ : { *(.interp) }
diff --git a/sysroots/x86_64-linux-musl/lib/rcrt1.o b/sysroots/x86_64-linux-musl/lib/rcrt1.o
index 00825a7..1716ec2 100644
--- a/sysroots/x86_64-linux-musl/lib/rcrt1.o
+++ b/sysroots/x86_64-linux-musl/lib/rcrt1.o
Binary files differ