Upgrade bison from 2.3 to 2.7

See README.android for how the upgrade was done.

Bug: 8517572
Change-Id: I1e42ab59ff385130a7e488371c6058a13add244d
diff --git a/src/AnnotationList.c b/src/AnnotationList.c
new file mode 100644
index 0000000..4c1e0ae
--- /dev/null
+++ b/src/AnnotationList.c
@@ -0,0 +1,807 @@
+/* IELR's inadequacy annotation list.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include "AnnotationList.h"
+#include "lalr.h"
+#include "ielr.h"
+
+/**
+ * \pre
+ *   - <tt>annotations_obstackp != NULL</tt>.
+ * \post
+ *   - \c result is a new \c AnnotationList with one node whose:
+ *     - \c inadequacyNode member is \c NULL.
+ *     - \c contributions member is allocated with \c contribution_count
+ *       uninitialized elements.
+ *   - All memory was allocated on \c annotations_obstackp.
+ */
+static AnnotationList*
+AnnotationList__alloc_on_obstack (ContributionIndex contribution_count,
+                                  struct obstack *annotations_obstackp)
+{
+  AnnotationList *result;
+  size_t contributions_size =
+    contribution_count * sizeof result->contributions[0];
+  result = obstack_alloc (annotations_obstackp,
+                          offsetof (AnnotationList, contributions)
+                          + contributions_size);
+  result->next = NULL;
+  result->inadequacyNode = NULL;
+  return result;
+}
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - <tt>0 <= ci < self->inadequacyNode->contributionCount</tt>.
+ * \post
+ *   - \c result = true iff contribution \c ci in \c self represents an
+ *     "always" contribution.
+ */
+static bool
+AnnotationList__isContributionAlways (AnnotationList const *self,
+                                      ContributionIndex ci)
+{
+  aver (0 <= ci && ci < self->inadequacyNode->contributionCount);
+  return self->contributions[ci] == NULL;
+}
+
+/**
+ * \pre
+ *   - \c self is a single node.
+ *   - \c self annotates the same state as every other node in \c list, and
+ *     that state has \c nitems kernel items.
+ * \post
+ *   - If the list \c list already contains an identical annotation to \c self,
+ *     \c self was discarded, \c result is false, and the caller is responsible
+ *     for the memory of \c self.
+ *   - Otherwise, \c list now contains the node \c self, \c result is true, and
+ *     \c list assumes responsibility for the memory of \c self.
+ *   - The sort in \c list is:
+ *     - Sort in reverse order on the unique ID of the associated
+ *       inadequacy node.  Because these IDs are assigned in ascending
+ *       order, this should mean that the insertion position within an
+ *       annotation list is usually near the beginning with other
+ *       annotations associated with the same inadequacy.
+ *     - Next, sort on the first contribution that is different as follows:
+ *       - Sort an always-contribution before a never-contribution before a
+ *         potential-contribution.
+ *       - Two always-contributions are identical.
+ *       - Two never-contributions are identical.
+ *       - For two potential-contributions, sort on the contributions' kernel
+ *         item bitsets interpreted as binary numbers.
+ *  - The sorting has a few effects:
+ *    - It accelerates elimination of identical annotations during insertion.
+ *    - It determines how the output of \c AnnotationList__debug is sorted.
+ *    - Other than that, it's probably not important.
+ */
+static bool
+AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
+                            size_t nitems)
+{
+  AnnotationList **node;
+  for (node = list; *node; node = &(*node)->next)
+    {
+      int cmp = 0;
+      ContributionIndex ci;
+      if (self->inadequacyNode->id < (*node)->inadequacyNode->id)
+        cmp = 1;
+      else if ((*node)->inadequacyNode->id < self->inadequacyNode->id)
+        cmp = -1;
+      else
+        for (ci = 0;
+             cmp == 0 && ci < self->inadequacyNode->contributionCount;
+             ++ci)
+          {
+            if (AnnotationList__isContributionAlways (self, ci))
+              {
+                if (!AnnotationList__isContributionAlways (*node, ci))
+                  cmp = -1;
+              }
+            else if (AnnotationList__isContributionAlways (*node, ci))
+              cmp = 1;
+            else
+              {
+                size_t item;
+                for (item = 0; cmp == 0 && item < nitems; ++item)
+                  {
+                    if (!Sbitset__test (self->contributions[ci], item))
+                      {
+                        if (Sbitset__test ((*node)->contributions[ci], item))
+                          cmp = -1;
+                      }
+                    else if (!Sbitset__test ((*node)->contributions[ci], item))
+                      cmp = 1;
+                  }
+              }
+          }
+      if (cmp < 0)
+        {
+          self->next = *node;
+          *node = self;
+          break;
+        }
+      else if (cmp == 0)
+        {
+          self = NULL;
+          break;
+        }
+    }
+  if (!*node)
+    *node = self;
+  return self != NULL;
+}
+
+static bitset
+AnnotationList__compute_shift_tokens (transitions *trans)
+{
+  bitset shift_tokens = bitset_create (ntokens, BITSET_FIXED);
+  int i;
+  FOR_EACH_SHIFT (trans, i)
+    bitset_set (shift_tokens, TRANSITION_SYMBOL (trans, i));
+  return shift_tokens;
+}
+
+static bitset
+AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
+                                           reductions *reds)
+{
+  bitset conflicted_tokens = bitset_create (ntokens, BITSET_FIXED);
+  bitset conflicted_tokens_rule = bitset_create (ntokens, BITSET_FIXED);
+  bitset tokens = bitset_create (ntokens, BITSET_FIXED);
+  int i;
+
+  bitset_copy (tokens, shift_tokens);
+  for (i = 0; i < reds->num; ++i)
+    {
+      bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]);
+      bitset_or (conflicted_tokens,
+                 conflicted_tokens, conflicted_tokens_rule);
+      bitset_or (tokens, tokens, reds->lookahead_tokens[i]);
+      /* Check that rules are sorted on rule number or the next step in
+         AnnotationList__compute_from_inadequacies will misbehave.  */
+      aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
+    }
+
+  bitset_free (tokens);
+  bitset_free (conflicted_tokens_rule);
+
+  return conflicted_tokens;
+}
+
+static bool
+AnnotationList__compute_lhs_contributions (state *s, rule *the_rule,
+                                           symbol_number conflicted_token,
+                                           bitsetv follow_kernel_items,
+                                           bitsetv always_follows,
+                                           state ***predecessors,
+                                           bitset **item_lookahead_sets,
+                                           Sbitset *items,
+                                           struct obstack
+                                             *annotations_obstackp)
+{
+  goto_number lhs_goto = map_goto (s->number, the_rule->lhs->number);
+  if (bitset_test (always_follows[lhs_goto], conflicted_token))
+    return true;
+  *items = Sbitset__new_on_obstack (s->nitems, annotations_obstackp);
+  {
+    bitset_iterator biter_item;
+    bitset_bindex item;
+    BITSET_FOR_EACH (biter_item, follow_kernel_items[lhs_goto], item, 0)
+      if (ielr_item_has_lookahead (s, 0, item, conflicted_token,
+                                   predecessors, item_lookahead_sets))
+        Sbitset__set (*items, item);
+  }
+  return false;
+}
+
+static void
+AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
+                                               bitsetv follow_kernel_items,
+                                               bitsetv always_follows,
+                                               state ***predecessors,
+                                               bitset **item_lookahead_sets,
+                                               AnnotationList
+                                                 **annotation_lists,
+                                               AnnotationIndex
+                                                 *annotation_counts,
+                                               struct obstack
+                                                 *annotations_obstackp)
+{
+  state **predecessor;
+  for (predecessor = predecessors[s->number]; *predecessor; ++predecessor)
+    {
+      AnnotationList *annotation_node =
+        AnnotationList__alloc_on_obstack (
+          self->inadequacyNode->contributionCount, annotations_obstackp);
+      annotation_node->inadequacyNode = self->inadequacyNode;
+      bool potential_contribution = false;
+      bitset *lookaheads = NULL;
+      {
+        ContributionIndex ci;
+        for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
+          {
+            symbol_number contribution_token =
+              InadequacyList__getContributionToken (self->inadequacyNode, ci)
+                ->number;
+            if (AnnotationList__isContributionAlways (self, ci))
+              {
+                annotation_node->contributions[ci] = NULL;
+                continue;
+              }
+            annotation_node->contributions[ci] =
+              Sbitset__new_on_obstack ((*predecessor)->nitems,
+                                       annotations_obstackp);
+            {
+              size_t predecessor_item = 0;
+              Sbitset sbiter_item;
+              Sbitset__Index self_item;
+              SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
+                                 sbiter_item, self_item)
+                {
+                  /* If this kernel item is the beginning of a RHS, it must be
+                     the kernel item in the start state, and so it has an empty
+                     lookahead set.  Thus, it can't contribute to inadequacies,
+                     and so it should never have been identified as a
+                     contribution.  If, instead, this kernel item is the
+                     successor of the start state's kernel item, the lookahead
+                     set is still empty, and so it also should never have been
+                     identified as a contribution.  This situation is fortunate
+                     because we want to avoid the - 2 below in both cases.  */
+                  aver (s->items[self_item] > 1);
+                  /* If this kernel item is next to the beginning of the RHS,
+                     then check all of the predecessor's goto follows for the
+                     LHS.  */
+                  if (item_number_is_rule_number (ritem[s->items[self_item]
+                                                        - 2]))
+                    {
+                      Sbitset items;
+                      unsigned int rulei;
+                      for (rulei = s->items[self_item];
+                           !item_number_is_rule_number (ritem[rulei]);
+                           ++rulei)
+                        ;
+                      if (AnnotationList__compute_lhs_contributions (
+                            *predecessor,
+                            &rules[item_number_as_rule_number (ritem[rulei])],
+                            contribution_token,
+                            follow_kernel_items, always_follows, predecessors,
+                            item_lookahead_sets, &items, annotations_obstackp))
+                        {
+                          obstack_free (annotations_obstackp,
+                                        annotation_node->contributions[ci]);
+                          annotation_node->contributions[ci] = NULL;
+                          break;
+                        }
+                      else
+                        {
+                          Sbitset__or (annotation_node->contributions[ci],
+                                       annotation_node->contributions[ci],
+                                       items, (*predecessor)->nitems);
+                          obstack_free (annotations_obstackp, items);
+                        }
+                    }
+                  /* If this kernel item is later in the RHS, then check the
+                     predecessor item's lookahead set.  */
+                  else
+                    {
+                      /* We don't have to start the predecessor item search at
+                         the beginning every time because items from both
+                         states are sorted by their indices in ritem.  */
+                      for (;
+                           predecessor_item < (*predecessor)->nitems;
+                           ++predecessor_item)
+                        if ((*predecessor)->items[predecessor_item]
+                            == s->items[self_item] - 1)
+                          break;
+                      aver (predecessor_item != (*predecessor)->nitems);
+                      if (ielr_item_has_lookahead (*predecessor, 0,
+                                                   predecessor_item,
+                                                   contribution_token,
+                                                   predecessors,
+                                                   item_lookahead_sets))
+                        Sbitset__set (annotation_node->contributions[ci],
+                                      predecessor_item);
+                    }
+                }
+            }
+            if (annotation_node->contributions[ci])
+              {
+                Sbitset biter;
+                Sbitset__Index i;
+                SBITSET__FOR_EACH (annotation_node->contributions[ci],
+                                   (*predecessor)->nitems, biter, i)
+                  {
+                    potential_contribution = true;
+                    if (!lookaheads)
+                      {
+                        size_t j;
+                        lookaheads = xnmalloc ((*predecessor)->nitems,
+                                               sizeof *lookaheads);
+                        for (j = 0; j < (*predecessor)->nitems; ++j)
+                          lookaheads[j] = NULL;
+                      }
+                    if (!lookaheads[i])
+                      lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
+                    bitset_set (lookaheads[i], contribution_token);
+                  }
+              }
+          }
+      }
+
+      /* If the predecessor has any contributions besides just "always" and
+         "never" contributions:
+         - If the dominant contribution is split-stable, the annotation could
+           not affect merging on this predecessor state or its eventual
+           predecessor states.  Moreover, all contributions that affect
+           whether the dominant contribution remains dominant must be "always"
+           or "never" contributions in order for the dominant contribution to
+           be split-stable.  Thus, the dominant contribution computation result
+           in eventual successor states will not be affected by lookaheads
+           tracked for this predecessor state.  (Also, as in the isocore
+           compatibility test, we depend on the fact that isocores with equal
+           dominant contributions will have the same dominant contribution when
+           merged.  Otherwise, we might have to worry that the presence of a
+           potential contribution might somehow be the culprit of that behavior
+           and thus need to be tracked regardless of the split stability of the
+           dominant contribution.)  Thus, go ahead and discard the annotation
+           to save space now plus time during state splitting.
+         - Otherwise, record the annotation, and compute any resulting
+           annotations needed on predecessor states.  */
+      if (potential_contribution)
+        {
+          if (ContributionIndex__none
+              != AnnotationList__computeDominantContribution (
+                   annotation_node, (*predecessor)->nitems, lookaheads, true))
+            {
+              obstack_free (annotations_obstackp, annotation_node);
+              annotation_node = NULL;
+            }
+          {
+            size_t i;
+            for (i = 0; i < (*predecessor)->nitems; ++i)
+              if (lookaheads[i])
+                bitset_free (lookaheads[i]);
+            free (lookaheads);
+          }
+          if (annotation_node)
+            {
+              if (AnnotationList__insertInto (annotation_node,
+                                              &annotation_lists[(*predecessor)
+                                                                ->number],
+                                              (*predecessor)->nitems))
+                {
+                  ++annotation_counts[(*predecessor)->number];
+                  AnnotationList__computePredecessorAnnotations (
+                    annotation_node, *predecessor,
+                    follow_kernel_items, always_follows, predecessors,
+                    item_lookahead_sets, annotation_lists, annotation_counts,
+                    annotations_obstackp);
+                }
+              else
+                obstack_free (annotations_obstackp, annotation_node);
+            }
+        }
+      else
+        obstack_free (annotations_obstackp, annotation_node);
+    }
+}
+
+void
+AnnotationList__compute_from_inadequacies (
+  state *s, bitsetv follow_kernel_items, bitsetv always_follows,
+  state ***predecessors, bitset **item_lookahead_sets,
+  InadequacyList **inadequacy_lists, AnnotationList **annotation_lists,
+  AnnotationIndex *annotation_counts,
+  ContributionIndex *max_contributionsp,
+  struct obstack *annotations_obstackp,
+  InadequacyListNodeCount *inadequacy_list_node_count)
+{
+  bitsetv all_lookaheads;
+  bitset shift_tokens;
+  bitset conflicted_tokens;
+  bitset_iterator biter_conflict;
+  bitset_bindex conflicted_token;
+
+  /* Return an empty list if s->lookahead_tokens = NULL.  */
+  if (s->consistent)
+    return;
+
+  all_lookaheads = bitsetv_create (s->nitems, ntokens, BITSET_FIXED);
+  bitsetv_ones (all_lookaheads);
+  shift_tokens = AnnotationList__compute_shift_tokens (s->transitions);
+  conflicted_tokens =
+    AnnotationList__compute_conflicted_tokens (shift_tokens, s->reductions);
+
+  /* Add an inadequacy annotation for each conflicted_token.  */
+  BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0)
+    {
+      AnnotationList *annotation_node;
+      /* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient?  Now
+         or convert it inside InadequacyList__new_conflict?  */
+      bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
+      ContributionIndex contribution_count = 0;
+      bool potential_contribution = false;
+
+      /* Allocate the annotation node.  */
+      {
+        int rule_i;
+        for (rule_i = 0; rule_i < s->reductions->num; ++rule_i)
+          if (bitset_test (s->reductions->lookahead_tokens[rule_i],
+                           conflicted_token))
+            ++contribution_count;
+        if (bitset_test (shift_tokens, conflicted_token))
+          ++contribution_count;
+        annotation_node =
+          AnnotationList__alloc_on_obstack (contribution_count,
+                                            annotations_obstackp);
+      }
+
+      /* Add a contribution for each reduction that has conflicted_token as a
+         lookahead.  */
+      {
+        ContributionIndex ci = 0;
+        int item_i = 0;
+        int rule_i;
+        for (rule_i = 0; rule_i < s->reductions->num; ++rule_i)
+          {
+            rule *the_rule = s->reductions->rules[rule_i];
+            if (bitset_test (s->reductions->lookahead_tokens[rule_i],
+                             conflicted_token))
+              {
+                bitset_set (actions, rule_i);
+                /* If this reduction is on a kernel item, just add it.  */
+                if (!item_number_is_rule_number (the_rule->rhs[0]))
+                  {
+                    annotation_node->contributions[ci] =
+                      Sbitset__new_on_obstack (s->nitems,
+                                               annotations_obstackp);
+                    /* Catch item_i up to rule_i.  This works because both are
+                       sorted on rule number.  */
+                    while (!item_number_is_rule_number (
+                             ritem[s->items[item_i]])
+                           || item_number_as_rule_number (
+                                ritem[s->items[item_i]])
+                              != the_rule->number)
+                      {
+                        ++item_i;
+                        aver (item_i < s->nitems);
+                      }
+                    Sbitset__set (annotation_node->contributions[ci], item_i);
+                  }
+                /* Otherwise, add the kernel items whose lookahead sets
+                   contribute the conflicted token to this reduction's
+                   lookahead set.  */
+                else if (AnnotationList__compute_lhs_contributions (
+                           s, the_rule, conflicted_token, follow_kernel_items,
+                           always_follows, predecessors, item_lookahead_sets,
+                           &annotation_node->contributions[ci],
+                           annotations_obstackp))
+                  {
+                    annotation_node->contributions[ci++] = NULL;
+                    continue;
+                  }
+                /* The lookahead token has to come from somewhere.  */
+                aver (!Sbitset__isEmpty (annotation_node->contributions[ci],
+                                         s->nitems));
+                ++ci;
+                potential_contribution = true;
+              }
+          }
+      }
+
+      /* If there are any contributions besides just "always" contributions:
+         - If there's also a shift contribution, record it.
+         - If the dominant contribution is split-stable, then the annotation
+           could not affect merging, so go ahead and discard the annotation and
+           the inadequacy to save space now plus time during state splitting.
+         - Otherwise, record the annotation and the inadequacy, and compute any
+           resulting annotations needed on predecessor states.  */
+      if (potential_contribution)
+        {
+          if (bitset_test (shift_tokens, conflicted_token))
+            {
+              bitset_set (actions, s->reductions->num);
+              annotation_node->contributions[contribution_count - 1] = NULL;
+            }
+          {
+            InadequacyList *conflict_node =
+              InadequacyList__new_conflict (
+                s, symbols[conflicted_token], actions,
+                inadequacy_list_node_count);
+            actions = NULL;
+            annotation_node->inadequacyNode = conflict_node;
+            if (ContributionIndex__none
+                != AnnotationList__computeDominantContribution (
+                     annotation_node, s->nitems, all_lookaheads, true))
+              {
+                obstack_free (annotations_obstackp, annotation_node);
+                InadequacyList__delete (conflict_node);
+              }
+            else
+              {
+                InadequacyList__prependTo (conflict_node,
+                                           &inadequacy_lists[s->number]);
+                aver (AnnotationList__insertInto (
+                        annotation_node, &annotation_lists[s->number],
+                        s->nitems));
+                /* This aver makes sure the
+                   AnnotationList__computeDominantContribution check above
+                   does discard annotations in the simplest case of a S/R
+                   conflict with no token precedence.  */
+                aver (!bitset_test (shift_tokens, conflicted_token)
+                      || symbols[conflicted_token]->prec);
+                ++annotation_counts[s->number];
+                if (contribution_count > *max_contributionsp)
+                  *max_contributionsp = contribution_count;
+                AnnotationList__computePredecessorAnnotations (
+                  annotation_node, s,
+                  follow_kernel_items, always_follows, predecessors,
+                  item_lookahead_sets, annotation_lists, annotation_counts,
+                  annotations_obstackp);
+              }
+          }
+        }
+      else
+        {
+          bitset_free (actions);
+          obstack_free (annotations_obstackp, annotation_node);
+        }
+    }
+
+  bitsetv_free (all_lookaheads);
+  bitset_free (shift_tokens);
+  bitset_free (conflicted_tokens);
+}
+
+void
+AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
+{
+  AnnotationList const *a;
+  AnnotationIndex ai;
+  for (a = self, ai = 0; a; a = a->next, ++ai)
+    {
+      {
+        int j;
+        for (j = 0; j < spaces; ++j)
+          putc (' ', stderr);
+      }
+      fprintf (stderr, "Annotation %d (manifesting state %d):\n",
+               ai, a->inadequacyNode->manifestingState->number);
+      {
+        ContributionIndex ci;
+        bitset_bindex rulei = 0; /* init suppresses compiler warning */
+        rulei = bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
+        for (ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
+          {
+            symbol_number token =
+              InadequacyList__getContributionToken (a->inadequacyNode, ci)
+                ->number;
+            {
+              int j;
+              for (j = 0; j < spaces+2; ++j)
+                putc (' ', stderr);
+            }
+            if (ci == InadequacyList__getShiftContributionIndex (
+                        a->inadequacyNode))
+              fprintf (stderr, "Contributes shift of token %d.\n", token);
+            else
+              {
+                fprintf (stderr, "Contributes token %d", token);
+                aver (rulei != BITSET_BINDEX_MAX);
+                fprintf (stderr, " as lookahead, rule number %d",
+                         a->inadequacyNode->manifestingState
+                           ->reductions->rules[rulei]->number);
+                rulei =
+                  bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
+                               rulei+1);
+                if (AnnotationList__isContributionAlways (a, ci))
+                  fprintf (stderr, " always.");
+                else
+                  {
+                    fprintf (stderr, ", items: ");
+                    Sbitset__fprint (a->contributions[ci], nitems, stderr);
+                  }
+                fprintf (stderr, "\n");
+              }
+          }
+      }
+    }
+}
+
+void
+AnnotationList__computeLookaheadFilter (AnnotationList const *self,
+                                        size_t nitems,
+                                        bitsetv lookahead_filter)
+{
+  bitsetv_zero (lookahead_filter);
+  for (; self; self = self->next)
+    {
+      ContributionIndex ci;
+      for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
+        if (!AnnotationList__isContributionAlways (self, ci))
+          {
+            Sbitset__Index item;
+            Sbitset biter;
+            symbol_number token =
+              InadequacyList__getContributionToken (self->inadequacyNode, ci)
+                ->number;
+            SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
+              bitset_set (lookahead_filter[item], token);
+          }
+    }
+}
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - \c nitems is the number of kernel items in the LR(0) state that \c self
+ *     annotates.
+ *   - \c lookaheads describes the lookahead sets on the kernel items of some
+ *     isocore of the LR(0) state that \c self annotates.  Either:
+ *     - <tt>lookaheads = NULL</tt> only if the lookahead set on every kernel
+ *       item is empty.
+ *     - For any <tt>0 <= i < nitems</tt>, <tt>lookaheads[i]</tt> is either:
+ *       - \c NULL only if the lookahead set on kernel item \c i is empty.
+ *       - The (possibly empty) lookahead set on kernel item \c i.
+ *   - <tt>0 <= ci < self->inadequacyNode->contributionCount</tt>.
+ * \post
+ *   - \c result = true iff contribution \c ci in \c self is made by the state
+ *     described by \c lookaheads.
+ */
+static bool
+AnnotationList__stateMakesContribution (AnnotationList const *self,
+                                        size_t nitems, ContributionIndex ci,
+                                        bitset *lookaheads)
+{
+  if (AnnotationList__isContributionAlways (self, ci))
+    return true;
+  if (!lookaheads)
+    return false;
+  {
+    symbol_number token =
+      InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
+    Sbitset__Index item;
+    Sbitset biter;
+    SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
+      if (lookaheads[item] && bitset_test (lookaheads[item], token))
+        return true;
+  }
+  return false;
+}
+
+ContributionIndex
+AnnotationList__computeDominantContribution (AnnotationList const *self,
+                                             size_t nitems, bitset *lookaheads,
+                                             bool require_split_stable)
+{
+  symbol *token;
+  ContributionIndex const ci_shift =
+    InadequacyList__getShiftContributionIndex (self->inadequacyNode);
+
+  token = self->inadequacyNode->inadequacy.conflict.token;
+
+  /* S/R conflict.  */
+  if (ci_shift != ContributionIndex__none)
+    {
+      bool find_stable_domination_over_shift = false;
+      bool find_stable_error_action_domination = false;
+      {
+        ContributionIndex ci;
+        int actioni;
+        ContributionIndex ci_rr_dominator = ContributionIndex__none;
+        int shift_precedence = token->prec;
+
+        /* If the token has no precedence set, shift is always chosen.  */
+        if (!shift_precedence)
+          return ci_shift;
+
+        /* Figure out which reductions contribute, which of those would
+           dominate in a R/R comparison, and whether any reduction dominates
+           the shift so that the R/R comparison is actually needed.  */
+        for (ci = 0, actioni = bitset_first (self->inadequacyNode->inadequacy
+                                             .conflict.actions);
+             ci < self->inadequacyNode->contributionCount;
+             ++ci, actioni = bitset_next (self->inadequacyNode->inadequacy
+                                          .conflict.actions, actioni+1))
+          {
+            int reduce_precedence = 0;
+            if (ci == ci_shift)
+              continue;
+            {
+              rule *r = self->inadequacyNode->manifestingState
+                          ->reductions->rules[actioni];
+              if (r->prec)
+                reduce_precedence = r->prec->prec;
+            }
+            /* If there's no need to check whether this reduction actually
+               contributes because the shift eliminates it from the R/R
+               comparison anyway, continue to the next reduction.  */
+            if (reduce_precedence
+                && (reduce_precedence < shift_precedence
+                    || (reduce_precedence == shift_precedence
+                        && token->assoc == right_assoc)))
+              continue;
+            if (!AnnotationList__stateMakesContribution (self, nitems, ci,
+                                                         lookaheads))
+              continue;
+            /* This uneliminated reduction contributes, so see if it can cause
+               an error action.  */
+            if (reduce_precedence == shift_precedence
+                 && token->assoc == non_assoc)
+              {
+                /* It's not possible to find split-stable domination over
+                   shift after a potential %nonassoc.  */
+                if (find_stable_domination_over_shift)
+                  return ContributionIndex__none;
+                if (!require_split_stable
+                    || AnnotationList__isContributionAlways (self, ci))
+                  return ContributionIndex__error_action;
+                find_stable_error_action_domination = true;
+              }
+            /* Consider this uneliminated contributing reduction in the R/R
+               comparison.  */
+            if (ci_rr_dominator == ContributionIndex__none)
+              ci_rr_dominator = ci;
+            /* If precedence is set for this uneliminated contributing
+               reduction, it dominates the shift, so try to figure out which
+               reduction dominates the R/R comparison.  */
+            if (reduce_precedence)
+              {
+                /* It's not possible to find split-stable error action
+                   domination after a potential reduction.  */
+                if (find_stable_error_action_domination)
+                  return ContributionIndex__none;
+                if (!require_split_stable)
+                  return ci_rr_dominator;
+                if (!AnnotationList__isContributionAlways (self,
+                                                           ci_rr_dominator))
+                  return ContributionIndex__none;
+                if (AnnotationList__isContributionAlways (self, ci))
+                  return ci_rr_dominator;
+                find_stable_domination_over_shift = true;
+              }
+          }
+      }
+      if (find_stable_domination_over_shift
+          || find_stable_error_action_domination)
+        return ContributionIndex__none;
+      /* No reduce or error action domination found, so shift dominates.  */
+      return ci_shift;
+    }
+
+  /* R/R conflict, so the reduction with the lowest rule number dominates.
+     Fortunately, contributions are sorted by rule number.  */
+  {
+    ContributionIndex ci;
+    for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
+      if (AnnotationList__stateMakesContribution (self, nitems, ci,
+                                                  lookaheads))
+        {
+          if (require_split_stable
+              && !AnnotationList__isContributionAlways (self, ci))
+            return ContributionIndex__none;
+          return ci;
+        }
+  }
+  return ContributionIndex__none;
+}
diff --git a/src/AnnotationList.h b/src/AnnotationList.h
new file mode 100644
index 0000000..3088a83
--- /dev/null
+++ b/src/AnnotationList.h
@@ -0,0 +1,182 @@
+/* IELR's inadequacy annotation list.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef ANNOTATION_LIST_H_
+# define ANNOTATION_LIST_H_
+
+#include <bitsetv.h>
+#include "Sbitset.h"
+#include "InadequacyList.h"
+#include "state.h"
+
+typedef unsigned int AnnotationIndex;
+
+/**
+ * A node in a list of annotations on a particular LR(0) state.  Each
+ * annotation records how isocores of that LR(0) state might contribute to an
+ * individual inadequacy, which might manifest in a different state.  Don't
+ * break encapsulation by modifying the fields directly.  Use the provided
+ * interface functions.
+ */
+typedef struct AnnotationList
+{
+  /** The next node in the list or \c NULL if none.  */
+  struct AnnotationList *next;
+  /** The \c InadequacyList node describing how this inadequacy manifests.  */
+  InadequacyList *inadequacyNode;
+  /**
+   * List of how the "always", "never", and potential contributions of the
+   * inadequacy might be made by isocores of the annotated LR(0) state:
+   *   - The number of rows is the number of contributions.  That is,
+   *     <tt>AnnotationList::inadequacyNode->contributionCount</tt>.
+   *   - The token associated with contribution \c i is
+   *     <tt>InadequacyList__getContributionToken (AnnotationList::inadequacyNode, i)</tt>.
+   *   - Iff <tt>AnnotationList::contributions[i] = NULL</tt>, contribution
+   *     \c i is an "always" contribution.  That is, for every isocore of the
+   *     annotated LR(0) state, its core or the core of one its eventual
+   *     successors will definitely make this contribution to the inadequacy.
+   *     It may contribute by either:
+   *     - Creating a shift of contribution <tt>i</tt>'s token in the state
+   *       that can manifest the inadequacy.
+   *     - Propagating that token to the lookahead set of contribution
+   *       <tt>i</tt>'s reduction in the state that can manifest the
+   *       inadequacy.
+   *   - Otherwise:
+   *     - The number of columns in <tt>AnnotationList::contributions[i]</tt>
+   *       is the number of kernel items in any isocore of the annotated LR(0)
+   *       state.
+   *     - Iff <tt>AnnotationList::contributions[i]</tt> is empty, contribution
+   *       \c i is a "never" contribution.  That is, no isocore of the
+   *       annotated LR(0) state can make this contribution to the inadequacy.
+   *     - Otherwise, for each bit \c j that is set in
+   *       <tt>AnnotationList::contributions[i]</tt>, if the token associated
+   *       with contribution \c i is present in the lookahead set of kernel
+   *       item \c j of an isocore of the annotated LR(0) state, that isocore
+   *       will make contribution \c i to the inadequacy by propagating the
+   *       contribution's token to the lookahead set of the contribution's
+   *       reduction in the state that can manifest the inadequacy.
+   */
+  Sbitset contributions[1];
+} AnnotationList;
+
+/**
+ * \pre
+ *   - <tt>s != NULL</tt>.
+ *   - \c follow_kernel_items, \c always_follows, and \c predecessors were
+ *     computed by \c ielr_compute_auxiliary_tables.
+ *   - The size of each of \c annotation_lists and \c annotation_counts is
+ *     \c ::nstates.
+ *   - If no \c InadequacyList nodes are currently allocated for the
+ *     parser tables to which \c s belongs, then it is best if
+ *     <tt>*inadequacy_list_node_count</tt> is zero to avoid overflow.
+ *     Otherwise, <tt>*inadequacy_list_node_count</tt> has not been
+ *     modified by any function except
+ *     \c AnnotationList__compute_from_inadequacies since the invocation
+ *     of \c AnnotationList__compute_from_inadequacies that constructed
+ *     the first of the \c InadequacyList nodes currently allocated for
+ *     those parser tables.
+ * \post
+ *   - <tt>inadequacy_lists[s->number]</tt> now describes all inadequacies that
+ *     manifest in \c s.
+ *   - For every state <tt>states[i]</tt>, <tt>annotation_lists[i]</tt> now
+ *     contains all annotations associated with all inadequacies that manifest
+ *     in \c s.
+ *   - <tt>annotation_counts[i]</tt> was incremented by the number of new
+ *     annotations added to <tt>states[i]</tt>.
+ *   - <tt>*max_contributionsp</tt> is the higher of:
+ *     - The maximum number of contributions computed per annotation.
+ *     - <tt>*max_contributionsp \@pre</tt>.
+ *   - All memory for all new annotations was allocated on
+ *     \c annotations_obstackp.
+ */
+void
+AnnotationList__compute_from_inadequacies (
+  state *s, bitsetv follow_kernel_items, bitsetv always_follows,
+  state ***predecessors, bitset **item_lookahead_sets,
+  InadequacyList **inadequacy_lists, AnnotationList **annotation_lists,
+  AnnotationIndex *annotation_counts,
+  ContributionIndex *max_contributionsp,
+  struct obstack *annotations_obstackp,
+  InadequacyListNodeCount *inadequacy_list_node_count);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - \c nitems is the number of kernel items in the LR(0) state that every
+ *     node in the list \c self annotates.
+ * \post
+ *   - A textual representation of all nodes in the list \c self was printed to
+ *     stderr.  \c spaces spaces were printed before each line of the text.
+ */
+void AnnotationList__debug (AnnotationList const *self, size_t nitems,
+                            int spaces);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - \c nitems is the number of kernel items in the LR(0) state that \c self
+ *     annotates.
+ *   - The number of rows in \c lookahead_filter is at least \c nitems, and the
+ *     number of columns is \c ::ntokens.
+ * \post
+ *   - <tt>lookahead_filter[i][j]</tt> is set iff some annotation in the list
+ *     \c self lists token \c j in kernel item \c i as a contributor.
+ */
+void AnnotationList__computeLookaheadFilter (AnnotationList const *self,
+                                             size_t nitems,
+                                             bitsetv lookahead_filter);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - \c nitems is the number of kernel items in the LR(0) state that \c self
+ *     annotates.
+ *   - \c lookaheads describes the lookahead sets on the kernel items of some
+ *     isocore of the LR(0) state that \c self annotates.  Either:
+ *     - <tt>lookaheads = NULL</tt> only if the lookahead set on every kernel
+ *       item is empty.
+ *     - For any <tt>0 <= i < nitems</tt>, <tt>lookaheads[i]</tt> is either:
+ *       - \c NULL only if the lookahead set on kernel item \c i is empty.
+ *       - The (possibly empty) lookahead set on kernel item \c i.
+ * \post
+ *   - If <tt>require_split_stable = false</tt>, \c result = either:
+ *     - \c ContributionIndex__none iff the state described by \c lookaheads
+ *       makes none of the contributions in \c self.
+ *     - The index of the dominating contribution in \c self that is made by
+ *       that state.
+ *     - \c ContributionIndex__error_action to indicate that the inadequacy
+ *       manifests as a conflict and that a syntax error action (because of a
+ *       %nonassoc) dominates instead.
+ *   - Otherwise, \c result is the same as if <tt>require_split_stable =
+ *     false</tt> except that it is also \c ContributionIndex__none if there
+ *     are contributions made by the state but the dominating contribution is
+ *     not split-stable.  By split-stable, we mean that the dominating
+ *     contribution cannot change due to loss of one or more potential
+ *     contributions due to loss of lookaheads due to splitting of the state.
+ *   - After determining which contributions are actually made by the state,
+ *     the algorithm for determining which contribution dominates in the
+ *     conflict is intended to choose exactly the same action as conflicts.c
+ *     would choose... no matter how crazy conflicts.c's choice is.
+ */
+ContributionIndex
+AnnotationList__computeDominantContribution (AnnotationList const *self,
+                                             size_t nitems, bitset *lookaheads,
+                                             bool require_split_stable);
+
+#endif /* !ANNOTATION_LIST_H_ */
diff --git a/src/InadequacyList.c b/src/InadequacyList.c
new file mode 100644
index 0000000..838685b
--- /dev/null
+++ b/src/InadequacyList.c
@@ -0,0 +1,79 @@
+/* IELR's inadequacy list.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include "InadequacyList.h"
+
+ContributionIndex const ContributionIndex__none = -1;
+ContributionIndex const ContributionIndex__error_action = -2;
+
+InadequacyList *
+InadequacyList__new_conflict (state *manifesting_state, symbol *token,
+                              bitset actions,
+                              InadequacyListNodeCount *node_count)
+{
+  InadequacyList *result = xmalloc (sizeof *result);
+  result->id = (*node_count)++;
+  aver (*node_count != 0);
+  result->next = NULL;
+  result->manifestingState = manifesting_state;
+  result->contributionCount = bitset_count (actions);
+  result->inadequacy.conflict.token = token;
+  result->inadequacy.conflict.actions = actions;
+  return result;
+}
+
+void
+InadequacyList__delete (InadequacyList *self)
+{
+  while (self)
+    {
+      InadequacyList *node = self;
+      self = self->next;
+      bitset_free (node->inadequacy.conflict.actions);
+      free (node);
+    }
+}
+
+ContributionIndex
+InadequacyList__getShiftContributionIndex (InadequacyList const *self)
+{
+  if (!bitset_test (self->inadequacy.conflict.actions,
+                    self->manifestingState->reductions->num))
+    return ContributionIndex__none;
+  return self->contributionCount - 1;
+}
+
+symbol *
+InadequacyList__getContributionToken (InadequacyList const *self,
+                                      ContributionIndex i)
+{
+  aver (0 <= i && i < self->contributionCount);
+  return self->inadequacy.conflict.token;
+}
+
+void
+InadequacyList__prependTo (InadequacyList *self, InadequacyList **list)
+{
+  InadequacyList *head_old = *list;
+  *list = self;
+  self->next = head_old;
+}
diff --git a/src/InadequacyList.h b/src/InadequacyList.h
new file mode 100644
index 0000000..d8120dd
--- /dev/null
+++ b/src/InadequacyList.h
@@ -0,0 +1,156 @@
+/* IELR's inadequacy list.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef INADEQUACY_LIST_H_
+# define INADEQUACY_LIST_H_
+
+#include <bitset.h>
+#include "gram.h"
+#include "state.h"
+#include "symtab.h"
+
+/**
+ * A unique ID assigned to every \c InadequacyList node.
+ *
+ * This must remain unsigned so that the overflow check in
+ * \c InadequacyList__new_conflict works properly.
+ */
+typedef unsigned long long int InadequacyListNodeCount;
+
+/**
+ * For a conflict, each rule in the grammar can have at most one contributing
+ * reduction except that rule 0 cannot have any because the reduction on rule 0
+ * cannot have lookaheads.  For a conflict, exactly one shift can contribute.
+ * Thus the number of rules in the grammar is an upper bound on the number of
+ * possible contributions to any conflict.  The maximum number of possible
+ * items in a state is also an upper bound, but the \c nitems member of \c
+ * state is currently a \c size_t and thus, if changed, risks becoming out of
+ * sync with this type.  Whatever the type, it must support negatives for sake
+ * of the special values below.
+ */
+typedef rule_number ContributionIndex;
+
+/* Special \c ContributionIndex used to indicate null result when looking for a
+   contribution.  */
+extern ContributionIndex const ContributionIndex__none;
+
+/* Special \c ContributionIndex used by
+   \c AnnotationList__computeDominantContribution to signal when the action
+   chosen in a conflict is a syntax error because of a %nonassoc.  */
+extern ContributionIndex const ContributionIndex__error_action;
+
+/**
+ * The description of a conflict.  Don't break encapsulation by modifying the
+ * fields directly.  Use the provided interface functions for
+ * \c InadequacyList.
+ */
+typedef struct {
+  /** The \c token passed to \c InadequacyList__new_conflict.  */
+  symbol *token;
+  /** The \c actions passed to \c InadequacyList__new_conflict.  */
+  bitset actions;
+} Conflict;
+
+/**
+ * A node in a list that describes all the inadequacies that manifest in a
+ * particular state.  Don't break encapsulation by modifying the fields
+ * directly.  Use the provided interface functions.
+ */
+typedef struct InadequacyList {
+  struct InadequacyList *next;
+  InadequacyListNodeCount id;
+  state *manifestingState;
+  ContributionIndex contributionCount;
+  union {
+    Conflict conflict;
+  } inadequacy;
+} InadequacyList;
+
+/**
+ * \pre
+ *   - <tt>manifesting_state != NULL</tt>.
+ *   - \c token is a token.
+ *   - The size of \c actions is
+ *     <tt>manifesting_state->reductions->num + 1</tt>.
+ *   - If the set of all \c InadequacyList nodes with which the new
+ *     \c InadequacyList node might be compared is currently empty, then
+ *     it is best if <tt>*node_count</t> is zero so that the node count
+ *     does not eventually overflow.  However, if that set is not
+ *     currently empty, then <tt>*node_count</tt> has not been modified
+ *     by any function except \c InadequacyList__new_conflict since the
+ *     invocation of \c InadequacyList__new_conflict that constructed
+ *     the first existing member of that set.
+ * \post
+ *   - \c result is a new \c InadequacyList with one node indicating that, in
+ *     \c manifesting_state, the following actions are in conflict on \c token:
+ *     - Shift iff
+ *       <tt>bitset_test (actions, manifesting_state->reductions->num)</tt>.
+ *     - For any \c i such that
+ *       <tt>0 <= i < manifesting_state->reductions->num</tt>, the reduction
+ *       for the rule <tt>manifesting_state->reductions->rules[i]</tt> iff
+ *       <tt>actions[i]</tt> is set.
+ *   - Given any node \c n from the set of all existing
+ *     \c InadequacyList nodes with which \c result might be compared
+ *     such that <tt>n != result</tt>, then <tt>n->id < result->id</tt>.
+ *   - \c result assumes responsibility for the memory of \c actions.
+ */
+InadequacyList *InadequacyList__new_conflict (
+  state *manifesting_state, symbol *token, bitset actions,
+  InadequacyListNodeCount *node_count);
+
+/**
+ * \post
+ *   - All memory associated with all nodes in the list \c self was freed.
+ */
+void InadequacyList__delete (InadequacyList *self);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ * \post
+ *   - \c result = either:
+ *     - \c ContributionIndex__none iff there is no shift contribution in
+ *       \c self (perhaps because \c self isn't a conflict).
+ *     - The index of the shift contribution, otherwise.
+ */
+ContributionIndex
+InadequacyList__getShiftContributionIndex (InadequacyList const *self);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - <tt>0 <= i < self->contributionCount</tt>.
+ * \post
+ *   - \c result = the token associated with contribution \c i in the
+ *     inadequacy described by the node \c self.
+ */
+symbol *InadequacyList__getContributionToken (InadequacyList const *self,
+                                              ContributionIndex i);
+
+/**
+ * \pre
+ *   - \c self is a single node.
+ *   - <tt>list != NULL</tt>.
+ * \post
+ *   - \c list now contains \c self as its first node.
+ *   - \c list assumes responsibility for the memory of \c self.
+ */
+void InadequacyList__prependTo (InadequacyList *self, InadequacyList **list);
+
+#endif /* !INADEQUACY_LIST_H_ */
diff --git a/src/LR0.c b/src/LR0.c
index 259b891..37bfe81 100644
--- a/src/LR0.c
+++ b/src/LR0.c
@@ -1,24 +1,22 @@
-/* Generate the nondeterministic finite state machine for Bison.
+/* Generate the LR(0) parser states for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2004, 2005 Free
+   Copyright (C) 1984, 1986, 1989, 2000-2002, 2004-2007, 2009-2012 Free
    Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 /* See comments in state.h for the data structures that represent it.
@@ -28,7 +26,6 @@
 #include "system.h"
 
 #include <bitset.h>
-#include <quotearg.h>
 
 #include "LR0.h"
 #include "closure.h"
@@ -169,6 +166,10 @@
 | shifted.  For each symbol in the grammar, kernel_base[symbol]  |
 | points to a vector of item numbers activated if that symbol is |
 | shifted, and kernel_size[symbol] is their numbers.             |
+|                                                                |
+| itemset is sorted on item index in ritem, which is sorted on   |
+| rule number.  Compute each kernel_base[symbol] with the same   |
+| sort.                                                          |
 `---------------------------------------------------------------*/
 
 static void
@@ -183,8 +184,8 @@
 
   nshifts = 0;
 
-  for (i = 0; i < nritemset; ++i)
-    if (ritem[itemset[i]] >= 0)
+  for (i = 0; i < nitemset; ++i)
+    if (item_number_is_symbol_number (ritem[itemset[i]]))
       {
 	symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
 	if (!kernel_size[sym])
@@ -272,7 +273,7 @@
   size_t i;
 
   /* Find and count the active items that represent ends of rules. */
-  for (i = 0; i < nritemset; ++i)
+  for (i = 0; i < nitemset; ++i)
     {
       item_number item = ritem[itemset[i]];
       if (item_number_is_rule_number (item))
@@ -282,7 +283,7 @@
 	  if (r == 0)
 	    {
 	      /* This is "reduce 0", i.e., accept. */
-	      assert (!final_state);
+	      aver (!final_state);
 	      final_state = s;
 	    }
 	}
@@ -327,8 +328,8 @@
 
 
 /*-------------------------------------------------------------------.
-| Compute the nondeterministic finite state machine (see state.h for |
-| details) from the grammar.                                         |
+| Compute the LR(0) parser states (see state.h for details) from the |
+| grammar.                                                           |
 `-------------------------------------------------------------------*/
 
 void
@@ -351,10 +352,8 @@
 	fprintf (stderr, "Processing state %d (reached by %s)\n",
 		 s->number,
 		 symbols[s->accessing_symbol]->tag);
-      /* Set up ruleset and itemset for the transitions out of this
-         state.  ruleset gets a 1 bit for each rule that could reduce
-         now.  itemset gets a vector of all the items that could be
-         accepted next.  */
+      /* Set up itemset for the transitions out of this state.  itemset gets a
+         vector of all the items that could be accepted next.  */
       closure (s->items, s->nitems);
       /* Record the reductions allowed out of this state.  */
       save_reductions (s);
diff --git a/src/LR0.h b/src/LR0.h
index 6004538..45f922a 100644
--- a/src/LR0.h
+++ b/src/LR0.h
@@ -1,22 +1,22 @@
-/* Generate the nondeterministic finite state machine for bison,
-   Copyright 1984, 1986, 1989, 2000, 2001, 2002  Free Software Foundation, Inc.
+/* Generate the LR(0) parser states for Bison.
+
+   Copyright (C) 1984, 1986, 1989, 2000-2002, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef LR0_H_
 # define LR0_H_
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index eeb1d5b..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,655 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# src/Makefile.  Generated from Makefile.in by configure.
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-
-
-
-srcdir = .
-top_srcdir = ..
-
-pkgdatadir = $(datadir)/bison
-pkglibdir = $(libdir)/bison
-pkgincludedir = $(includedir)/bison
-top_builddir = ..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = /usr/bin/install -c
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = x86_64-unknown-linux-gnu
-host_triplet = x86_64-unknown-linux-gnu
-bin_PROGRAMS = bison$(EXEEXT)
-subdir = src
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in parse-gram.c \
-	scan-gram.c scan-skel.c
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/bison-i18n.m4 \
-	$(top_srcdir)/m4/c-working.m4 $(top_srcdir)/m4/cxx.m4 \
-	$(top_srcdir)/m4/dirname.m4 $(top_srcdir)/m4/dmalloc.m4 \
-	$(top_srcdir)/m4/dos.m4 $(top_srcdir)/m4/error.m4 \
-	$(top_srcdir)/m4/exitfail.m4 $(top_srcdir)/m4/extensions.m4 \
-	$(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gettext_gl.m4 \
-	$(top_srcdir)/m4/gnulib.m4 $(top_srcdir)/m4/hard-locale.m4 \
-	$(top_srcdir)/m4/hash.m4 $(top_srcdir)/m4/iconv.m4 \
-	$(top_srcdir)/m4/inttypes_h_gl.m4 \
-	$(top_srcdir)/m4/lib-ld_gl.m4 $(top_srcdir)/m4/lib-link.m4 \
-	$(top_srcdir)/m4/lib-prefix_gl.m4 $(top_srcdir)/m4/m4.m4 \
-	$(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbstate_t.m4 \
-	$(top_srcdir)/m4/mbswidth.m4 $(top_srcdir)/m4/nls.m4 \
-	$(top_srcdir)/m4/obstack.m4 $(top_srcdir)/m4/onceonly.m4 \
-	$(top_srcdir)/m4/po_gl.m4 $(top_srcdir)/m4/progtest.m4 \
-	$(top_srcdir)/m4/quote.m4 $(top_srcdir)/m4/quotearg.m4 \
-	$(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stdint_h_gl.m4 \
-	$(top_srcdir)/m4/stdio-safer.m4 $(top_srcdir)/m4/stpcpy.m4 \
-	$(top_srcdir)/m4/strdup.m4 $(top_srcdir)/m4/strerror.m4 \
-	$(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \
-	$(top_srcdir)/m4/strtol.m4 $(top_srcdir)/m4/strtoul.m4 \
-	$(top_srcdir)/m4/strverscmp.m4 $(top_srcdir)/m4/subpipe.m4 \
-	$(top_srcdir)/m4/timevar.m4 $(top_srcdir)/m4/uintmax_t_gl.m4 \
-	$(top_srcdir)/m4/ulonglong_gl.m4 \
-	$(top_srcdir)/m4/unistd-safer.m4 $(top_srcdir)/m4/unistd_h.m4 \
-	$(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/warning.m4 \
-	$(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xstrndup.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-PROGRAMS = $(bin_PROGRAMS)
-am_bison_OBJECTS = LR0.$(OBJEXT) assoc.$(OBJEXT) closure.$(OBJEXT) \
-	complain.$(OBJEXT) conflicts.$(OBJEXT) derives.$(OBJEXT) \
-	files.$(OBJEXT) getargs.$(OBJEXT) gram.$(OBJEXT) \
-	lalr.$(OBJEXT) location.$(OBJEXT) main.$(OBJEXT) \
-	muscle_tab.$(OBJEXT) nullable.$(OBJEXT) output.$(OBJEXT) \
-	parse-gram.$(OBJEXT) print.$(OBJEXT) print_graph.$(OBJEXT) \
-	reader.$(OBJEXT) reduce.$(OBJEXT) relation.$(OBJEXT) \
-	scan-gram-c.$(OBJEXT) scan-skel-c.$(OBJEXT) state.$(OBJEXT) \
-	symlist.$(OBJEXT) symtab.$(OBJEXT) tables.$(OBJEXT) \
-	uniqstr.$(OBJEXT) vcg.$(OBJEXT)
-bison_OBJECTS = $(am_bison_OBJECTS)
-bison_LDADD = $(LDADD)
-am__DEPENDENCIES_1 =
-bison_DEPENDENCIES = ../lib/libbison.a $(am__DEPENDENCIES_1)
-binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
-SCRIPTS = $(bin_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
-YLWRAP = $(top_srcdir)/build-aux/ylwrap
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
-SOURCES = $(bison_SOURCES) $(EXTRA_bison_SOURCES)
-DIST_SOURCES = $(bison_SOURCES) $(EXTRA_bison_SOURCES)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run aclocal-1.9
-AMDEP_FALSE = #
-AMDEP_TRUE = 
-AMTAR = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run tar
-AUTOCONF = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run autoconf
-AUTOHEADER = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run autoheader
-AUTOM4TE = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run autom4te
-AUTOMAKE = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run automake-1.9
-AWK = gawk
-BISON_CXX_WORKS = :
-BISON_CXX_WORKS_FALSE = #
-BISON_CXX_WORKS_TRUE = 
-BISON_LOCALEDIR = /usr/share/locale
-CC = gcc
-CCDEPMODE = depmode=gcc3
-CFLAGS = -g -O2
-CPP = gcc -E
-CPPFLAGS = 
-CXX = g++
-CXXDEPMODE = depmode=gcc3
-CXXFLAGS = -g -O2
-CYGPATH_W = echo
-DEFS = -DHAVE_CONFIG_H -DPKGDATADIR=\"$(pkgdatadir)\" \
-	-DLOCALEDIR=\"$(datadir)/locale\"
-DEPDIR = .deps
-ECHO_C = 
-ECHO_N = -n
-ECHO_T = 
-EGREP = grep -E
-EXEEXT = 
-GCC = yes
-GETOPT_H = 
-GMSGFMT = /usr/bin/msgfmt
-HAVE__BOOL = 1
-INSTALL_DATA = ${INSTALL} -m 644
-INSTALL_PROGRAM = ${INSTALL}
-INSTALL_SCRIPT = ${INSTALL}
-INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
-INTLLIBS = 
-INTL_MACOSX_LIBS = 
-LDFLAGS = 
-LEX = flex
-LEXLIB = -lfl
-LEX_OUTPUT_ROOT = lex.yy
-LIBICONV = -liconv
-LIBINTL = 
-LIBOBJS =  dirname$U.o exitfail$U.o hard-locale$U.o hash$U.o quote$U.o quotearg$U.o fopen-safer$U.o dup-safer$U.o fd-safer$U.o pipe-safer$U.o xmalloc$U.o
-LIBS = 
-LTLIBICONV = -liconv
-LTLIBINTL = 
-LTLIBOBJS =  dirname$U.lo exitfail$U.lo hard-locale$U.lo hash$U.lo quote$U.lo quotearg$U.lo fopen-safer$U.lo dup-safer$U.lo fd-safer$U.lo pipe-safer$U.lo xmalloc$U.lo
-M4 = /usr/bin/m4
-MAKEINFO = ${SHELL} /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/missing --run makeinfo
-MKINSTALLDIRS = $(top_builddir)/build-aux/mkinstalldirs
-MSGFMT = /usr/bin/msgfmt
-MSGMERGE = /usr/bin/msgmerge
-O0CFLAGS = -g 
-O0CXXFLAGS = -g 
-OBJEXT = o
-PACKAGE = bison
-PACKAGE_BUGREPORT = bug-bison@gnu.org
-PACKAGE_NAME = GNU Bison
-PACKAGE_STRING = GNU Bison 2.3
-PACKAGE_TARNAME = bison
-PACKAGE_VERSION = 2.3
-PATH_SEPARATOR = :
-POSUB = po
-RANLIB = ranlib
-SET_MAKE = 
-SHELL = /bin/sh
-STDBOOL_H = 
-STRIP = 
-UNISTD_H = 
-USE_NLS = yes
-VALGRIND = 
-VERSION = 2.3
-WARNING_CFLAGS = 
-WARNING_CXXFLAGS = 
-WERROR_CFLAGS = 
-XGETTEXT = /usr/bin/xgettext
-
-# Use our own Bison to build the parser.  Of course, you ought to
-# keep a sane version of Bison nearby...
-YACC = ../tests/bison -y
-YACC_LIBRARY = liby.a
-YACC_SCRIPT = yacc
-ac_ct_CC = gcc
-ac_ct_CXX = g++
-ac_ct_RANLIB = ranlib
-ac_ct_STRIP = 
-aclocaldir = ${datadir}/aclocal
-am__fastdepCC_FALSE = #
-am__fastdepCC_TRUE = 
-am__fastdepCXX_FALSE = #
-am__fastdepCXX_TRUE = 
-am__include = include
-am__leading_dot = .
-am__quote = 
-am__tar = ${AMTAR} chof - "$$tardir"
-am__untar = ${AMTAR} xf -
-bindir = ${exec_prefix}/bin
-build = x86_64-unknown-linux-gnu
-build_alias = 
-build_cpu = x86_64
-build_os = linux-gnu
-build_vendor = unknown
-datadir = ${prefix}/share
-exec_prefix = ${prefix}
-host = x86_64-unknown-linux-gnu
-host_alias = 
-host_cpu = x86_64
-host_os = linux-gnu
-host_vendor = unknown
-includedir = ${prefix}/include
-infodir = ${prefix}/info
-install_sh = /usr/local/google/workspace/WebKit/tools/bison-2.3/build-aux/install-sh
-libdir = ${exec_prefix}/lib
-libexecdir = ${exec_prefix}/libexec
-localstatedir = ${prefix}/var
-mandir = ${prefix}/man
-mkdir_p = mkdir -p --
-oldincludedir = /usr/include
-prefix = /home/phanna/src/bison
-program_transform_name = s,x,x,
-sbindir = ${exec_prefix}/sbin
-sharedstatedir = ${prefix}/com
-sysconfdir = ${prefix}/etc
-target_alias = 
-AM_CFLAGS = $(WARNING_CFLAGS) $(WERROR_CFLAGS)
-AM_CPPFLAGS = -I$(top_srcdir)/lib -I../lib
-AM_YFLAGS = "-dv"
-LDADD = ../lib/libbison.a $(LIBINTL)
-bin_SCRIPTS = $(YACC_SCRIPT)
-EXTRA_SCRIPTS = yacc
-bison_SOURCES = \
-	LR0.c LR0.h				  \
-	assoc.c assoc.h				  \
-	closure.c closure.h			  \
-	complain.c complain.h			  \
-	conflicts.c conflicts.h			  \
-	derives.c derives.h			  \
-	files.c files.h				  \
-	getargs.c getargs.h			  \
-	gram.c gram.h				  \
-	lalr.h lalr.c				  \
-	location.c location.h			  \
-	main.c					  \
-	muscle_tab.c muscle_tab.h		  \
-	nullable.c nullable.h			  \
-	output.c output.h			  \
-	parse-gram.h parse-gram.y		  \
-	print.c print.h				  \
-	print_graph.c print_graph.h		  \
-	reader.c reader.h			  \
-	reduce.c reduce.h			  \
-	relation.c relation.h			  \
-	scan-gram-c.c				  \
-	scan-skel-c.c scan-skel.h		  \
-	state.c state.h				  \
-	symlist.c symlist.h			  \
-	symtab.c symtab.h			  \
-	system.h				  \
-	tables.h tables.c			  \
-	uniqstr.c uniqstr.h			  \
-	vcg.c vcg.h				  \
-	vcg_defaults.h
-
-EXTRA_bison_SOURCES = scan-skel.l scan-gram.l
-BUILT_SOURCES = scan-skel.c scan-gram.c parse-gram.c parse-gram.h
-MOSTLYCLEANFILES = yacc
-all: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .l .o .obj .y
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  src/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-binPROGRAMS: $(bin_PROGRAMS)
-	@$(NORMAL_INSTALL)
-	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
-	@list='$(bin_PROGRAMS)'; for p in $$list; do \
-	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-	  if test -f $$p \
-	  ; then \
-	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-	   echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
-	   $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
-	  else :; fi; \
-	done
-
-uninstall-binPROGRAMS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(bin_PROGRAMS)'; for p in $$list; do \
-	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
-	done
-
-clean-binPROGRAMS:
-	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-bison$(EXEEXT): $(bison_OBJECTS) $(bison_DEPENDENCIES) 
-	@rm -f bison$(EXEEXT)
-	$(LINK) $(bison_LDFLAGS) $(bison_OBJECTS) $(bison_LDADD) $(LIBS)
-install-binSCRIPTS: $(bin_SCRIPTS)
-	@$(NORMAL_INSTALL)
-	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
-	@list='$(bin_SCRIPTS)'; for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f $$d$$p; then \
-	    f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
-	    echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
-	    $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
-	  else :; fi; \
-	done
-
-uninstall-binSCRIPTS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(bin_SCRIPTS)'; for p in $$list; do \
-	  f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
-	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
-	done
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
-include ./$(DEPDIR)/LR0.Po
-include ./$(DEPDIR)/assoc.Po
-include ./$(DEPDIR)/closure.Po
-include ./$(DEPDIR)/complain.Po
-include ./$(DEPDIR)/conflicts.Po
-include ./$(DEPDIR)/derives.Po
-include ./$(DEPDIR)/files.Po
-include ./$(DEPDIR)/getargs.Po
-include ./$(DEPDIR)/gram.Po
-include ./$(DEPDIR)/lalr.Po
-include ./$(DEPDIR)/location.Po
-include ./$(DEPDIR)/main.Po
-include ./$(DEPDIR)/muscle_tab.Po
-include ./$(DEPDIR)/nullable.Po
-include ./$(DEPDIR)/output.Po
-include ./$(DEPDIR)/parse-gram.Po
-include ./$(DEPDIR)/print.Po
-include ./$(DEPDIR)/print_graph.Po
-include ./$(DEPDIR)/reader.Po
-include ./$(DEPDIR)/reduce.Po
-include ./$(DEPDIR)/relation.Po
-include ./$(DEPDIR)/scan-gram-c.Po
-include ./$(DEPDIR)/scan-gram.Po
-include ./$(DEPDIR)/scan-skel-c.Po
-include ./$(DEPDIR)/scan-skel.Po
-include ./$(DEPDIR)/state.Po
-include ./$(DEPDIR)/symlist.Po
-include ./$(DEPDIR)/symtab.Po
-include ./$(DEPDIR)/tables.Po
-include ./$(DEPDIR)/uniqstr.Po
-include ./$(DEPDIR)/vcg.Po
-
-.c.o:
-	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
-	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
-#	source='$<' object='$@' libtool=no \
-#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
-#	$(COMPILE) -c $<
-
-.c.obj:
-	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
-	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
-#	source='$<' object='$@' libtool=no \
-#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
-#	$(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.l.c:
-	$(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
-
-.y.c:
-	$(YACCCOMPILE) $<
-	if test -f y.tab.h; then \
-	  to=`echo "$*_H" | sed \
-                -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-                -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
-	  sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
-            y.tab.h >$*.ht; \
-	  rm -f y.tab.h; \
-	  if cmp -s $*.ht $*.h; then \
-	    rm -f $*.ht ;\
-	  else \
-	    mv $*.ht $*.h; \
-	  fi; \
-	fi
-	if test -f y.output; then \
-	  mv y.output $*.output; \
-	fi
-	sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
-	rm -f y.tab.c
-uninstall-info-am:
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(PROGRAMS) $(SCRIPTS)
-installdirs:
-	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
-	done
-install: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-	-rm -f parse-gram.c
-	-rm -f scan-gram.c
-	-rm -f scan-skel.c
-	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-clean: clean-am
-
-clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-exec-am: install-binPROGRAMS install-binSCRIPTS
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
-	uninstall-info-am
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
-	clean-generic ctags distclean distclean-compile \
-	distclean-generic distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-binPROGRAMS \
-	install-binSCRIPTS install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am install-man \
-	install-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-binPROGRAMS \
-	uninstall-binSCRIPTS uninstall-info-am
-
-
-yacc:
-	echo '#! /bin/sh' >$@
-	echo 'exec $(bindir)/bison -y "$$@"' >>$@
-	chmod a+x $@
-
-echo:
-	echo $(bison_SOURCES) $(noinst_HEADERS)
-
-# The following rule is not designed to be portable,
-# and relies on tools that not everyone has.
-
-# Most functions in src/*.c should have static scope.
-# Any that don't must be marked with `extern', but `main'
-# and `usage' are exceptions.  They're always extern, but
-# don't need to be marked.
-#
-# The second nm|grep checks for file-scope variables with `extern' scope.
-sc_tight_scope: $(all_programs)
-	@t=exceptions-$$$$;						\
-	trap 's=$$?; rm -f $$t; exit $$s' 0 1 2 13 15;			\
-	( printf '^main$$\n^usage$$\n';					\
-	  grep -h -A1 '^extern .*[^;]$$' $(SOURCES)			\
-	    | grep -vE '^(extern |--)' |sed 's/^/^/;s/ .*/$$/' ) > $$t;	\
-	if nm -e *.$(OBJEXT)						\
-	    | sed -n 's/.* T //p'					\
-	    | grep -Ev -f $$t; then					\
-	  echo 'the above functions should have static scope' 1>&2;	\
-	  exit 1;							\
-	fi;								\
-	( printf '^program_name$$\n';					\
-	  sed -n 's/^extern .*[* ]\([a-zA-Z_][a-zA-Z_0-9]*\);$$/^\1$$/p' \
-	    $$(ls $(SOURCES) | grep '\.h$$') /dev/null) > $$t;		\
-	if nm -e *.$(OBJEXT)						\
-	    | sed -n 's/.* [BD] //p'					\
-	    | grep -Ev -f $$t; then					\
-	  echo 'the above variables should have static scope' 1>&2;	\
-	  exit 1;							\
-	fi
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/Makefile.am b/src/Makefile.am
index c973e9e..511b905 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,82 +1,89 @@
-## Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Make bison/src.
 
-## 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 2 of the License, or
-## (at your option) any later version.
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
 
-## 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.
+# 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 <http://www.gnu.org/licenses/>.
 
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-## 02110-1301  USA
-
-DEFS += -DPKGDATADIR=\"$(pkgdatadir)\" -DLOCALEDIR=\"$(datadir)/locale\"
-
-AM_CFLAGS = $(WARNING_CFLAGS) $(WERROR_CFLAGS)
-AM_CPPFLAGS = -I$(top_srcdir)/lib -I../lib
-AM_YFLAGS = "-dv"
-
-LDADD = ../lib/libbison.a $(LIBINTL)
-
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/lib
+BISON = ../tests/bison
 # Use our own Bison to build the parser.  Of course, you ought to
 # keep a sane version of Bison nearby...
-YACC = ../tests/bison -y
+YACC = $(BISON) -y
+AM_YFLAGS = -d -v --warnings=all,error --report=all
+
+LDADD = ../lib/libbison.a $(LIBINTL)
 
 bin_PROGRAMS = bison
 bin_SCRIPTS = $(YACC_SCRIPT)
 EXTRA_SCRIPTS = yacc
 
-bison_SOURCES =					  \
-	LR0.c LR0.h				  \
-	assoc.c assoc.h				  \
-	closure.c closure.h			  \
-	complain.c complain.h			  \
-	conflicts.c conflicts.h			  \
-	derives.c derives.h			  \
-	files.c files.h				  \
-	getargs.c getargs.h			  \
-	gram.c gram.h				  \
-	lalr.h lalr.c				  \
-	location.c location.h			  \
-	main.c					  \
-	muscle_tab.c muscle_tab.h		  \
-	nullable.c nullable.h			  \
-	output.c output.h			  \
-	parse-gram.h parse-gram.y		  \
-	print.c print.h				  \
-	print_graph.c print_graph.h		  \
-	reader.c reader.h			  \
-	reduce.c reduce.h			  \
-	relation.c relation.h			  \
-	scan-gram-c.c				  \
-	scan-skel-c.c scan-skel.h		  \
-	state.c state.h				  \
-	symlist.c symlist.h			  \
-	symtab.c symtab.h			  \
-	system.h				  \
-	tables.h tables.c			  \
-	uniqstr.c uniqstr.h			  \
-	vcg.c vcg.h				  \
-	vcg_defaults.h
+bison_SOURCES =                                 \
+  AnnotationList.c AnnotationList.h             \
+  InadequacyList.c InadequacyList.h             \
+  LR0.c LR0.h                                   \
+  Sbitset.c Sbitset.h                           \
+  assoc.c assoc.h                               \
+  closure.c closure.h                           \
+  complain.c complain.h                         \
+  conflicts.c conflicts.h                       \
+  derives.c derives.h                           \
+  files.c files.h                               \
+  flex-scanner.h                                \
+  getargs.c getargs.h                           \
+  gram.c gram.h                                 \
+  lalr.h lalr.c                                 \
+  ielr.h ielr.c                                 \
+  location.c location.h                         \
+  main.c                                        \
+  muscle-tab.c muscle-tab.h                     \
+  named-ref.c named-ref.h                       \
+  nullable.c nullable.h                         \
+  output.c output.h                             \
+  parse-gram.y                                  \
+  print.c print.h                               \
+  print_graph.c print_graph.h                   \
+  print-xml.c print-xml.h                       \
+  reader.c reader.h                             \
+  reduce.c reduce.h                             \
+  relation.c relation.h                         \
+  scan-code.h scan-code-c.c                     \
+  scan-gram.h scan-gram-c.c                     \
+  scan-skel.h scan-skel-c.c                     \
+  state.c state.h                               \
+  symlist.c symlist.h                           \
+  symtab.c symtab.h                             \
+  system.h                                      \
+  tables.h tables.c                             \
+  uniqstr.c uniqstr.h                           \
+  graphviz.c graphviz.h
 
-EXTRA_bison_SOURCES = scan-skel.l scan-gram.l
+EXTRA_bison_SOURCES = scan-code.l scan-skel.l scan-gram.l
 
-BUILT_SOURCES = scan-skel.c scan-gram.c parse-gram.c parse-gram.h
+BUILT_SOURCES =                                 \
+  parse-gram.c parse-gram.h                     \
+  scan-code.c                                   \
+  scan-skel.c                                   \
+  scan-gram.c
 
 MOSTLYCLEANFILES = yacc
 
 yacc:
-	echo '#! /bin/sh' >$@
-	echo 'exec $(bindir)/bison -y "$$@"' >>$@
-	chmod a+x $@
+	$(AM_V_GEN)echo '#! /bin/sh' >$@
+	$(AM_V_at)echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@
+	$(AM_V_at)chmod a+x $@
 
-echo:
-	echo $(bison_SOURCES) $(noinst_HEADERS)
 
 # The following rule is not designed to be portable,
 # and relies on tools that not everyone has.
diff --git a/src/Makefile.in b/src/Makefile.in
index 7de9081..304f2ce 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# Makefile.in generated by automake 1.12.5 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
+# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -14,16 +14,46 @@
 
 @SET_MAKE@
 
+# Make bison/src.
 
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
+# Copyright (C) 2001-2012 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 <http://www.gnu.org/licenses/>.
+
+
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
+pkglibdir = $(libdir)/@PACKAGE@
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
 install_sh_SCRIPT = $(install_sh) -c
@@ -39,171 +69,1305 @@
 host_triplet = @host@
 bin_PROGRAMS = bison$(EXEEXT)
 subdir = src
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in parse-gram.c \
-	scan-gram.c scan-skel.c
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(top_srcdir)/build-aux/depcomp $(top_srcdir)/build-aux/ylwrap \
+	parse-gram.c parse-gram.h scan-code.c scan-gram.c scan-skel.c
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/bison-i18n.m4 \
-	$(top_srcdir)/m4/c-working.m4 $(top_srcdir)/m4/cxx.m4 \
-	$(top_srcdir)/m4/dirname.m4 $(top_srcdir)/m4/dmalloc.m4 \
-	$(top_srcdir)/m4/dos.m4 $(top_srcdir)/m4/error.m4 \
-	$(top_srcdir)/m4/exitfail.m4 $(top_srcdir)/m4/extensions.m4 \
-	$(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gettext_gl.m4 \
-	$(top_srcdir)/m4/gnulib.m4 $(top_srcdir)/m4/hard-locale.m4 \
-	$(top_srcdir)/m4/hash.m4 $(top_srcdir)/m4/iconv.m4 \
-	$(top_srcdir)/m4/inttypes_h_gl.m4 \
-	$(top_srcdir)/m4/lib-ld_gl.m4 $(top_srcdir)/m4/lib-link.m4 \
-	$(top_srcdir)/m4/lib-prefix_gl.m4 $(top_srcdir)/m4/m4.m4 \
-	$(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbstate_t.m4 \
-	$(top_srcdir)/m4/mbswidth.m4 $(top_srcdir)/m4/nls.m4 \
-	$(top_srcdir)/m4/obstack.m4 $(top_srcdir)/m4/onceonly.m4 \
-	$(top_srcdir)/m4/po_gl.m4 $(top_srcdir)/m4/progtest.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
+	$(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/asm-underscore.m4 \
+	$(top_srcdir)/m4/assert.m4 $(top_srcdir)/m4/bison-i18n.m4 \
+	$(top_srcdir)/m4/c-working.m4 $(top_srcdir)/m4/calloc.m4 \
+	$(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/close.m4 \
+	$(top_srcdir)/m4/closeout.m4 $(top_srcdir)/m4/codeset.m4 \
+	$(top_srcdir)/m4/config-h.m4 $(top_srcdir)/m4/configmake.m4 \
+	$(top_srcdir)/m4/cxx.m4 $(top_srcdir)/m4/dirname.m4 \
+	$(top_srcdir)/m4/dmalloc.m4 \
+	$(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup2.m4 \
+	$(top_srcdir)/m4/environ.m4 $(top_srcdir)/m4/errno_h.m4 \
+	$(top_srcdir)/m4/error.m4 $(top_srcdir)/m4/exponentd.m4 \
+	$(top_srcdir)/m4/exponentf.m4 $(top_srcdir)/m4/exponentl.m4 \
+	$(top_srcdir)/m4/extensions.m4 \
+	$(top_srcdir)/m4/extern-inline.m4 \
+	$(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fcntl-o.m4 \
+	$(top_srcdir)/m4/fcntl.m4 $(top_srcdir)/m4/fcntl_h.m4 \
+	$(top_srcdir)/m4/flex.m4 $(top_srcdir)/m4/float_h.m4 \
+	$(top_srcdir)/m4/fopen.m4 $(top_srcdir)/m4/fpending.m4 \
+	$(top_srcdir)/m4/fpieee.m4 $(top_srcdir)/m4/fprintf-posix.m4 \
+	$(top_srcdir)/m4/frexp.m4 $(top_srcdir)/m4/frexpl.m4 \
+	$(top_srcdir)/m4/fseterr.m4 $(top_srcdir)/m4/fstat.m4 \
+	$(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \
+	$(top_srcdir)/m4/getline.m4 $(top_srcdir)/m4/getopt.m4 \
+	$(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc21.m4 \
+	$(top_srcdir)/m4/gnulib-common.m4 \
+	$(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/iconv.m4 \
+	$(top_srcdir)/m4/include_next.m4 \
+	$(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax_t.m4 \
+	$(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \
+	$(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/isnan.m4 \
+	$(top_srcdir)/m4/isnand.m4 $(top_srcdir)/m4/isnanf.m4 \
+	$(top_srcdir)/m4/isnanl.m4 $(top_srcdir)/m4/iswblank.m4 \
+	$(top_srcdir)/m4/javacomp.m4 $(top_srcdir)/m4/javaexec.m4 \
+	$(top_srcdir)/m4/largefile.m4 $(top_srcdir)/m4/ldexp.m4 \
+	$(top_srcdir)/m4/ldexpl.m4 $(top_srcdir)/m4/lib-ld.m4 \
+	$(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+	$(top_srcdir)/m4/libunistring-base.m4 \
+	$(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/locale-fr.m4 \
+	$(top_srcdir)/m4/locale-ja.m4 $(top_srcdir)/m4/locale-zh.m4 \
+	$(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \
+	$(top_srcdir)/m4/m4.m4 $(top_srcdir)/m4/malloc.m4 \
+	$(top_srcdir)/m4/math_h.m4 $(top_srcdir)/m4/mbchar.m4 \
+	$(top_srcdir)/m4/mbiter.m4 $(top_srcdir)/m4/mbrtowc.m4 \
+	$(top_srcdir)/m4/mbsinit.m4 $(top_srcdir)/m4/mbstate_t.m4 \
+	$(top_srcdir)/m4/mbswidth.m4 $(top_srcdir)/m4/memchr.m4 \
+	$(top_srcdir)/m4/mmap-anon.m4 $(top_srcdir)/m4/mode_t.m4 \
+	$(top_srcdir)/m4/msvc-inval.m4 \
+	$(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \
+	$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/nocrash.m4 \
+	$(top_srcdir)/m4/obstack-printf.m4 $(top_srcdir)/m4/off_t.m4 \
+	$(top_srcdir)/m4/open.m4 $(top_srcdir)/m4/pathmax.m4 \
+	$(top_srcdir)/m4/perror.m4 $(top_srcdir)/m4/pipe2.m4 \
+	$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/posix_spawn.m4 \
+	$(top_srcdir)/m4/printf-frexp.m4 \
+	$(top_srcdir)/m4/printf-frexpl.m4 \
+	$(top_srcdir)/m4/printf-posix-rpl.m4 \
+	$(top_srcdir)/m4/printf.m4 $(top_srcdir)/m4/progtest.m4 \
 	$(top_srcdir)/m4/quote.m4 $(top_srcdir)/m4/quotearg.m4 \
-	$(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stdint_h_gl.m4 \
-	$(top_srcdir)/m4/stdio-safer.m4 $(top_srcdir)/m4/stpcpy.m4 \
+	$(top_srcdir)/m4/raise.m4 $(top_srcdir)/m4/rawmemchr.m4 \
+	$(top_srcdir)/m4/realloc.m4 $(top_srcdir)/m4/sched_h.m4 \
+	$(top_srcdir)/m4/setenv.m4 $(top_srcdir)/m4/sig_atomic_t.m4 \
+	$(top_srcdir)/m4/sigaction.m4 $(top_srcdir)/m4/signal_h.m4 \
+	$(top_srcdir)/m4/signalblocking.m4 $(top_srcdir)/m4/signbit.m4 \
+	$(top_srcdir)/m4/size_max.m4 \
+	$(top_srcdir)/m4/snprintf-posix.m4 \
+	$(top_srcdir)/m4/snprintf.m4 $(top_srcdir)/m4/spawn-pipe.m4 \
+	$(top_srcdir)/m4/spawn_h.m4 $(top_srcdir)/m4/sprintf-posix.m4 \
+	$(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat.m4 \
+	$(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \
+	$(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \
+	$(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \
+	$(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strchrnul.m4 \
 	$(top_srcdir)/m4/strdup.m4 $(top_srcdir)/m4/strerror.m4 \
+	$(top_srcdir)/m4/strerror_r.m4 $(top_srcdir)/m4/string_h.m4 \
 	$(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \
-	$(top_srcdir)/m4/strtol.m4 $(top_srcdir)/m4/strtoul.m4 \
-	$(top_srcdir)/m4/strverscmp.m4 $(top_srcdir)/m4/subpipe.m4 \
-	$(top_srcdir)/m4/timevar.m4 $(top_srcdir)/m4/uintmax_t_gl.m4 \
-	$(top_srcdir)/m4/ulonglong_gl.m4 \
+	$(top_srcdir)/m4/strtoul.m4 $(top_srcdir)/m4/strverscmp.m4 \
+	$(top_srcdir)/m4/sys_socket_h.m4 \
+	$(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_types_h.m4 \
+	$(top_srcdir)/m4/sys_wait_h.m4 $(top_srcdir)/m4/threadlib.m4 \
+	$(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/timevar.m4 \
 	$(top_srcdir)/m4/unistd-safer.m4 $(top_srcdir)/m4/unistd_h.m4 \
-	$(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/warning.m4 \
-	$(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xstrndup.m4 \
+	$(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/vasnprintf.m4 \
+	$(top_srcdir)/m4/vfprintf-posix.m4 \
+	$(top_srcdir)/m4/vsnprintf-posix.m4 \
+	$(top_srcdir)/m4/vsnprintf.m4 \
+	$(top_srcdir)/m4/vsprintf-posix.m4 \
+	$(top_srcdir)/m4/wait-process.m4 $(top_srcdir)/m4/waitpid.m4 \
+	$(top_srcdir)/m4/warn-on-use.m4 $(top_srcdir)/m4/warnings.m4 \
+	$(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \
+	$(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wcwidth.m4 \
+	$(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xalloc.m4 \
+	$(top_srcdir)/m4/xsize.m4 $(top_srcdir)/m4/xstrndup.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/lib/config.h
 CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS)
-am_bison_OBJECTS = LR0.$(OBJEXT) assoc.$(OBJEXT) closure.$(OBJEXT) \
-	complain.$(OBJEXT) conflicts.$(OBJEXT) derives.$(OBJEXT) \
-	files.$(OBJEXT) getargs.$(OBJEXT) gram.$(OBJEXT) \
-	lalr.$(OBJEXT) location.$(OBJEXT) main.$(OBJEXT) \
-	muscle_tab.$(OBJEXT) nullable.$(OBJEXT) output.$(OBJEXT) \
+am_bison_OBJECTS = AnnotationList.$(OBJEXT) InadequacyList.$(OBJEXT) \
+	LR0.$(OBJEXT) Sbitset.$(OBJEXT) assoc.$(OBJEXT) \
+	closure.$(OBJEXT) complain.$(OBJEXT) conflicts.$(OBJEXT) \
+	derives.$(OBJEXT) files.$(OBJEXT) getargs.$(OBJEXT) \
+	gram.$(OBJEXT) lalr.$(OBJEXT) ielr.$(OBJEXT) \
+	location.$(OBJEXT) main.$(OBJEXT) muscle-tab.$(OBJEXT) \
+	named-ref.$(OBJEXT) nullable.$(OBJEXT) output.$(OBJEXT) \
 	parse-gram.$(OBJEXT) print.$(OBJEXT) print_graph.$(OBJEXT) \
-	reader.$(OBJEXT) reduce.$(OBJEXT) relation.$(OBJEXT) \
-	scan-gram-c.$(OBJEXT) scan-skel-c.$(OBJEXT) state.$(OBJEXT) \
-	symlist.$(OBJEXT) symtab.$(OBJEXT) tables.$(OBJEXT) \
-	uniqstr.$(OBJEXT) vcg.$(OBJEXT)
+	print-xml.$(OBJEXT) reader.$(OBJEXT) reduce.$(OBJEXT) \
+	relation.$(OBJEXT) scan-code-c.$(OBJEXT) scan-gram-c.$(OBJEXT) \
+	scan-skel-c.$(OBJEXT) state.$(OBJEXT) symlist.$(OBJEXT) \
+	symtab.$(OBJEXT) tables.$(OBJEXT) uniqstr.$(OBJEXT) \
+	graphviz.$(OBJEXT)
 bison_OBJECTS = $(am_bison_OBJECTS)
 bison_LDADD = $(LDADD)
 am__DEPENDENCIES_1 =
 bison_DEPENDENCIES = ../lib/libbison.a $(am__DEPENDENCIES_1)
-binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 SCRIPTS = $(bin_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/lib
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
+am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS)
+AM_V_LEX = $(am__v_LEX_@AM_V@)
+am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@)
+am__v_LEX_0 = @echo "  LEX     " $@;
+am__v_LEX_1 = 
 YLWRAP = $(top_srcdir)/build-aux/ylwrap
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \
+		   -e s/c++$$/h++/ -e s/c$$/h/
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
+AM_V_YACC = $(am__v_YACC_@AM_V@)
+am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@)
+am__v_YACC_0 = @echo "  YACC    " $@;
+am__v_YACC_1 = 
 SOURCES = $(bison_SOURCES) $(EXTRA_bison_SOURCES)
 DIST_SOURCES = $(bison_SOURCES) $(EXTRA_bison_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibexecdir = @pkglibexecdir@
 ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOM4TE = @AUTOM4TE@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 BISON_CXX_WORKS = @BISON_CXX_WORKS@
-BISON_CXX_WORKS_FALSE = @BISON_CXX_WORKS_FALSE@
-BISON_CXX_WORKS_TRUE = @BISON_CXX_WORKS_TRUE@
+BISON_C_WORKS = @BISON_C_WORKS@
 BISON_LOCALEDIR = @BISON_LOCALEDIR@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
+CLASSPATH = @CLASSPATH@
+CLASSPATH_SEPARATOR = @CLASSPATH_SEPARATOR@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CONF_JAVA = @CONF_JAVA@
+CONF_JAVAC = @CONF_JAVAC@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
+CXX_COMPILER_POSIXLY_CORRECT = @CXX_COMPILER_POSIXLY_CORRECT@
 CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@ -DPKGDATADIR=\"$(pkgdatadir)\" \
-	-DLOCALEDIR=\"$(datadir)/locale\"
+C_COMPILER_POSIXLY_CORRECT = @C_COMPILER_POSIXLY_CORRECT@
+DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DOT = @DOT@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
 EXEEXT = @EXEEXT@
+FLOAT_H = @FLOAT_H@
 GCC = @GCC@
 GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
 GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ACOSF = @GNULIB_ACOSF@
+GNULIB_ACOSL = @GNULIB_ACOSL@
+GNULIB_ASINF = @GNULIB_ASINF@
+GNULIB_ASINL = @GNULIB_ASINL@
+GNULIB_ATAN2F = @GNULIB_ATAN2F@
+GNULIB_ATANF = @GNULIB_ATANF@
+GNULIB_ATANL = @GNULIB_ATANL@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CBRT = @GNULIB_CBRT@
+GNULIB_CBRTF = @GNULIB_CBRTF@
+GNULIB_CBRTL = @GNULIB_CBRTL@
+GNULIB_CEIL = @GNULIB_CEIL@
+GNULIB_CEILF = @GNULIB_CEILF@
+GNULIB_CEILL = @GNULIB_CEILL@
+GNULIB_CHDIR = @GNULIB_CHDIR@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_COPYSIGN = @GNULIB_COPYSIGN@
+GNULIB_COPYSIGNF = @GNULIB_COPYSIGNF@
+GNULIB_COPYSIGNL = @GNULIB_COPYSIGNL@
+GNULIB_COSF = @GNULIB_COSF@
+GNULIB_COSHF = @GNULIB_COSHF@
+GNULIB_COSL = @GNULIB_COSL@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP = @GNULIB_DUP@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_EXP2 = @GNULIB_EXP2@
+GNULIB_EXP2F = @GNULIB_EXP2F@
+GNULIB_EXP2L = @GNULIB_EXP2L@
+GNULIB_EXPF = @GNULIB_EXPF@
+GNULIB_EXPL = @GNULIB_EXPL@
+GNULIB_EXPM1 = @GNULIB_EXPM1@
+GNULIB_EXPM1F = @GNULIB_EXPM1F@
+GNULIB_EXPM1L = @GNULIB_EXPM1L@
+GNULIB_FABSF = @GNULIB_FABSF@
+GNULIB_FABSL = @GNULIB_FABSL@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
+GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
+GNULIB_FDOPEN = @GNULIB_FDOPEN@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FFSL = @GNULIB_FFSL@
+GNULIB_FFSLL = @GNULIB_FFSLL@
+GNULIB_FGETC = @GNULIB_FGETC@
+GNULIB_FGETS = @GNULIB_FGETS@
+GNULIB_FLOOR = @GNULIB_FLOOR@
+GNULIB_FLOORF = @GNULIB_FLOORF@
+GNULIB_FLOORL = @GNULIB_FLOORL@
+GNULIB_FMA = @GNULIB_FMA@
+GNULIB_FMAF = @GNULIB_FMAF@
+GNULIB_FMAL = @GNULIB_FMAL@
+GNULIB_FMOD = @GNULIB_FMOD@
+GNULIB_FMODF = @GNULIB_FMODF@
+GNULIB_FMODL = @GNULIB_FMODL@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREAD = @GNULIB_FREAD@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FREXP = @GNULIB_FREXP@
+GNULIB_FREXPF = @GNULIB_FREXPF@
+GNULIB_FREXPL = @GNULIB_FREXPL@
+GNULIB_FSCANF = @GNULIB_FSCANF@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSTAT = @GNULIB_FSTAT@
+GNULIB_FSTATAT = @GNULIB_FSTATAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETC = @GNULIB_GETC@
+GNULIB_GETCHAR = @GNULIB_GETCHAR@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@
+GNULIB_HYPOT = @GNULIB_HYPOT@
+GNULIB_HYPOTF = @GNULIB_HYPOTF@
+GNULIB_HYPOTL = @GNULIB_HYPOTL@
+GNULIB_ILOGB = @GNULIB_ILOGB@
+GNULIB_ILOGBF = @GNULIB_ILOGBF@
+GNULIB_ILOGBL = @GNULIB_ILOGBL@
+GNULIB_IMAXABS = @GNULIB_IMAXABS@
+GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
+GNULIB_ISATTY = @GNULIB_ISATTY@
+GNULIB_ISFINITE = @GNULIB_ISFINITE@
+GNULIB_ISINF = @GNULIB_ISINF@
+GNULIB_ISNAN = @GNULIB_ISNAN@
+GNULIB_ISNAND = @GNULIB_ISNAND@
+GNULIB_ISNANF = @GNULIB_ISNANF@
+GNULIB_ISNANL = @GNULIB_ISNANL@
+GNULIB_ISWBLANK = @GNULIB_ISWBLANK@
+GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LDEXPF = @GNULIB_LDEXPF@
+GNULIB_LDEXPL = @GNULIB_LDEXPL@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LOG = @GNULIB_LOG@
+GNULIB_LOG10 = @GNULIB_LOG10@
+GNULIB_LOG10F = @GNULIB_LOG10F@
+GNULIB_LOG10L = @GNULIB_LOG10L@
+GNULIB_LOG1P = @GNULIB_LOG1P@
+GNULIB_LOG1PF = @GNULIB_LOG1PF@
+GNULIB_LOG1PL = @GNULIB_LOG1PL@
+GNULIB_LOG2 = @GNULIB_LOG2@
+GNULIB_LOG2F = @GNULIB_LOG2F@
+GNULIB_LOG2L = @GNULIB_LOG2L@
+GNULIB_LOGB = @GNULIB_LOGB@
+GNULIB_LOGBF = @GNULIB_LOGBF@
+GNULIB_LOGBL = @GNULIB_LOGBL@
+GNULIB_LOGF = @GNULIB_LOGF@
+GNULIB_LOGL = @GNULIB_LOGL@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_LSTAT = @GNULIB_LSTAT@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MBTOWC = @GNULIB_MBTOWC@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKFIFO = @GNULIB_MKFIFO@
+GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
+GNULIB_MKNOD = @GNULIB_MKNOD@
+GNULIB_MKNODAT = @GNULIB_MKNODAT@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_MKTIME = @GNULIB_MKTIME@
+GNULIB_MODF = @GNULIB_MODF@
+GNULIB_MODFF = @GNULIB_MODFF@
+GNULIB_MODFL = @GNULIB_MODFL@
+GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
+GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
+GNULIB_PCLOSE = @GNULIB_PCLOSE@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@
+GNULIB_POSIX_SPAWN = @GNULIB_POSIX_SPAWN@
+GNULIB_POSIX_SPAWNATTR_DESTROY = @GNULIB_POSIX_SPAWNATTR_DESTROY@
+GNULIB_POSIX_SPAWNATTR_GETFLAGS = @GNULIB_POSIX_SPAWNATTR_GETFLAGS@
+GNULIB_POSIX_SPAWNATTR_GETPGROUP = @GNULIB_POSIX_SPAWNATTR_GETPGROUP@
+GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@
+GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@
+GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@
+GNULIB_POSIX_SPAWNATTR_GETSIGMASK = @GNULIB_POSIX_SPAWNATTR_GETSIGMASK@
+GNULIB_POSIX_SPAWNATTR_INIT = @GNULIB_POSIX_SPAWNATTR_INIT@
+GNULIB_POSIX_SPAWNATTR_SETFLAGS = @GNULIB_POSIX_SPAWNATTR_SETFLAGS@
+GNULIB_POSIX_SPAWNATTR_SETPGROUP = @GNULIB_POSIX_SPAWNATTR_SETPGROUP@
+GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@
+GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@
+GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@
+GNULIB_POSIX_SPAWNATTR_SETSIGMASK = @GNULIB_POSIX_SPAWNATTR_SETSIGMASK@
+GNULIB_POSIX_SPAWNP = @GNULIB_POSIX_SPAWNP@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@
+GNULIB_POWF = @GNULIB_POWF@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RAISE = @GNULIB_RAISE@
+GNULIB_RANDOM = @GNULIB_RANDOM@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READ = @GNULIB_READ@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_REMAINDER = @GNULIB_REMAINDER@
+GNULIB_REMAINDERF = @GNULIB_REMAINDERF@
+GNULIB_REMAINDERL = @GNULIB_REMAINDERL@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_RINT = @GNULIB_RINT@
+GNULIB_RINTF = @GNULIB_RINTF@
+GNULIB_RINTL = @GNULIB_RINTL@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_ROUND = @GNULIB_ROUND@
+GNULIB_ROUNDF = @GNULIB_ROUNDF@
+GNULIB_ROUNDL = @GNULIB_ROUNDL@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SCANF = @GNULIB_SCANF@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
+GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
+GNULIB_SIGNBIT = @GNULIB_SIGNBIT@
+GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
+GNULIB_SINF = @GNULIB_SINF@
+GNULIB_SINHF = @GNULIB_SINHF@
+GNULIB_SINL = @GNULIB_SINL@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_SQRTF = @GNULIB_SQRTF@
+GNULIB_SQRTL = @GNULIB_SQRTL@
+GNULIB_STAT = @GNULIB_STAT@
+GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRERROR_R = @GNULIB_STRERROR_R@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRPTIME = @GNULIB_STRPTIME@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TANF = @GNULIB_TANF@
+GNULIB_TANHF = @GNULIB_TANHF@
+GNULIB_TANL = @GNULIB_TANL@
+GNULIB_TIMEGM = @GNULIB_TIMEGM@
+GNULIB_TIME_R = @GNULIB_TIME_R@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@
+GNULIB_TRUNC = @GNULIB_TRUNC@
+GNULIB_TRUNCF = @GNULIB_TRUNCF@
+GNULIB_TRUNCL = @GNULIB_TRUNCL@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VFSCANF = @GNULIB_VFSCANF@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSCANF = @GNULIB_VSCANF@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WAITPID = @GNULIB_WAITPID@
+GNULIB_WCPCPY = @GNULIB_WCPCPY@
+GNULIB_WCPNCPY = @GNULIB_WCPNCPY@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@
+GNULIB_WCSCAT = @GNULIB_WCSCAT@
+GNULIB_WCSCHR = @GNULIB_WCSCHR@
+GNULIB_WCSCMP = @GNULIB_WCSCMP@
+GNULIB_WCSCOLL = @GNULIB_WCSCOLL@
+GNULIB_WCSCPY = @GNULIB_WCSCPY@
+GNULIB_WCSCSPN = @GNULIB_WCSCSPN@
+GNULIB_WCSDUP = @GNULIB_WCSDUP@
+GNULIB_WCSLEN = @GNULIB_WCSLEN@
+GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@
+GNULIB_WCSNCAT = @GNULIB_WCSNCAT@
+GNULIB_WCSNCMP = @GNULIB_WCSNCMP@
+GNULIB_WCSNCPY = @GNULIB_WCSNCPY@
+GNULIB_WCSNLEN = @GNULIB_WCSNLEN@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSPBRK = @GNULIB_WCSPBRK@
+GNULIB_WCSRCHR = @GNULIB_WCSRCHR@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCSSPN = @GNULIB_WCSSPN@
+GNULIB_WCSSTR = @GNULIB_WCSSTR@
+GNULIB_WCSTOK = @GNULIB_WCSTOK@
+GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@
+GNULIB_WCSXFRM = @GNULIB_WCSXFRM@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
+GNULIB_WCTRANS = @GNULIB_WCTRANS@
+GNULIB_WCTYPE = @GNULIB_WCTYPE@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WMEMCHR = @GNULIB_WMEMCHR@
+GNULIB_WMEMCMP = @GNULIB_WMEMCMP@
+GNULIB_WMEMCPY = @GNULIB_WMEMCPY@
+GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@
+GNULIB_WMEMSET = @GNULIB_WMEMSET@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ACOSF = @HAVE_ACOSF@
+HAVE_ACOSL = @HAVE_ACOSL@
+HAVE_ASINF = @HAVE_ASINF@
+HAVE_ASINL = @HAVE_ASINL@
+HAVE_ATAN2F = @HAVE_ATAN2F@
+HAVE_ATANF = @HAVE_ATANF@
+HAVE_ATANL = @HAVE_ATANL@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CBRT = @HAVE_CBRT@
+HAVE_CBRTF = @HAVE_CBRTF@
+HAVE_CBRTL = @HAVE_CBRTL@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_COPYSIGN = @HAVE_COPYSIGN@
+HAVE_COPYSIGNL = @HAVE_COPYSIGNL@
+HAVE_COSF = @HAVE_COSF@
+HAVE_COSHF = @HAVE_COSHF@
+HAVE_COSL = @HAVE_COSL@
+HAVE_DECL_ACOSL = @HAVE_DECL_ACOSL@
+HAVE_DECL_ASINL = @HAVE_DECL_ASINL@
+HAVE_DECL_ATANL = @HAVE_DECL_ATANL@
+HAVE_DECL_CBRTF = @HAVE_DECL_CBRTF@
+HAVE_DECL_CBRTL = @HAVE_DECL_CBRTL@
+HAVE_DECL_CEILF = @HAVE_DECL_CEILF@
+HAVE_DECL_CEILL = @HAVE_DECL_CEILL@
+HAVE_DECL_COPYSIGNF = @HAVE_DECL_COPYSIGNF@
+HAVE_DECL_COSL = @HAVE_DECL_COSL@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXP2 = @HAVE_DECL_EXP2@
+HAVE_DECL_EXP2F = @HAVE_DECL_EXP2F@
+HAVE_DECL_EXP2L = @HAVE_DECL_EXP2L@
+HAVE_DECL_EXPL = @HAVE_DECL_EXPL@
+HAVE_DECL_EXPM1L = @HAVE_DECL_EXPM1L@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@
+HAVE_DECL_FLOORF = @HAVE_DECL_FLOORF@
+HAVE_DECL_FLOORL = @HAVE_DECL_FLOORL@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREXPL = @HAVE_DECL_FREXPL@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_LDEXPL = @HAVE_DECL_LDEXPL@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_LOG10L = @HAVE_DECL_LOG10L@
+HAVE_DECL_LOG2 = @HAVE_DECL_LOG2@
+HAVE_DECL_LOG2F = @HAVE_DECL_LOG2F@
+HAVE_DECL_LOG2L = @HAVE_DECL_LOG2L@
+HAVE_DECL_LOGB = @HAVE_DECL_LOGB@
+HAVE_DECL_LOGL = @HAVE_DECL_LOGL@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_REMAINDER = @HAVE_DECL_REMAINDER@
+HAVE_DECL_REMAINDERL = @HAVE_DECL_REMAINDERL@
+HAVE_DECL_RINTF = @HAVE_DECL_RINTF@
+HAVE_DECL_ROUND = @HAVE_DECL_ROUND@
+HAVE_DECL_ROUNDF = @HAVE_DECL_ROUNDF@
+HAVE_DECL_ROUNDL = @HAVE_DECL_ROUNDL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
+HAVE_DECL_SINL = @HAVE_DECL_SINL@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_SQRTL = @HAVE_DECL_SQRTL@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@
+HAVE_DECL_TANL = @HAVE_DECL_TANL@
+HAVE_DECL_TRUNC = @HAVE_DECL_TRUNC@
+HAVE_DECL_TRUNCF = @HAVE_DECL_TRUNCF@
+HAVE_DECL_TRUNCL = @HAVE_DECL_TRUNCL@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPF = @HAVE_EXPF@
+HAVE_EXPL = @HAVE_EXPL@
+HAVE_EXPM1 = @HAVE_EXPM1@
+HAVE_EXPM1F = @HAVE_EXPM1F@
+HAVE_FABSF = @HAVE_FABSF@
+HAVE_FABSL = @HAVE_FABSL@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FDATASYNC = @HAVE_FDATASYNC@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FFSL = @HAVE_FFSL@
+HAVE_FFSLL = @HAVE_FFSLL@
+HAVE_FMA = @HAVE_FMA@
+HAVE_FMAF = @HAVE_FMAF@
+HAVE_FMAL = @HAVE_FMAL@
+HAVE_FMODF = @HAVE_FMODF@
+HAVE_FMODL = @HAVE_FMODL@
+HAVE_FREXPF = @HAVE_FREXPF@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GCJ_C = @HAVE_GCJ_C@
+HAVE_GCJ_IN_PATH = @HAVE_GCJ_IN_PATH@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GIJ = @HAVE_GIJ@
+HAVE_GIJ_IN_PATH = @HAVE_GIJ_IN_PATH@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_HYPOTF = @HAVE_HYPOTF@
+HAVE_HYPOTL = @HAVE_HYPOTL@
+HAVE_ILOGB = @HAVE_ILOGB@
+HAVE_ILOGBF = @HAVE_ILOGBF@
+HAVE_ILOGBL = @HAVE_ILOGBL@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISNAND = @HAVE_ISNAND@
+HAVE_ISNANF = @HAVE_ISNANF@
+HAVE_ISNANL = @HAVE_ISNANL@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_JAVA = @HAVE_JAVA@
+HAVE_JAVAC = @HAVE_JAVAC@
+HAVE_JAVAC_ENVVAR = @HAVE_JAVAC_ENVVAR@
+HAVE_JAVAC_IN_PATH = @HAVE_JAVAC_IN_PATH@
+HAVE_JAVA_ENVVAR = @HAVE_JAVA_ENVVAR@
+HAVE_JAVA_IN_PATH = @HAVE_JAVA_IN_PATH@
+HAVE_JIKES = @HAVE_JIKES@
+HAVE_JIKES_IN_PATH = @HAVE_JIKES_IN_PATH@
+HAVE_JRE = @HAVE_JRE@
+HAVE_JRE_IN_PATH = @HAVE_JRE_IN_PATH@
+HAVE_JVIEW = @HAVE_JVIEW@
+HAVE_JVIEW_IN_PATH = @HAVE_JVIEW_IN_PATH@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LDEXPF = @HAVE_LDEXPF@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LOG10F = @HAVE_LOG10F@
+HAVE_LOG10L = @HAVE_LOG10L@
+HAVE_LOG1P = @HAVE_LOG1P@
+HAVE_LOG1PF = @HAVE_LOG1PF@
+HAVE_LOG1PL = @HAVE_LOG1PL@
+HAVE_LOGBF = @HAVE_LOGBF@
+HAVE_LOGBL = @HAVE_LOGBL@
+HAVE_LOGF = @HAVE_LOGF@
+HAVE_LOGL = @HAVE_LOGL@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMCHR = @HAVE_MEMCHR@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_MODFF = @HAVE_MODFF@
+HAVE_MODFL = @HAVE_MODFL@
+HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PCLOSE = @HAVE_PCLOSE@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POPEN = @HAVE_POPEN@
+HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_POSIX_SPAWN = @HAVE_POSIX_SPAWN@
+HAVE_POSIX_SPAWNATTR_T = @HAVE_POSIX_SPAWNATTR_T@
+HAVE_POSIX_SPAWN_FILE_ACTIONS_T = @HAVE_POSIX_SPAWN_FILE_ACTIONS_T@
+HAVE_POWF = @HAVE_POWF@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PTSNAME_R = @HAVE_PTSNAME_R@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RAISE = @HAVE_RAISE@
+HAVE_RANDOM = @HAVE_RANDOM@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_REMAINDER = @HAVE_REMAINDER@
+HAVE_REMAINDERF = @HAVE_REMAINDERF@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_RINT = @HAVE_RINT@
+HAVE_RINTL = @HAVE_RINTL@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = @HAVE_SAME_LONG_DOUBLE_AS_DOUBLE@
+HAVE_SCHED_H = @HAVE_SCHED_H@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
+HAVE_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SINF = @HAVE_SINF@
+HAVE_SINHF = @HAVE_SINHF@
+HAVE_SINL = @HAVE_SINL@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_SPAWN_H = @HAVE_SPAWN_H@
+HAVE_SQRTF = @HAVE_SQRTF@
+HAVE_SQRTL = @HAVE_SQRTL@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_TANF = @HAVE_TANF@
+HAVE_TANHF = @HAVE_TANHF@
+HAVE_TANL = @HAVE_TANL@
+HAVE_TIMEGM = @HAVE_TIMEGM@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WCTRANS_T = @HAVE_WCTRANS_T@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WCTYPE_T = @HAVE_WCTYPE_T@
+HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMSET = @HAVE_WMEMSET@
 HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+HELP2MAN = @HELP2MAN@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@
+INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@
 INTLLIBS = @INTLLIBS@
 INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+ISNAND_LIBM = @ISNAND_LIBM@
+ISNANF_LIBM = @ISNANF_LIBM@
+ISNANL_LIBM = @ISNANL_LIBM@
+ISNAN_LIBM = @ISNAN_LIBM@
+LDEXPL_LIBM = @LDEXPL_LIBM@
+LDEXP_LIBM = @LDEXP_LIBM@
 LDFLAGS = @LDFLAGS@
 LEX = @LEX@
 LEXLIB = @LEXLIB@
+LEX_IS_FLEX = @LEX_IS_FLEX@
 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBBISON_LIBDEPS = @LIBBISON_LIBDEPS@
+LIBBISON_LTLIBDEPS = @LIBBISON_LTLIBDEPS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
 LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
+LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@
+LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
 LTLIBICONV = @LTLIBICONV@
 LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
 M4 = @M4@
+M4_DEBUGFILE = @M4_DEBUGFILE@
+M4_GNU = @M4_GNU@
 MAKEINFO = @MAKEINFO@
-MKINSTALLDIRS = @MKINSTALLDIRS@
+MKDIR_P = @MKDIR_P@
 MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
-O0CFLAGS = @O0CFLAGS@
-O0CXXFLAGS = @O0CXXFLAGS@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_MATH_H = @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
+NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_SPAWN_H = @NEXT_AS_FIRST_DIRECTIVE_SPAWN_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_MATH_H = @NEXT_MATH_H@
+NEXT_SCHED_H = @NEXT_SCHED_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_SPAWN_H = @NEXT_SPAWN_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@
+NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_COPYRIGHT_YEAR = @PACKAGE_COPYRIGHT_YEAR@
 PACKAGE_NAME = @PACKAGE_NAME@
 PACKAGE_STRING = @PACKAGE_STRING@
 PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
 POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
 RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CBRTF = @REPLACE_CBRTF@
+REPLACE_CBRTL = @REPLACE_CBRTL@
+REPLACE_CEIL = @REPLACE_CEIL@
+REPLACE_CEILF = @REPLACE_CEILF@
+REPLACE_CEILL = @REPLACE_CEILL@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_EXP2 = @REPLACE_EXP2@
+REPLACE_EXP2L = @REPLACE_EXP2L@
+REPLACE_EXPM1 = @REPLACE_EXPM1@
+REPLACE_EXPM1F = @REPLACE_EXPM1F@
+REPLACE_FABSL = @REPLACE_FABSL@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FDOPEN = @REPLACE_FDOPEN@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FLOOR = @REPLACE_FLOOR@
+REPLACE_FLOORF = @REPLACE_FLOORF@
+REPLACE_FLOORL = @REPLACE_FLOORL@
+REPLACE_FMA = @REPLACE_FMA@
+REPLACE_FMAF = @REPLACE_FMAF@
+REPLACE_FMAL = @REPLACE_FMAL@
+REPLACE_FMOD = @REPLACE_FMOD@
+REPLACE_FMODF = @REPLACE_FMODF@
+REPLACE_FMODL = @REPLACE_FMODL@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FREXP = @REPLACE_FREXP@
+REPLACE_FREXPF = @REPLACE_FREXPF@
+REPLACE_FREXPL = @REPLACE_FREXPL@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_HUGE_VAL = @REPLACE_HUGE_VAL@
+REPLACE_HYPOT = @REPLACE_HYPOT@
+REPLACE_HYPOTF = @REPLACE_HYPOTF@
+REPLACE_HYPOTL = @REPLACE_HYPOTL@
+REPLACE_ILOGB = @REPLACE_ILOGB@
+REPLACE_ILOGBF = @REPLACE_ILOGBF@
+REPLACE_ISATTY = @REPLACE_ISATTY@
+REPLACE_ISFINITE = @REPLACE_ISFINITE@
+REPLACE_ISINF = @REPLACE_ISINF@
+REPLACE_ISNAN = @REPLACE_ISNAN@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_ITOLD = @REPLACE_ITOLD@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LDEXPL = @REPLACE_LDEXPL@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LOG = @REPLACE_LOG@
+REPLACE_LOG10 = @REPLACE_LOG10@
+REPLACE_LOG10F = @REPLACE_LOG10F@
+REPLACE_LOG10L = @REPLACE_LOG10L@
+REPLACE_LOG1P = @REPLACE_LOG1P@
+REPLACE_LOG1PF = @REPLACE_LOG1PF@
+REPLACE_LOG1PL = @REPLACE_LOG1PL@
+REPLACE_LOG2 = @REPLACE_LOG2@
+REPLACE_LOG2F = @REPLACE_LOG2F@
+REPLACE_LOG2L = @REPLACE_LOG2L@
+REPLACE_LOGB = @REPLACE_LOGB@
+REPLACE_LOGBF = @REPLACE_LOGBF@
+REPLACE_LOGBL = @REPLACE_LOGBL@
+REPLACE_LOGF = @REPLACE_LOGF@
+REPLACE_LOGL = @REPLACE_LOGL@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_MODF = @REPLACE_MODF@
+REPLACE_MODFF = @REPLACE_MODFF@
+REPLACE_MODFL = @REPLACE_MODFL@
+REPLACE_NAN = @REPLACE_NAN@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_POSIX_SPAWN = @REPLACE_POSIX_SPAWN@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
+REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_RAISE = @REPLACE_RAISE@
+REPLACE_RANDOM_R = @REPLACE_RANDOM_R@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMAINDER = @REPLACE_REMAINDER@
+REPLACE_REMAINDERF = @REPLACE_REMAINDERF@
+REPLACE_REMAINDERL = @REPLACE_REMAINDERL@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_ROUND = @REPLACE_ROUND@
+REPLACE_ROUNDF = @REPLACE_ROUNDF@
+REPLACE_ROUNDL = @REPLACE_ROUNDL@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SIGNBIT = @REPLACE_SIGNBIT@
+REPLACE_SIGNBIT_USING_GCC = @REPLACE_SIGNBIT_USING_GCC@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_SQRTL = @REPLACE_SQRTL@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TOWLOWER = @REPLACE_TOWLOWER@
+REPLACE_TRUNC = @REPLACE_TRUNC@
+REPLACE_TRUNCF = @REPLACE_TRUNCF@
+REPLACE_TRUNCL = @REPLACE_TRUNCL@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SCHED_H = @SCHED_H@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
 STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
 STRIP = @STRIP@
-UNISTD_H = @UNISTD_H@
+SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
 USE_NLS = @USE_NLS@
 VALGRIND = @VALGRIND@
+VALGRIND_PREBISON = @VALGRIND_PREBISON@
 VERSION = @VERSION@
-WARNING_CFLAGS = @WARNING_CFLAGS@
-WARNING_CXXFLAGS = @WARNING_CXXFLAGS@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_CFLAGS_TEST = @WARN_CFLAGS_TEST@
+WARN_CXXFLAGS = @WARN_CXXFLAGS@
+WARN_CXXFLAGS_TEST = @WARN_CXXFLAGS_TEST@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
 WERROR_CFLAGS = @WERROR_CFLAGS@
+WERROR_CXXFLAGS = @WERROR_CXXFLAGS@
+WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@
+WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
 XGETTEXT = @XGETTEXT@
-
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XSLTPROC = @XSLTPROC@
 # Use our own Bison to build the parser.  Of course, you ought to
 # keep a sane version of Bison nearby...
-YACC = ../tests/bison -y
+YACC = $(BISON) -y
 YACC_LIBRARY = @YACC_LIBRARY@
 YACC_SCRIPT = @YACC_SCRIPT@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
 aclocaldir = @aclocaldir@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -215,69 +1379,100 @@
 build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
+builddir = @builddir@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-AM_CFLAGS = $(WARNING_CFLAGS) $(WERROR_CFLAGS)
-AM_CPPFLAGS = -I$(top_srcdir)/lib -I../lib
-AM_YFLAGS = "-dv"
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/lib
+BISON = ../tests/bison
+AM_YFLAGS = -d -v --warnings=all,error --report=all
 LDADD = ../lib/libbison.a $(LIBINTL)
 bin_SCRIPTS = $(YACC_SCRIPT)
 EXTRA_SCRIPTS = yacc
 bison_SOURCES = \
-	LR0.c LR0.h				  \
-	assoc.c assoc.h				  \
-	closure.c closure.h			  \
-	complain.c complain.h			  \
-	conflicts.c conflicts.h			  \
-	derives.c derives.h			  \
-	files.c files.h				  \
-	getargs.c getargs.h			  \
-	gram.c gram.h				  \
-	lalr.h lalr.c				  \
-	location.c location.h			  \
-	main.c					  \
-	muscle_tab.c muscle_tab.h		  \
-	nullable.c nullable.h			  \
-	output.c output.h			  \
-	parse-gram.h parse-gram.y		  \
-	print.c print.h				  \
-	print_graph.c print_graph.h		  \
-	reader.c reader.h			  \
-	reduce.c reduce.h			  \
-	relation.c relation.h			  \
-	scan-gram-c.c				  \
-	scan-skel-c.c scan-skel.h		  \
-	state.c state.h				  \
-	symlist.c symlist.h			  \
-	symtab.c symtab.h			  \
-	system.h				  \
-	tables.h tables.c			  \
-	uniqstr.c uniqstr.h			  \
-	vcg.c vcg.h				  \
-	vcg_defaults.h
+  AnnotationList.c AnnotationList.h             \
+  InadequacyList.c InadequacyList.h             \
+  LR0.c LR0.h                                   \
+  Sbitset.c Sbitset.h                           \
+  assoc.c assoc.h                               \
+  closure.c closure.h                           \
+  complain.c complain.h                         \
+  conflicts.c conflicts.h                       \
+  derives.c derives.h                           \
+  files.c files.h                               \
+  flex-scanner.h                                \
+  getargs.c getargs.h                           \
+  gram.c gram.h                                 \
+  lalr.h lalr.c                                 \
+  ielr.h ielr.c                                 \
+  location.c location.h                         \
+  main.c                                        \
+  muscle-tab.c muscle-tab.h                     \
+  named-ref.c named-ref.h                       \
+  nullable.c nullable.h                         \
+  output.c output.h                             \
+  parse-gram.y                                  \
+  print.c print.h                               \
+  print_graph.c print_graph.h                   \
+  print-xml.c print-xml.h                       \
+  reader.c reader.h                             \
+  reduce.c reduce.h                             \
+  relation.c relation.h                         \
+  scan-code.h scan-code-c.c                     \
+  scan-gram.h scan-gram-c.c                     \
+  scan-skel.h scan-skel-c.c                     \
+  state.c state.h                               \
+  symlist.c symlist.h                           \
+  symtab.c symtab.h                             \
+  system.h                                      \
+  tables.h tables.c                             \
+  uniqstr.c uniqstr.h                           \
+  graphviz.c graphviz.h
 
-EXTRA_bison_SOURCES = scan-skel.l scan-gram.l
-BUILT_SOURCES = scan-skel.c scan-gram.c parse-gram.c parse-gram.h
+EXTRA_bison_SOURCES = scan-code.l scan-skel.l scan-gram.l
+BUILT_SOURCES = \
+  parse-gram.c parse-gram.h                     \
+  scan-code.c                                   \
+  scan-skel.c                                   \
+  scan-gram.c
+
 MOSTLYCLEANFILES = yacc
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -288,14 +1483,14 @@
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
-	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-		&& exit 0; \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/Makefile'; \
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  src/Makefile
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnits src/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -313,51 +1508,119 @@
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
 install-binPROGRAMS: $(bin_PROGRAMS)
 	@$(NORMAL_INSTALL)
-	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
-	@list='$(bin_PROGRAMS)'; for p in $$list; do \
-	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-	  if test -f $$p \
-	  ; then \
-	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-	   echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
-	   $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
-	  else :; fi; \
-	done
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	      echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	      $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
 
 uninstall-binPROGRAMS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(bin_PROGRAMS)'; for p in $$list; do \
-	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
-	done
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
 
 clean-binPROGRAMS:
 	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-bison$(EXEEXT): $(bison_OBJECTS) $(bison_DEPENDENCIES) 
+
+installcheck-binPROGRAMS: $(bin_PROGRAMS)
+	bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \
+	  case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
+	   *" $$p "* | *" $(srcdir)/$$p "*) continue;; \
+	  esac; \
+	  f=`echo "$$p" | \
+	     sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  for opt in --help --version; do \
+	    if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \
+	         2>c$${pid}_.err </dev/null \
+		 && test -n "`cat c$${pid}_.out`" \
+		 && test -z "`cat c$${pid}_.err`"; then :; \
+	    else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
+	  done; \
+	done; rm -f c$${pid}_.???; exit $$bad
+parse-gram.h: parse-gram.c
+	@if test ! -f $@; then rm -f parse-gram.c; else :; fi
+	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) parse-gram.c; else :; fi
+bison$(EXEEXT): $(bison_OBJECTS) $(bison_DEPENDENCIES) $(EXTRA_bison_DEPENDENCIES) 
 	@rm -f bison$(EXEEXT)
-	$(LINK) $(bison_LDFLAGS) $(bison_OBJECTS) $(bison_LDADD) $(LIBS)
+	$(AM_V_CCLD)$(LINK) $(bison_OBJECTS) $(bison_LDADD) $(LIBS)
 install-binSCRIPTS: $(bin_SCRIPTS)
 	@$(NORMAL_INSTALL)
-	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
-	@list='$(bin_SCRIPTS)'; for p in $$list; do \
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f $$d$$p; then \
-	    f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
-	    echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
-	    $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
-	  else :; fi; \
-	done
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
 
 uninstall-binSCRIPTS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(bin_SCRIPTS)'; for p in $$list; do \
-	  f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
-	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
-	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
-	done
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+installcheck-binSCRIPTS: $(bin_SCRIPTS)
+	bad=0; pid=$$$$; list="$(bin_SCRIPTS)"; for p in $$list; do \
+	  case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
+	   *" $$p "* | *" $(srcdir)/$$p "*) continue;; \
+	  esac; \
+	  f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \
+	  for opt in --help --version; do \
+	    if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \
+	         2>c$${pid}_.err </dev/null \
+		 && test -n "`cat c$${pid}_.out`" \
+		 && test -z "`cat c$${pid}_.err`"; then :; \
+	    else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
+	  done; \
+	done; rm -f c$${pid}_.???; exit $$bad
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -365,7 +1628,10 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnotationList.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InadequacyList.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LR0.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sbitset.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assoc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/complain.Po@am__quote@
@@ -374,18 +1640,24 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getargs.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gram.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graphviz.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ielr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lalr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/location.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muscle_tab.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muscle-tab.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/named-ref.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nullable.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse-gram.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print-xml.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print_graph.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reduce.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relation.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan-code-c.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan-code.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan-gram-c.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan-gram.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan-skel-c.Po@am__quote@
@@ -395,119 +1667,120 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symtab.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tables.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniqstr.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcg.Po@am__quote@
 
 .c.o:
-@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
-@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .l.c:
-	$(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
+	$(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
 
 .y.c:
-	$(YACCCOMPILE) $<
-	if test -f y.tab.h; then \
-	  to=`echo "$*_H" | sed \
-                -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-                -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
-	  sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
-            y.tab.h >$*.ht; \
-	  rm -f y.tab.h; \
-	  if cmp -s $*.ht $*.h; then \
-	    rm -f $*.ht ;\
-	  else \
-	    mv $*.ht $*.h; \
-	  fi; \
-	fi
-	if test -f y.output; then \
-	  mv y.output $*.output; \
-	fi
-	sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
-	rm -f y.tab.c
-uninstall-info-am:
+	$(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE)
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
 TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
-	tags=; \
+	set x; \
 	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
 	fi
 ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
+	     $$unique
 
 GTAGS:
 	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+cscopelist:  $(HEADERS) $(SOURCES) $(LISP)
+	list='$(SOURCES) $(HEADERS) $(LISP)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
 	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
 	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
 	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
 	    || exit 1; \
 	  fi; \
 	done
@@ -517,7 +1790,7 @@
 all-am: Makefile $(PROGRAMS) $(SCRIPTS)
 installdirs:
 	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) install-am
@@ -530,10 +1803,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
@@ -541,11 +1819,14 @@
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
 	-rm -f parse-gram.c
+	-rm -f parse-gram.h
+	-rm -f scan-code.c
 	-rm -f scan-gram.c
 	-rm -f scan-skel.c
 	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
@@ -565,19 +1846,39 @@
 
 html: html-am
 
+html-am:
+
 info: info-am
 
 info-am:
 
 install-data-am:
 
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
 install-exec-am: install-binPROGRAMS install-binSCRIPTS
 
+install-html: install-html-am
+
+install-html-am:
+
 install-info: install-info-am
 
+install-info-am:
+
 install-man:
 
-installcheck-am:
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am: installcheck-binPROGRAMS installcheck-binSCRIPTS
 
 maintainer-clean: maintainer-clean-am
 	-rm -rf ./$(DEPDIR)
@@ -596,29 +1897,30 @@
 
 ps-am:
 
-uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
-	uninstall-info-am
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS
+
+.MAKE: all check install install-am install-strip
 
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
-	clean-generic ctags distclean distclean-compile \
+	clean-generic cscopelist ctags distclean distclean-compile \
 	distclean-generic distclean-tags distdir dvi dvi-am html \
 	html-am info info-am install install-am install-binPROGRAMS \
-	install-binSCRIPTS install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am install-man \
-	install-strip installcheck installcheck-am installdirs \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am \
+	installcheck-binPROGRAMS installcheck-binSCRIPTS installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
 	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
 	tags uninstall uninstall-am uninstall-binPROGRAMS \
-	uninstall-binSCRIPTS uninstall-info-am
+	uninstall-binSCRIPTS
 
 
 yacc:
-	echo '#! /bin/sh' >$@
-	echo 'exec $(bindir)/bison -y "$$@"' >>$@
-	chmod a+x $@
-
-echo:
-	echo $(bison_SOURCES) $(noinst_HEADERS)
+	$(AM_V_GEN)echo '#! /bin/sh' >$@
+	$(AM_V_at)echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@
+	$(AM_V_at)chmod a+x $@
 
 # The following rule is not designed to be portable,
 # and relies on tools that not everyone has.
@@ -650,6 +1952,7 @@
 	  echo 'the above variables should have static scope' 1>&2;	\
 	  exit 1;							\
 	fi
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/src/Sbitset.c b/src/Sbitset.c
new file mode 100644
index 0000000..ce65f37
--- /dev/null
+++ b/src/Sbitset.c
@@ -0,0 +1,80 @@
+/* A simple, memory-efficient bitset implementation.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include "Sbitset.h"
+
+Sbitset
+Sbitset__new (Sbitset__Index nbits)
+{
+  /* Some functions, like Sbitset__last_byte_mask, will fail if nbits = 0.  */
+  aver (nbits);
+  return xcalloc (1, Sbitset__nbytes (nbits));
+}
+
+Sbitset
+Sbitset__new_on_obstack (Sbitset__Index nbits, struct obstack *obstackp)
+{
+  Sbitset result;
+  Sbitset ptr;
+  Sbitset end;
+  aver (nbits);
+  result = obstack_alloc (obstackp, Sbitset__nbytes (nbits));
+  for (ptr = result, end = result + Sbitset__nbytes (nbits); ptr < end; ++ptr)
+    *ptr = 0;
+  return result;
+}
+
+void
+Sbitset__delete (Sbitset self)
+{
+  free (self);
+}
+
+bool
+Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits)
+{
+  Sbitset last = self + Sbitset__nbytes (nbits) - 1;
+  for (; self < last; ++self)
+    if (*self != 0)
+      return false;
+  return ((*last) & Sbitset__last_byte_mask (nbits)) == 0;
+}
+
+void
+Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file)
+{
+  Sbitset__Index i;
+  Sbitset itr;
+  bool first = true;
+  fprintf (file,
+           "nbits = %" SBITSET__INDEX__CONVERSION_SPEC ", set = {",
+           nbits);
+  SBITSET__FOR_EACH (self, nbits, itr, i)
+    {
+      if (first)
+        first = false;
+      else
+        fprintf (file, ",");
+      fprintf (file, " %" SBITSET__INDEX__CONVERSION_SPEC, i);
+    }
+  fprintf (file, " }");
+}
diff --git a/src/Sbitset.h b/src/Sbitset.h
new file mode 100644
index 0000000..4a32402
--- /dev/null
+++ b/src/Sbitset.h
@@ -0,0 +1,92 @@
+/* A simple, memory-efficient bitset implementation.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef SBITSET_H_
+# define SBITSET_H_
+
+typedef unsigned char *Sbitset;
+typedef size_t Sbitset__Index;
+#define SBITSET__INDEX__CONVERSION_SPEC "zu"
+
+#define Sbitset__nbytes(NBITS) \
+  (((NBITS) + CHAR_BIT - 1) / CHAR_BIT)
+#define Sbitset__byteAddress(SELF, INDEX) \
+  (((SELF) + (INDEX) / CHAR_BIT))
+#define Sbitset__bit_mask(INDEX) \
+  (1 << (CHAR_BIT - 1 - (INDEX) % CHAR_BIT))
+#define Sbitset__last_byte_mask(NBITS) \
+  (UCHAR_MAX << (CHAR_BIT - 1 - ((NBITS) - 1) % CHAR_BIT))
+
+/* nbits must not be 0.  */
+Sbitset Sbitset__new (Sbitset__Index nbits);
+Sbitset Sbitset__new_on_obstack (Sbitset__Index nbits,
+                                 struct obstack *obstackp);
+void Sbitset__delete (Sbitset self);
+
+#define Sbitset__test(SELF, INDEX)                                            \
+  ((*Sbitset__byteAddress ((SELF), (INDEX)) & Sbitset__bit_mask (INDEX)) != 0)
+
+bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits);
+
+void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file);
+
+#define Sbitset__set(SELF, INDEX)                                             \
+do {                                                                          \
+  *Sbitset__byteAddress ((SELF), (INDEX)) =                                   \
+    *Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX);      \
+} while(0)
+
+#define Sbitset__reset(SELF, INDEX)                                           \
+do {                                                                          \
+  *Sbitset__byteAddress ((SELF), (INDEX)) =                                   \
+    *Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX);     \
+} while(0)
+
+/* NBITS is the size of the bitset.  More than NBITS bits might be reset.  */
+#define Sbitset__zero(SELF, NBITS)                                            \
+do {                                                                          \
+  memset (SELF, 0, Sbitset__nbytes (NBITS));                                  \
+} while(0)
+
+/* NBITS is the size of the bitset.  More than NBITS bits might be set.  */
+#define Sbitset__ones(SELF, NBITS)                                            \
+do {                                                                          \
+  memset (SELF, UCHAR_MAX, Sbitset__nbytes (NBITS));                          \
+} while(0)
+
+/* NBITS is the size of every bitset.  More than NBITS bits might be set.  */
+#define Sbitset__or(SELF, OTHER1, OTHER2, NBITS)                              \
+do {                                                                          \
+  Sbitset ptr_self = (SELF);                                                  \
+  Sbitset ptr_other1 = (OTHER1);                                              \
+  Sbitset ptr_other2 = (OTHER2);                                              \
+  Sbitset end_self = ptr_self + Sbitset__nbytes (NBITS);                      \
+  for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2)         \
+    *ptr_self = *ptr_other1 | *ptr_other2;                                    \
+} while(0)
+
+#define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX)                           \
+  for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER))  \
+    if (*(ITER) != 0)                                                         \
+      for ((INDEX) = ((ITER)-(SELF))*CHAR_BIT;                                \
+           (INDEX) < (NBITS) && (SELF)+(INDEX)/CHAR_BIT < (ITER)+1;           \
+           ++(INDEX))                                                         \
+        if (((*ITER) & Sbitset__bit_mask (INDEX)) != 0)
+
+#endif /* !SBITSET_H_ */
diff --git a/src/assoc.c b/src/assoc.c
index 6f9a3b5..989cb26 100644
--- a/src/assoc.c
+++ b/src/assoc.c
@@ -1,22 +1,22 @@
 /* Associativity information.
-   Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
+
+   Copyright (C) 2002, 2005-2006, 2009-2012 Free Software Foundation,
+   Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
diff --git a/src/assoc.h b/src/assoc.h
index 778a451..54f9b65 100644
--- a/src/assoc.h
+++ b/src/assoc.h
@@ -1,22 +1,21 @@
 /* Associativity information.
-   Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+
+   Copyright (C) 2002, 2006, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef ASSOC_H_
 # define ASSOC_H_
diff --git a/src/closure.c b/src/closure.c
index 001b831..d9bc5ff 100644
--- a/src/closure.c
+++ b/src/closure.c
@@ -1,24 +1,22 @@
 /* Closures for Bison
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005 Free
+   Copyright (C) 1984, 1989, 2000-2002, 2004-2005, 2007, 2009-2012 Free
    Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
@@ -26,7 +24,6 @@
 #include <bitset.h>
 #include <bitsetv-print.h>
 #include <bitsetv.h>
-#include <quotearg.h>
 
 #include "closure.h"
 #include "derives.h"
@@ -37,7 +34,7 @@
 
 /* NITEMSET is the size of the array ITEMSET.  */
 item_number *itemset;
-size_t nritemset;
+size_t nitemset;
 
 static bitset ruleset;
 
@@ -213,30 +210,32 @@
     if (ISVAR (ritem[core[c]]))
       bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
 
-  nritemset = 0;
+  /* core is sorted on item index in ritem, which is sorted on rule number.
+     Compute itemset with the same sort.  */
+  nitemset = 0;
   c = 0;
   BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
     {
       item_number itemno = rules[ruleno].rhs - ritem;
       while (c < n && core[c] < itemno)
 	{
-	  itemset[nritemset] = core[c];
-	  nritemset++;
+	  itemset[nitemset] = core[c];
+	  nitemset++;
 	  c++;
 	}
-      itemset[nritemset] = itemno;
-      nritemset++;
+      itemset[nitemset] = itemno;
+      nitemset++;
     };
 
   while (c < n)
     {
-      itemset[nritemset] = core[c];
-      nritemset++;
+      itemset[nitemset] = core[c];
+      nitemset++;
       c++;
     }
 
   if (trace_flag & trace_sets)
-    print_closure ("output", itemset, nritemset);
+    print_closure ("output", itemset, nitemset);
 }
 
 
diff --git a/src/closure.h b/src/closure.h
index a2582e8..0f96a8b 100644
--- a/src/closure.h
+++ b/src/closure.h
@@ -1,24 +1,22 @@
 /* Subroutines for bison
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software
+   Copyright (C) 1984, 1989, 2000-2002, 2007, 2009-2012 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef CLOSURE_H_
 # define CLOSURE_H_
@@ -32,7 +30,7 @@
 void new_closure (unsigned int n);
 
 
-/* Given the kernel (aka core) of a state (a vector of item numbers
+/* Given the kernel (aka core) of a state (a sorted vector of item numbers
    ITEMS, of length N), set up RULESET and ITEMSET to indicate what
    rules could be run and which items could be accepted when those
    items are the active ones.
@@ -41,7 +39,7 @@
    all rules which could potentially describe the next input to be
    read.
 
-   ITEMSET is a vector of item numbers; NITEMSET is its size
+   ITEMSET is a sorted vector of item numbers; NITEMSET is its size
    (actually, points to just beyond the end of the part of it that is
    significant).  CLOSURE places there the indices of all items which
    represent units of input that could arrive next.  */
@@ -54,6 +52,6 @@
 void free_closure (void);
 
 extern item_number *itemset;
-extern size_t nritemset;
+extern size_t nitemset;
 
 #endif /* !CLOSURE_H_ */
diff --git a/src/complain.c b/src/complain.c
index 927dbb6..ede0ccf 100644
--- a/src/complain.c
+++ b/src/complain.c
@@ -1,11 +1,12 @@
 /* Declaration for error-reporting function for Bison.
 
-   Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2004-2006, 2009-2012 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 2, or (at your option) any
-   later version.
+   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
@@ -13,9 +14,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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-   USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Based on error.c and error.h,
    written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
@@ -24,57 +23,124 @@
 #include "system.h"
 
 #include <stdarg.h>
+#include <progname.h>
 
 #include "complain.h"
 #include "files.h"
+#include "getargs.h"
 
-/* The calling program should define program_name and set it to the
-   name of the executing program.  */
-extern char *program_name;
-
-/* This variable is set each time `warn' is called.  */
-bool warning_issued;
-
-/* This variable is set each time `complain' is called.  */
 bool complaint_issued;
+static unsigned *indent_ptr = 0;
 
 
+
+/** Report an error message.
+ *
+ * \param loc     the location, defaulting to the current file,
+ *                or the program name.
+ * \param prefix  put before the message (e.g., "warning").
+ * \param message the error message, a printf format string.  Iff it
+ *                ends with ": ", then no trailing newline is printed,
+ *                and the caller should print the remaining
+ *                newline-terminated message to stderr.
+ * \param args    the arguments of the format string.
+ */
+static
+void
+error_message (location *loc,
+	       const char *prefix,
+	       const char *message, va_list args)
+{
+  unsigned pos = 0;
+
+  if (loc)
+    pos += location_print (stderr, *loc);
+  else
+    pos += fprintf(stderr, "%s", current_file ? current_file : program_name);
+  pos += fprintf(stderr, ": ");
+
+  if (indent_ptr)
+    {
+      if (!*indent_ptr)
+        *indent_ptr = pos;
+      else if (*indent_ptr > pos)
+        fprintf (stderr, "%*s", *indent_ptr - pos, "");
+      indent_ptr = 0;
+    }
+
+  if (prefix)
+    fprintf (stderr, "%s: ", prefix);
+
+  vfprintf (stderr, message, args);
+  {
+    size_t l = strlen (message);
+    if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
+      {
+        putc ('\n', stderr);
+        fflush (stderr);
+        if (loc && feature_flag & feature_caret)
+          location_caret (stderr, *loc);
+      }
+  }
+  fflush (stderr);
+}
+
+/** Wrap error_message() with varargs handling. */
+#define ERROR_MESSAGE(Loc, Prefix, Message)	\
+{						\
+  va_list args;					\
+  va_start (args, Message);			\
+  error_message (Loc, Prefix, Message, args);	\
+  va_end (args);				\
+}
+
+
 /*--------------------------------.
 | Report a warning, and proceed.  |
 `--------------------------------*/
 
 void
+set_warning_issued (void)
+{
+  static bool warning_issued = false;
+  if (!warning_issued && (warnings_flag & warnings_error))
+    {
+      fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
+      complaint_issued = true;
+    }
+  warning_issued = true;
+}
+
+void
 warn_at (location loc, const char *message, ...)
 {
-  va_list args;
+  if (!(warnings_flag & warnings_other))
+    return;
+  set_warning_issued ();
+  ERROR_MESSAGE (&loc, _("warning"), message);
+}
 
-  location_print (stderr, loc);
-  fputs (": ", stderr);
-  fputs (_("warning: "), stderr);
-
-  va_start (args, message);
-  vfprintf (stderr, message, args);
-  va_end (args);
-
-  warning_issued = true;
-  putc ('\n', stderr);
+void
+warn_at_indent (location loc, unsigned *indent,
+                const char *message, ...)
+{
+  if (!(warnings_flag & warnings_other))
+    return;
+  set_warning_issued ();
+  indent_ptr = indent;
+  ERROR_MESSAGE (&loc, *indent ? NULL : _("warning"), message);
 }
 
 void
 warn (const char *message, ...)
 {
-  va_list args;
-
-  fprintf (stderr, "%s: %s", current_file ? current_file : program_name, _("warning: "));
-
-  va_start (args, message);
-  vfprintf (stderr, message, args);
-  va_end (args);
-
-  warning_issued = true;
-  putc ('\n', stderr);
+  if (!(warnings_flag & warnings_other))
+    return;
+  set_warning_issued ();
+  ERROR_MESSAGE (NULL, _("warning"), message);
 }
-
+
+
 /*-----------------------------------------------------------.
 | An error has occurred, but we can proceed, and die later.  |
 `-----------------------------------------------------------*/
@@ -82,34 +148,56 @@
 void
 complain_at (location loc, const char *message, ...)
 {
-  va_list args;
-
-  location_print (stderr, loc);
-  fputs (": ", stderr);
-
-  va_start (args, message);
-  vfprintf (stderr, message, args);
-  va_end (args);
-
+  ERROR_MESSAGE (&loc, _("error"), message);
   complaint_issued = true;
-  putc ('\n', stderr);
+}
+
+void
+complain_at_indent (location loc, unsigned *indent,
+                    const char *message, ...)
+{
+  indent_ptr = indent;
+  ERROR_MESSAGE (&loc, *indent ? NULL : _("error"), message);
+  complaint_issued = true;
 }
 
 void
 complain (const char *message, ...)
 {
-  va_list args;
-
-  fprintf (stderr, "%s: ", current_file ? current_file : program_name);
-
-  va_start (args, message);
-  vfprintf (stderr, message, args);
-  va_end (args);
-
+  ERROR_MESSAGE (NULL, _("error"), message);
   complaint_issued = true;
-  putc ('\n', stderr);
 }
-
+
+
+/*--------------------------------------------------------------.
+| An incompatibility with POSIX Yacc: mapped either to warn* or |
+| complain* depending on yacc_flag.                             |
+`--------------------------------------------------------------*/
+
+void
+yacc_at (location loc, const char *message, ...)
+{
+  if (yacc_flag)
+    {
+      ERROR_MESSAGE (&loc, NULL, message);
+      complaint_issued = true;
+    }
+  else if (warnings_flag & warnings_yacc)
+    {
+      set_warning_issued ();
+      ERROR_MESSAGE (&loc, _("warning"), message);
+    }
+}
+
+void
+midrule_value_at (location loc, const char *message, ...)
+{
+  if (!(warnings_flag & warnings_midrule_values))
+    return;
+  set_warning_issued ();
+  ERROR_MESSAGE (&loc, _("warning"), message);
+}
+
 /*-------------------------------------------------.
 | A severe error has occurred, we cannot proceed.  |
 `-------------------------------------------------*/
@@ -117,31 +205,13 @@
 void
 fatal_at (location loc, const char *message, ...)
 {
-  va_list args;
-
-  location_print (stderr, loc);
-  fputs (": ", stderr);
-  fputs (_("fatal error: "), stderr);
-
-  va_start (args, message);
-  vfprintf (stderr, message, args);
-  va_end (args);
-  putc ('\n', stderr);
+  ERROR_MESSAGE (&loc, _("fatal error"), message);
   exit (EXIT_FAILURE);
 }
 
 void
 fatal (const char *message, ...)
 {
-  va_list args;
-
-  fprintf (stderr, "%s: ", current_file ? current_file : program_name);
-
-  fputs (_("fatal error: "), stderr);
-
-  va_start (args, message);
-  vfprintf (stderr, message, args);
-  va_end (args);
-  putc ('\n', stderr);
+  ERROR_MESSAGE (NULL, _("fatal error"), message);
   exit (EXIT_FAILURE);
 }
diff --git a/src/complain.h b/src/complain.h
index 9ae334a..997d577 100644
--- a/src/complain.h
+++ b/src/complain.h
@@ -1,10 +1,12 @@
 /* Declaration for error-reporting function for Bison.
-   Copyright (C) 2000, 2001, 2002 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 2, or (at your option) any
-   later version.
+   Copyright (C) 2000-2002, 2006, 2009-2012 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
@@ -12,9 +14,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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-   USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef COMPLAIN_H_
 # define COMPLAIN_H_ 1
@@ -25,7 +25,18 @@
 extern "C" {
 # endif
 
-/* Informative messages, but we proceed.  */
+/* Sub-messages indent. */
+#define SUB_INDENT (4)
+
+/** Record that a warning is about to be issued, and treat it as an
+    error if <tt>warnings_flag & warnings_error</tt>.  This is exported
+    only for the sake of Yacc-compatible conflict reports in conflicts.c.
+    All other warnings should be implemented in complain.c and should use
+    the normal warning format.  */
+void set_warning_issued (void);
+
+/** Informative messages, but we proceed.  Report iff
+    <tt>warnings_flag & warnings_other</tt>.  */
 
 void warn (char const *format, ...)
   __attribute__ ((__format__ (__printf__, 1, 2)));
@@ -33,7 +44,14 @@
 void warn_at (location loc, char const *format, ...)
   __attribute__ ((__format__ (__printf__, 2, 3)));
 
-/* Something bad happened, but let's continue and die later.  */
+/* Generate a message aligned by an indent.
+   When *indent == 0, assign message's indent to *indent,
+   When *indent > 0, align the message by *indent value. */
+void warn_at_indent (location loc, unsigned *indent,
+                     char const *format, ...)
+  __attribute__ ((__format__ (__printf__, 3, 4)));
+
+/** An error, but we continue and die later.  */
 
 void complain (char const *format, ...)
   __attribute__ ((__format__ (__printf__, 1, 2)));
@@ -41,7 +59,26 @@
 void complain_at (location loc, char const *format, ...)
   __attribute__ ((__format__ (__printf__, 2, 3)));
 
-/* Something bad happened, and let's die now.  */
+/* Generate a message aligned by an indent.
+   When *indent == 0, assign message's indent to *indent,
+   When *indent > 0, align the message by *indent value. */
+void complain_at_indent (location loc, unsigned *indent,
+                         char const *format, ...)
+  __attribute__ ((__format__ (__printf__, 3, 4)));
+
+/** An incompatibility with POSIX Yacc: mapped either to warn* or
+    complain* depending on yacc_flag. */
+
+void yacc_at (location loc, char const *format, ...)
+  __attribute__ ((__format__ (__printf__, 2, 3)));
+
+/** A midrule-value warning.  Report iff
+    <tt>warnings_flag & warnings_midrule_values</tt>.  */
+
+void midrule_value_at (location loc, char const *format, ...)
+  __attribute__ ((__format__ (__printf__, 2, 3)));
+
+/** A fatal error, causing immediate exit.  */
 
 void fatal (char const *format, ...)
   __attribute__ ((__noreturn__, __format__ (__printf__, 1, 2)));
@@ -49,10 +86,7 @@
 void fatal_at (location loc, char const *format, ...)
   __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
 
-/* This variable is set each time `warn' is called.  */
-extern bool warning_issued;
-
-/* This variable is set each time `complain' is called.  */
+/** Whether an error was reported.  */
 extern bool complaint_issued;
 
 # ifdef	__cplusplus
diff --git a/src/conflicts.c b/src/conflicts.c
index 13121f6..ba0b6ed 100644
--- a/src/conflicts.c
+++ b/src/conflicts.c
@@ -1,24 +1,22 @@
-/* Find and resolve or report look-ahead conflicts for bison,
+/* Find and resolve or report lookahead conflicts for bison,
 
-   Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1992, 2000-2007, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
@@ -32,6 +30,7 @@
 #include "getargs.h"
 #include "gram.h"
 #include "lalr.h"
+#include "print-xml.h"
 #include "reader.h"
 #include "state.h"
 #include "symtab.h"
@@ -41,9 +40,10 @@
 int expected_rr_conflicts = -1;
 static char *conflicts;
 static struct obstack solved_conflicts_obstack;
+static struct obstack solved_conflicts_xml_obstack;
 
 static bitset shift_set;
-static bitset look_ahead_set;
+static bitset lookahead_set;
 
 
 
@@ -73,24 +73,26 @@
 	{
 	case shift_resolution:
 	case right_resolution:
-	  obstack_fgrow2 (&solved_conflicts_obstack,
-			  _("\
-    Conflict between rule %d and token %s resolved as shift"),
+	  obstack_printf (&solved_conflicts_obstack,
+			  _("    Conflict between rule %d and token %s"
+			    " resolved as shift"),
 			  r->number,
 			  symbols[token]->tag);
 	  break;
+
 	case reduce_resolution:
 	case left_resolution:
-	  obstack_fgrow2 (&solved_conflicts_obstack,
-			  _("\
-    Conflict between rule %d and token %s resolved as reduce"),
+	  obstack_printf (&solved_conflicts_obstack,
+			  _("    Conflict between rule %d and token %s"
+			    " resolved as reduce"),
 			  r->number,
 			  symbols[token]->tag);
 	  break;
+
 	case nonassoc_resolution:
-	  obstack_fgrow2 (&solved_conflicts_obstack,
-			  _("\
-    Conflict between rule %d and token %s resolved as an error"),
+	  obstack_printf (&solved_conflicts_obstack,
+			  _("    Conflict between rule %d and token %s"
+			    " resolved as an error"),
 			  r->number,
 			  symbols[token]->tag);
 	  break;
@@ -100,45 +102,119 @@
       switch (resolution)
 	{
 	case shift_resolution:
-	  obstack_fgrow2 (&solved_conflicts_obstack,
+	  obstack_printf (&solved_conflicts_obstack,
 			  " (%s < %s)",
 			  r->prec->tag,
 			  symbols[token]->tag);
 	  break;
 
 	case reduce_resolution:
-	  obstack_fgrow2 (&solved_conflicts_obstack,
+	  obstack_printf (&solved_conflicts_obstack,
 			  " (%s < %s)",
 			  symbols[token]->tag,
 			  r->prec->tag);
 	  break;
 
 	case left_resolution:
-	  obstack_fgrow1 (&solved_conflicts_obstack,
+	  obstack_printf (&solved_conflicts_obstack,
 			  " (%%left %s)",
 			  symbols[token]->tag);
 	  break;
 
 	case right_resolution:
-	  obstack_fgrow1 (&solved_conflicts_obstack,
+	  obstack_printf (&solved_conflicts_obstack,
 			  " (%%right %s)",
 			  symbols[token]->tag);
 	  break;
+
 	case nonassoc_resolution:
-	  obstack_fgrow1 (&solved_conflicts_obstack,
+	  obstack_printf (&solved_conflicts_obstack,
 			  " (%%nonassoc %s)",
 			  symbols[token]->tag);
 	  break;
 	}
+
       obstack_sgrow (&solved_conflicts_obstack, ".\n");
     }
+
+  /* XML report */
+  if (xml_flag)
+    {
+      /* The description of the resolution. */
+      switch (resolution)
+        {
+        case shift_resolution:
+        case right_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "        <resolution rule=\"%d\" symbol=\"%s\""
+                          " type=\"shift\">",
+                          r->number,
+                          xml_escape (symbols[token]->tag));
+          break;
+
+        case reduce_resolution:
+        case left_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "        <resolution rule=\"%d\" symbol=\"%s\""
+                          " type=\"reduce\">",
+                          r->number,
+                          xml_escape (symbols[token]->tag));
+          break;
+
+        case nonassoc_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "        <resolution rule=\"%d\" symbol=\"%s\""
+                          " type=\"error\">",
+                          r->number,
+                          xml_escape (symbols[token]->tag));
+          break;
+        }
+
+      /* The reason. */
+      switch (resolution)
+        {
+        case shift_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "%s &lt; %s",
+                          xml_escape_n (0, r->prec->tag),
+                          xml_escape_n (1, symbols[token]->tag));
+          break;
+
+        case reduce_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "%s &lt; %s",
+                          xml_escape_n (0, symbols[token]->tag),
+                          xml_escape_n (1, r->prec->tag));
+          break;
+
+        case left_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "%%left %s",
+                          xml_escape (symbols[token]->tag));
+          break;
+
+        case right_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "%%right %s",
+                          xml_escape (symbols[token]->tag));
+          break;
+
+        case nonassoc_resolution:
+          obstack_printf (&solved_conflicts_xml_obstack,
+                          "%%nonassoc %s",
+                          xml_escape (symbols[token]->tag));
+      break;
+        }
+
+      obstack_sgrow (&solved_conflicts_xml_obstack, "</resolution>\n");
+    }
 }
 
 
 /*------------------------------------------------------------------.
 | Turn off the shift recorded for the specified token in the        |
 | specified state.  Used when we resolve a shift-reduce conflict in |
-| favor of the reduction.                                           |
+| favor of the reduction or as an error (%nonassoc).                |
 `------------------------------------------------------------------*/
 
 static void
@@ -147,7 +223,7 @@
   transitions *trans = s->transitions;
   int i;
 
-  bitset_reset (look_ahead_set, token);
+  bitset_reset (lookahead_set, token);
   for (i = 0; i < trans->num; i++)
     if (!TRANSITION_IS_DISABLED (trans, i)
 	&& TRANSITION_SYMBOL (trans, i) == token)
@@ -156,15 +232,15 @@
 
 
 /*--------------------------------------------------------------------.
-| Turn off the reduce recorded for the specified token for the        |
-| specified look-ahead.  Used when we resolve a shift-reduce conflict |
-| in favor of the shift.                                              |
+| Turn off the reduce recorded for the specified token in the         |
+| specified lookahead set.  Used when we resolve a shift-reduce       |
+| conflict in favor of the shift or as an error (%nonassoc).          |
 `--------------------------------------------------------------------*/
 
 static void
-flush_reduce (bitset look_ahead_tokens, int token)
+flush_reduce (bitset lookahead_tokens, int token)
 {
-  bitset_reset (look_ahead_tokens, token);
+  bitset_reset (lookahead_tokens, token);
 }
 
 
@@ -174,25 +250,25 @@
 | rule has a precedence.  A conflict is resolved by modifying the   |
 | shift or reduce tables so that there is no longer a conflict.     |
 |                                                                   |
-| RULENO is the number of the look-ahead bitset to consider.      |
+| RULENO is the number of the lookahead bitset to consider.         |
 |                                                                   |
-| ERRORS can be used to store discovered explicit errors.           |
+| ERRORS and NERRS can be used to store discovered explicit         |
+| errors.                                                           |
 `------------------------------------------------------------------*/
 
 static void
-resolve_sr_conflict (state *s, int ruleno, symbol **errors)
+resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
 {
   symbol_number i;
   reductions *reds = s->reductions;
   /* Find the rule to reduce by to get precedence of reduction.  */
   rule *redrule = reds->rules[ruleno];
   int redprec = redrule->prec->prec;
-  bitset look_ahead_tokens = reds->look_ahead_tokens[ruleno];
-  int nerrs = 0;
+  bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
 
   for (i = 0; i < ntokens; i++)
-    if (bitset_test (look_ahead_tokens, i)
-	&& bitset_test (look_ahead_set, i)
+    if (bitset_test (lookahead_tokens, i)
+	&& bitset_test (lookahead_set, i)
 	&& symbols[i]->prec)
       {
 	/* Shift-reduce conflict occurs for token number i
@@ -206,7 +282,7 @@
 	else if (symbols[i]->prec > redprec)
 	  {
 	    log_resolution (redrule, i, shift_resolution);
-	    flush_reduce (look_ahead_tokens, i);
+	    flush_reduce (lookahead_tokens, i);
 	  }
 	else
 	  /* Matching precedence levels.
@@ -221,7 +297,7 @@
 
 	    case right_assoc:
 	      log_resolution (redrule, i, right_resolution);
-	      flush_reduce (look_ahead_tokens, i);
+	      flush_reduce (lookahead_tokens, i);
 	      break;
 
 	    case left_assoc:
@@ -232,25 +308,12 @@
 	    case non_assoc:
 	      log_resolution (redrule, i, nonassoc_resolution);
 	      flush_shift (s, i);
-	      flush_reduce (look_ahead_tokens, i);
+	      flush_reduce (lookahead_tokens, i);
 	      /* Record an explicit error for this token.  */
-	      errors[nerrs++] = symbols[i];
+	      errors[(*nerrs)++] = symbols[i];
 	      break;
 	    }
       }
-
-  if (nerrs)
-    {
-      /* Some tokens have been explicitly made errors.  Allocate a
-	 permanent errs structure for this state, to record them.  */
-      state_errs_set (s, nerrs, errors);
-    }
-
-  if (obstack_object_size (&solved_conflicts_obstack))
-    {
-      obstack_1grow (&solved_conflicts_obstack, '\0');
-      s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
-    }
 }
 
 
@@ -258,7 +321,7 @@
 | Solve the S/R conflicts of state S using the                       |
 | precedence/associativity, and flag it inconsistent if it still has |
 | conflicts.  ERRORS can be used as storage to compute the list of   |
-| look-ahead tokens on which S raises a syntax error (%nonassoc).    |
+| lookahead tokens on which S raises a syntax error (%nonassoc).     |
 `-------------------------------------------------------------------*/
 
 static void
@@ -267,31 +330,48 @@
   int i;
   transitions *trans = s->transitions;
   reductions *reds = s->reductions;
+  int nerrs = 0;
 
   if (s->consistent)
     return;
 
-  bitset_zero (look_ahead_set);
+  bitset_zero (lookahead_set);
 
   FOR_EACH_SHIFT (trans, i)
-    bitset_set (look_ahead_set, TRANSITION_SYMBOL (trans, i));
+    bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
 
-  /* Loop over all rules which require look-ahead in this state.  First
+  /* Loop over all rules which require lookahead in this state.  First
      check for shift-reduce conflict, and try to resolve using
      precedence.  */
   for (i = 0; i < reds->num; ++i)
     if (reds->rules[i]->prec && reds->rules[i]->prec->prec
-	&& !bitset_disjoint_p (reds->look_ahead_tokens[i], look_ahead_set))
-      resolve_sr_conflict (s, i, errors);
+	&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
+      resolve_sr_conflict (s, i, errors, &nerrs);
 
-  /* Loop over all rules which require look-ahead in this state.  Check
+  if (nerrs)
+    {
+      /* Some tokens have been explicitly made errors.  Allocate a
+         permanent errs structure for this state, to record them.  */
+      state_errs_set (s, nerrs, errors);
+    }
+  if (obstack_object_size (&solved_conflicts_obstack))
+    {
+      obstack_1grow (&solved_conflicts_obstack, '\0');
+      s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
+    }
+  if (obstack_object_size (&solved_conflicts_xml_obstack))
+    {
+      obstack_1grow (&solved_conflicts_xml_obstack, '\0');
+      s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack);
+    }
+
+  /* Loop over all rules which require lookahead in this state.  Check
      for conflicts not resolved above.  */
   for (i = 0; i < reds->num; ++i)
     {
-      if (!bitset_disjoint_p (reds->look_ahead_tokens[i], look_ahead_set))
+      if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
 	conflicts[s->number] = 1;
-
-      bitset_or (look_ahead_set, look_ahead_set, reds->look_ahead_tokens[i]);
+      bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
     }
 }
 
@@ -305,13 +385,14 @@
 conflicts_solve (void)
 {
   state_number i;
-  /* List of look-ahead tokens on which we explicitly raise a syntax error.  */
+  /* List of lookahead tokens on which we explicitly raise a syntax error.  */
   symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
 
   conflicts = xcalloc (nstates, sizeof *conflicts);
   shift_set = bitset_create (ntokens, BITSET_FIXED);
-  look_ahead_set = bitset_create (ntokens, BITSET_FIXED);
+  lookahead_set = bitset_create (ntokens, BITSET_FIXED);
   obstack_init (&solved_conflicts_obstack);
+  obstack_init (&solved_conflicts_xml_obstack);
 
   for (i = 0; i < nstates; i++)
     {
@@ -327,6 +408,17 @@
 }
 
 
+void
+conflicts_update_state_numbers (state_number old_to_new[],
+                                state_number nstates_old)
+{
+  state_number i;
+  for (i = 0; i < nstates_old; ++i)
+    if (old_to_new[i] != nstates_old)
+      conflicts[old_to_new[i]] = conflicts[i];
+}
+
+
 /*---------------------------------------------.
 | Count the number of shift/reduce conflicts.  |
 `---------------------------------------------*/
@@ -342,18 +434,18 @@
   if (!trans)
     return 0;
 
-  bitset_zero (look_ahead_set);
+  bitset_zero (lookahead_set);
   bitset_zero (shift_set);
 
   FOR_EACH_SHIFT (trans, i)
     bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
 
   for (i = 0; i < reds->num; ++i)
-    bitset_or (look_ahead_set, look_ahead_set, reds->look_ahead_tokens[i]);
+    bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
 
-  bitset_and (look_ahead_set, look_ahead_set, shift_set);
+  bitset_and (lookahead_set, lookahead_set, shift_set);
 
-  src_count = bitset_count (look_ahead_set);
+  src_count = bitset_count (lookahead_set);
 
   return src_count;
 }
@@ -378,7 +470,7 @@
       int count = 0;
       int j;
       for (j = 0; j < reds->num; ++j)
-	if (bitset_test (reds->look_ahead_tokens[j], i))
+	if (bitset_test (reds->lookahead_tokens[j], i))
 	  count++;
 
       if (count >= 2)
@@ -433,7 +525,7 @@
 /*--------------------------------------------------------.
 | Total the number of S/R and R/R conflicts.  Unlike the  |
 | code in conflicts_output, however, count EACH pair of   |
-| reductions for the same state and look-ahead as one     |
+| reductions for the same state and lookahead as one      |
 | conflict.						  |
 `--------------------------------------------------------*/
 
@@ -502,8 +594,17 @@
     return;
 
   /* Report the total number of conflicts on STDERR.  */
+  if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1)
+    {
+      if (!(warnings_flag & warnings_conflicts_sr))
+        src_total = 0;
+      if (!(warnings_flag & warnings_conflicts_rr))
+        rrc_total = 0;
+    }
   if (src_total | rrc_total)
     {
+      if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1)
+        set_warning_issued ();
       if (! yacc_flag)
 	fprintf (stderr, "%s: ", current_file);
       conflict_report (stderr, src_total, rrc_total);
@@ -530,6 +631,7 @@
 {
   free (conflicts);
   bitset_free (shift_set);
-  bitset_free (look_ahead_set);
+  bitset_free (lookahead_set);
   obstack_free (&solved_conflicts_obstack, NULL);
+  obstack_free (&solved_conflicts_xml_obstack, NULL);
 }
diff --git a/src/conflicts.h b/src/conflicts.h
index 4389e5e..5a03454 100644
--- a/src/conflicts.h
+++ b/src/conflicts.h
@@ -1,28 +1,41 @@
-/* Find and resolve or report look-ahead conflicts for bison,
-   Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+/* Find and resolve or report lookahead conflicts for bison,
+
+   Copyright (C) 2000-2002, 2004, 2007, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef CONFLICTS_H_
 # define CONFLICTS_H_
 # include "state.h"
 
 void conflicts_solve (void);
+
+/**
+ * Update state numbers recorded in internal arrays such that:
+ *   - \c nstates_old is the old number of states.
+ *   - Where \c i is the old state number, <tt>old_to_new[i]</tt> is either:
+ *     - \c nstates_old if state \c i is removed because it is unreachable.
+ *     - The new state number.
+ *   - The highest new state number is the number of remaining states - 1.
+ *   - The numerical order of the remaining states has not changed.
+ */
+void conflicts_update_state_numbers (state_number old_to_new[],
+                                     state_number nstates_old);
+
 void conflicts_print (void);
 int conflicts_total_count (void);
 void conflicts_output (FILE *out);
diff --git a/src/derives.c b/src/derives.c
index 2e4ff31..ce5a6a5 100644
--- a/src/derives.c
+++ b/src/derives.c
@@ -1,24 +1,22 @@
 /* Match rules with nonterminals for bison,
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 2000-2003, 2005, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
diff --git a/src/derives.h b/src/derives.h
index 9a45dc9..f25e502 100644
--- a/src/derives.h
+++ b/src/derives.h
@@ -1,24 +1,22 @@
 /* Match rules with nonterminals for bison,
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software
+   Copyright (C) 1984, 1989, 2000-2002, 2009-2012 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef DERIVES_H_
 # define DERIVES_H_
diff --git a/src/files.c b/src/files.c
index f3bb0f9..f698c7e 100644
--- a/src/files.c
+++ b/src/files.c
@@ -1,42 +1,38 @@
 /* Open and close files for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
 #include <error.h>
+#include <dirname.h>
 #include <get-errno.h>
 #include <quote.h>
+#include <quotearg.h>
+#include <stdio-safer.h>
 #include <xstrndup.h>
 
 #include "complain.h"
-#include "dirname.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "stdio-safer.h"
-
-struct obstack pre_prologue_obstack;
-struct obstack post_prologue_obstack;
 
 /* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is
    tempting, but don't do that: for the time being our handling of the
@@ -48,10 +44,15 @@
 char const *spec_outfile = NULL;       /* for -o. */
 char const *spec_file_prefix = NULL;   /* for -b. */
 char const *spec_name_prefix = NULL;   /* for -p. */
-char const *spec_verbose_file = NULL;  /* for --verbose. */
-char const *spec_graph_file = NULL;    /* for -g. */
-char const *spec_defines_file = NULL;  /* for --defines. */
-char const *parser_file_name;
+char *spec_verbose_file = NULL;  /* for --verbose. */
+char *spec_graph_file = NULL;    /* for -g. */
+char *spec_xml_file = NULL;      /* for -x. */
+char *spec_defines_file = NULL;  /* for --defines. */
+char *parser_file_name;
+
+/* All computed output file names.  */
+static char **file_names = NULL;
+static int file_names_count = 0;
 
 uniqstr grammar_file = NULL;
 uniqstr current_file = NULL;
@@ -72,14 +73,14 @@
    empty string (meaning the current directory); otherwise it is
    `dir/'.  */
 
-static char const *all_but_ext;
-static char const *all_but_tab_ext;
-char const *dir_prefix;
+char *all_but_ext;
+static char *all_but_tab_ext;
+char *dir_prefix;
 
 /* C source file extension (the parser source).  */
-static char const *src_extension = NULL;
+static char *src_extension = NULL;
 /* Header file extension (if option ``-d'' is specified).  */
-static char const *header_extension = NULL;
+static char *header_extension = NULL;
 
 /*-----------------------------------------------------------------.
 | Return a newly allocated string composed of the concatenation of |
@@ -109,7 +110,8 @@
 
   ptr = fopen_safer (name, mode);
   if (!ptr)
-    error (EXIT_FAILURE, get_errno (), _("cannot open file `%s'"), name);
+    error (EXIT_FAILURE, get_errno (),
+           _("%s: cannot open"), quotearg_colon (name));
 
   return ptr;
 }
@@ -125,7 +127,7 @@
     return;
 
   if (ferror (ptr))
-    error (EXIT_FAILURE, 0, _("I/O error"));
+    error (EXIT_FAILURE, 0, _("input/output error"));
 
   if (fclose (ptr) != 0)
     error (EXIT_FAILURE, get_errno (), _("cannot close file"));
@@ -136,31 +138,24 @@
 | Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
 `------------------------------------------------------------------*/
 
-/* Replace all characters FROM by TO in the string IN.
-   and returns a new allocated string.  */
-static char *
-tr (const char *in, char from, char to)
-{
-  char *temp;
-  char *out = xmalloc (strlen (in) + 1);
-
-  for (temp = out; *in; in++, out++)
-    if (*in == from)
-      *out = to;
-    else
-      *out = *in;
-  *out = 0;
-  return (temp);
-}
-
 /* Compute extensions from the grammar file extension.  */
 static void
 compute_exts_from_gf (const char *ext)
 {
-  src_extension = tr (ext, 'y', 'c');
-  src_extension = tr (src_extension, 'Y', 'C');
-  header_extension = tr (ext, 'y', 'h');
-  header_extension = tr (header_extension, 'Y', 'H');
+  if (strcmp (ext, ".y") == 0)
+    {
+      src_extension = xstrdup (language->src_extension);
+      header_extension = xstrdup (language->header_extension);
+    }
+  else
+    {
+      src_extension = xstrdup (ext);
+      header_extension = xstrdup (ext);
+      tr (src_extension, 'y', 'c');
+      tr (src_extension, 'Y', 'C');
+      tr (header_extension, 'y', 'h');
+      tr (header_extension, 'Y', 'H');
+    }
 }
 
 /* Compute extensions from the given c source file extension.  */
@@ -171,8 +166,9 @@
      so the extenions must be computed unconditionally from the file name
      given by this option.  */
   src_extension = xstrdup (ext);
-  header_extension = tr (ext, 'c', 'h');
-  header_extension = tr (header_extension, 'C', 'H');
+  header_extension = xstrdup (ext);
+  tr (header_extension, 'c', 'h');
+  tr (header_extension, 'C', 'H');
 }
 
 
@@ -208,10 +204,10 @@
 file_name_split (const char *file_name,
 		 const char **base, const char **tab, const char **ext)
 {
-  *base = base_name (file_name);
+  *base = last_component (file_name);
 
   /* Look for the extension, i.e., look for the last dot. */
-  *ext = strrchr (*base, '.');
+  *ext = mbsrchr (*base, '.');
   *tab = NULL;
 
   /* If there is an extension, check if there is a `.tab' part right
@@ -264,25 +260,30 @@
       if (spec_file_prefix)
 	{
 	  /* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'.  */
-	  dir_prefix = xstrndup (grammar_file, base - grammar_file);
+	  dir_prefix =
+            xstrndup (spec_file_prefix,
+                      last_component (spec_file_prefix) - spec_file_prefix);
 	  all_but_tab_ext = xstrdup (spec_file_prefix);
 	}
       else if (yacc_flag)
 	{
 	  /* If --yacc, then the output is `y.tab.c'.  */
-	  dir_prefix = "";
-	  all_but_tab_ext = "y";
+	  dir_prefix = xstrdup ("");
+	  all_but_tab_ext = xstrdup ("y");
 	}
       else
 	{
 	  /* Otherwise, ALL_BUT_TAB_EXT is computed from the input
 	     grammar: `foo/bar.yy' => `bar'.  */
-	  dir_prefix = "";
+	  dir_prefix = xstrdup ("");
 	  all_but_tab_ext =
 	    xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
 	}
 
-      all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
+      if (language->add_tab)
+        all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
+      else
+        all_but_ext = xstrdup (all_but_tab_ext);
 
       /* Compute the extensions from the grammar file name.  */
       if (ext && !yacc_flag)
@@ -297,44 +298,99 @@
 void
 compute_output_file_names (void)
 {
-  char const *name[4];
-  int i;
-  int j;
-  int names = 0;
-
   compute_file_name_parts ();
 
   /* If not yet done. */
   if (!src_extension)
-    src_extension = ".c";
+    src_extension = xstrdup (".c");
   if (!header_extension)
-    header_extension = ".h";
+    header_extension = xstrdup (".h");
 
-  name[names++] = parser_file_name =
-    spec_outfile ? spec_outfile : concat2 (all_but_ext, src_extension);
+  parser_file_name =
+    (spec_outfile
+     ? xstrdup (spec_outfile)
+     : concat2 (all_but_ext, src_extension));
 
   if (defines_flag)
     {
       if (! spec_defines_file)
 	spec_defines_file = concat2 (all_but_ext, header_extension);
-      name[names++] = spec_defines_file;
     }
 
   if (graph_flag)
     {
       if (! spec_graph_file)
-	spec_graph_file = concat2 (all_but_tab_ext, ".vcg");
-      name[names++] = spec_graph_file;
+	spec_graph_file = concat2 (all_but_tab_ext, ".dot");
+      output_file_name_check (&spec_graph_file);
+    }
+
+  if (xml_flag)
+    {
+      if (! spec_xml_file)
+	spec_xml_file = concat2 (all_but_tab_ext, ".xml");
+      output_file_name_check (&spec_xml_file);
     }
 
   if (report_flag)
     {
-      spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
-      name[names++] = spec_verbose_file;
+      if (!spec_verbose_file)
+        spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
+      output_file_name_check (&spec_verbose_file);
     }
 
-  for (j = 0; j < names; j++)
-    for (i = 0; i < j; i++)
-      if (strcmp (name[i], name[j]) == 0)
-	warn (_("conflicting outputs to file %s"), quote (name[i]));
+  free (all_but_tab_ext);
+  free (src_extension);
+  free (header_extension);
+}
+
+void
+output_file_name_check (char **file_name)
+{
+  bool conflict = false;
+  if (0 == strcmp (*file_name, grammar_file))
+    {
+      complain (_("refusing to overwrite the input file %s"),
+                quote (*file_name));
+      conflict = true;
+    }
+  else
+    {
+      int i;
+      for (i = 0; i < file_names_count; i++)
+        if (0 == strcmp (file_names[i], *file_name))
+          {
+            warn (_("conflicting outputs to file %s"),
+                  quote (*file_name));
+            conflict = true;
+          }
+    }
+  if (conflict)
+    {
+      free (*file_name);
+      *file_name = strdup ("/dev/null");
+    }
+  else
+    {
+      file_names = xnrealloc (file_names, ++file_names_count,
+                              sizeof *file_names);
+      file_names[file_names_count-1] = xstrdup (*file_name);
+    }
+}
+
+void
+output_file_names_free (void)
+{
+  free (all_but_ext);
+  free (spec_verbose_file);
+  free (spec_graph_file);
+  free (spec_xml_file);
+  free (spec_defines_file);
+  free (parser_file_name);
+  free (dir_prefix);
+  {
+    int i;
+    for (i = 0; i < file_names_count; i++)
+      free (file_names[i]);
+  }
+  free (file_names);
 }
diff --git a/src/files.h b/src/files.h
index ba9fec2..8f0bec0 100644
--- a/src/files.h
+++ b/src/files.h
@@ -1,22 +1,22 @@
 /* File names and variables for bison,
-   Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   Copyright (C) 1984, 1989, 2000-2002, 2006-2007, 2009-2012 Free
+   Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef FILES_H_
 # define FILES_H_
@@ -27,7 +27,7 @@
 extern char const *spec_outfile;
 
 /* File name for the parser (i.e., the one above, or its default.) */
-extern char const *parser_file_name;
+extern char *parser_file_name;
 
 /* Symbol prefix specified with -p, or 0 if no -p.  */
 extern const char *spec_name_prefix;
@@ -36,21 +36,19 @@
 extern char const *spec_file_prefix;
 
 /* --verbose. */
-extern char const *spec_verbose_file;
+extern char *spec_verbose_file;
 
-/* File name specified for the output VCG graph.  */
-extern char const *spec_graph_file;
+/* File name specified for the output graph.  */
+extern char *spec_graph_file;
+
+/* File name specified for the xml output.  */
+extern char *spec_xml_file;
 
 /* File name specified with --defines.  */
-extern char const *spec_defines_file;
+extern char *spec_defines_file;
 
 /* Directory prefix of output file names.  */
-extern char const *dir_prefix;
-
-
-/* If semantic parser, output a .h file that defines YYSTYPE... */
-extern struct obstack pre_prologue_obstack;
-extern struct obstack post_prologue_obstack;
+extern char *dir_prefix;
 
 /* The file name as given on the command line.
    Not named "input_file" because Flex uses this name for an argument,
@@ -60,7 +58,12 @@
 /* The current file name.  Might change with %include, or with #line.  */
 extern uniqstr current_file;
 
+/* The computed base for output file names.  */
+extern char *all_but_ext;
+
 void compute_output_file_names (void);
+void output_file_names_free (void);
+void output_file_name_check (char **file_name);
 
 FILE *xfopen (const char *name, const char *mode);
 void xfclose (FILE *ptr);
diff --git a/src/flex-scanner.h b/src/flex-scanner.h
new file mode 100644
index 0000000..c854c29
--- /dev/null
+++ b/src/flex-scanner.h
@@ -0,0 +1,91 @@
+/* Common parts between scan-code.l, scan-gram.l, and scan-skel.l.
+
+   Copyright (C) 2006, 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef FLEX_PREFIX
+# error "FLEX_PREFIX not defined"
+#endif
+
+/* Flex full version as a number.  */
+#define FLEX_VERSION                    \
+  ((YY_FLEX_MAJOR_VERSION) * 1000000    \
+   + (YY_FLEX_MINOR_VERSION) * 1000     \
+   + (YY_FLEX_SUBMINOR_VERSION))
+
+/* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
+# if FLEX_VERSION <= 2005031
+int   FLEX_PREFIX (get_lineno) (void);
+FILE *FLEX_PREFIX (get_in) (void);
+FILE *FLEX_PREFIX (get_out) (void);
+int   FLEX_PREFIX (get_leng) (void);
+char *FLEX_PREFIX (get_text) (void);
+void  FLEX_PREFIX (set_lineno) (int);
+void  FLEX_PREFIX (set_in) (FILE *);
+void  FLEX_PREFIX (set_out) (FILE *);
+int   FLEX_PREFIX (get_debug) (void);
+void  FLEX_PREFIX (set_debug) (int);
+int   FLEX_PREFIX (lex_destroy) (void);
+#endif
+
+#define last_string    FLEX_PREFIX (last_string)
+
+/* It seems to be a nice "feature" of Flex that one cannot use yytext,
+   yyleng etc. when a prefix is given, since there is no longer a
+   #define, but rather the token is actually changed in the output.
+   However, this is not true for Flex 2.5.4.  */
+#ifndef yyleng
+# define yyleng  FLEX_PREFIX (leng)
+#endif
+#ifndef yytext
+# define yytext  FLEX_PREFIX (text)
+#endif
+
+/* Non-reentrant scanners generated by Flex 2.5.9 and later (and some earlier
+   versions according to the Flex manual) leak memory if yylex_destroy is not
+   invoked.  However, yylex_destroy is not defined before Flex 2.5.9, so give
+   an implementation here that at least appears to work with Flex 2.5.4.  */
+#if FLEX_VERSION <= 2005009
+# define yylex_destroy() yy_delete_buffer (YY_CURRENT_BUFFER)
+#endif
+
+/* OBSTACK_FOR_STRING -- Used to store all the characters that we need to
+   keep (to construct ID, STRINGS etc.).  Use the following macros to
+   use it.
+
+   Use STRING_GROW to append what has just been matched, and
+   STRING_FINISH to end the string (it puts the ending 0).
+   STRING_FINISH also stores this string in LAST_STRING, which can be
+   used, and which is used by STRING_FREE to free the last string.  */
+
+#ifndef FLEX_NO_OBSTACK
+
+static struct obstack obstack_for_string;
+
+# define STRING_GROW   \
+  obstack_grow (&obstack_for_string, yytext, yyleng)
+
+# define STRING_FINISH					\
+  do {							\
+    obstack_1grow (&obstack_for_string, '\0');		\
+    last_string = obstack_finish (&obstack_for_string);	\
+  } while (0)
+
+# define STRING_FREE \
+  obstack_free (&obstack_for_string, last_string)
+
+#endif
diff --git a/src/getargs.c b/src/getargs.c
index 13b0d32..ab2a28e 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -1,29 +1,30 @@
 /* Parse command line arguments for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
+#include "output.h"
 
 #include <argmatch.h>
+#include <c-strcase.h>
+#include <configmake.h>
 #include <error.h>
 
 /* Hack to get <getopt.h> to declare getopt with a prototype.  */
@@ -39,17 +40,21 @@
 # undef HACK_FOR___GNU_LIBRARY___PROTOTYPE
 #endif
 
+#include <progname.h>
+
 #include "complain.h"
 #include "files.h"
 #include "getargs.h"
+#include "muscle-tab.h"
+#include "quote.h"
 #include "uniqstr.h"
 
-bool debug_flag;
+bool debug;
 bool defines_flag;
 bool graph_flag;
+bool xml_flag;
 bool locations_flag;
 bool no_lines_flag;
-bool no_parser_flag;
 bool token_table_flag;
 bool yacc_flag;	/* for -y */
 
@@ -57,15 +62,119 @@
 
 bool nondeterministic_parser = false;
 bool glr_parser = false;
-bool pure_parser = false;
 
+int feature_flag = feature_none;
 int report_flag = report_none;
 int trace_flag = trace_none;
+int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr
+                    | warnings_other;
 
+static struct bison_language const valid_languages[] = {
+  { "c", "c-skel.m4", ".c", ".h", true },
+  { "c++", "c++-skel.m4", ".cc", ".hh", true },
+  { "java", "java-skel.m4", ".java", ".java", false },
+  { "", "", "", "", false }
+};
+
+int skeleton_prio = default_prio;
 const char *skeleton = NULL;
+int language_prio = default_prio;
+struct bison_language const *language = &valid_languages[0];
 const char *include = NULL;
 
-extern char *program_name;
+
+/** Decode an option's set of keys.
+ *
+ *  \param option   option being decoded.
+ *  \param keys     array of valid subarguments.
+ *  \param values   array of corresponding (int) values.
+ *  \param all      the all value.
+ *  \param flags    the flags to update
+ *  \param args     comma separated list of effective subarguments to decode.
+ *                  If 0, then activate all the flags.
+ *
+ *  If VALUE != 0 then KEY sets flags and no-KEY clears them.
+ *  If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
+ *  flags from \c all.  Thus no-none = all and no-all = none.
+ */
+static void
+flags_argmatch (const char *option,
+		const char * const keys[], const int values[],
+		int all, int *flags, char *args)
+{
+  if (args)
+    {
+      args = strtok (args, ",");
+      while (args)
+	{
+	  int no = strncmp (args, "no-", 3) == 0 ? 3 : 0;
+	  int value = XARGMATCH (option, args + no, keys, values);
+	  if (value == 0)
+	    {
+	      if (no)
+		*flags |= all;
+	      else
+		*flags &= ~all;
+	    }
+	  else
+	    {
+	      if (no)
+		*flags &= ~value;
+	      else
+		*flags |= value;
+	    }
+	  args = strtok (NULL, ",");
+	}
+    }
+  else
+    *flags |= all;
+}
+
+/** Decode a set of sub arguments.
+ *
+ *  \param FlagName  the flag familly to update.
+ *  \param Args      the effective sub arguments to decode.
+ *
+ *  \arg FlagName_args   the list of keys.
+ *  \arg FlagName_types  the list of values.
+ *  \arg FlagName_all    the all value.
+ *  \arg FlagName_flag   the flag to update.
+ */
+#define FLAGS_ARGMATCH(FlagName, Args)					\
+  flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
+		  FlagName ## _all, &FlagName ## _flag, Args)
+
+
+/*----------------------.
+| --report's handling.  |
+`----------------------*/
+
+static const char * const report_args[] =
+{
+  /* In a series of synonyms, present the most meaningful first, so
+     that argmatch_valid be more readable.  */
+  "none",
+  "state", "states",
+  "itemset", "itemsets",
+  "lookahead", "lookaheads", "look-ahead",
+  "solved",
+  "all",
+  0
+};
+
+static const int report_types[] =
+{
+  report_none,
+  report_states, report_states,
+  report_states | report_itemsets, report_states | report_itemsets,
+  report_states | report_lookahead_tokens,
+  report_states | report_lookahead_tokens,
+  report_states | report_lookahead_tokens,
+  report_states | report_solved_conflicts,
+  report_all
+};
+
+ARGMATCH_VERIFY (report_args, report_types);
 
 
 /*---------------------.
@@ -76,18 +185,20 @@
 {
   /* In a series of synonyms, present the most meaningful first, so
      that argmatch_valid be more readable.  */
-  "none       - no report",
+  "none       - no traces",
   "scan       - grammar scanner traces",
   "parse      - grammar parser traces",
-  "automaton  - contruction of the automaton",
+  "automaton  - construction of the automaton",
   "bitsets    - use of bitsets",
-  "grammar    - reading, reducing of the grammar",
+  "grammar    - reading, reducing the grammar",
   "resource   - memory consumption (where available)",
   "sets       - grammar sets: firsts, nullable etc.",
+  "muscles    - m4 definitions passed to the skeleton",
   "tools      - m4 invocation",
   "m4         - m4 traces",
   "skeleton   - skeleton postprocessing",
   "time       - time consumption",
+  "ielr       - IELR conversion",
   "all        - all of the above",
   0
 };
@@ -102,84 +213,71 @@
   trace_grammar,
   trace_resource,
   trace_sets,
+  trace_muscles,
   trace_tools,
   trace_m4,
   trace_skeleton,
   trace_time,
+  trace_ielr,
   trace_all
 };
 
 ARGMATCH_VERIFY (trace_args, trace_types);
 
-static void
-trace_argmatch (char *args)
-{
-  if (args)
-    {
-      args = strtok (args, ",");
-      do
-	{
-	  int trace = XARGMATCH ("--trace", args,
-				 trace_args, trace_types);
-	  if (trace == trace_none)
-	    trace_flag = trace_none;
-	  else
-	    trace_flag |= trace;
-	}
-      while ((args = strtok (NULL, ",")));
-    }
-  else
-    trace_flag = trace_all;
-}
 
+/*------------------------.
+| --warnings's handling.  |
+`------------------------*/
 
-/*----------------------.
-| --report's handling.  |
-`----------------------*/
-
-static const char * const report_args[] =
+static const char * const warnings_args[] =
 {
   /* In a series of synonyms, present the most meaningful first, so
      that argmatch_valid be more readable.  */
+  "none            - no warnings",
+  "midrule-values  - unset or unused midrule values",
+  "yacc            - incompatibilities with POSIX Yacc",
+  "conflicts-sr    - S/R conflicts",
+  "conflicts-rr    - R/R conflicts",
+  "other           - all other warnings",
+  "all             - all of the above",
+  "error           - warnings are errors",
+  0
+};
+
+static const int warnings_types[] =
+{
+  warnings_none,
+  warnings_midrule_values,
+  warnings_yacc,
+  warnings_conflicts_sr,
+  warnings_conflicts_rr,
+  warnings_other,
+  warnings_all,
+  warnings_error
+};
+
+ARGMATCH_VERIFY (warnings_args, warnings_types);
+
+/*-----------------------.
+| --feature's handling.  |
+`-----------------------*/
+
+static const char * const feature_args[] =
+{
   "none",
-  "state", "states",
-  "itemset", "itemsets",
-  "look-ahead", "lookahead", "lookaheads",
-  "solved",
+  "caret", "diagnostics-show-caret",
   "all",
   0
 };
 
-static const int report_types[] =
+static const int feature_types[] =
 {
-  report_none,
-  report_states, report_states,
-  report_states | report_itemsets, report_states | report_itemsets,
-  report_states | report_look_ahead_tokens,
-  report_states | report_look_ahead_tokens,
-  report_states | report_look_ahead_tokens,
-  report_states | report_solved_conflicts,
-  report_all
+  feature_none,
+  feature_caret, feature_caret,
+  feature_all
 };
 
-ARGMATCH_VERIFY (report_args, report_types);
-
-static void
-report_argmatch (char *args)
-{
-  args = strtok (args, ",");
-  do
-    {
-      int report = XARGMATCH ("--report", args,
-			      report_args, report_types);
-      if (report == report_none)
-	report_flag = report_none;
-      else
-	report_flag |= report;
-    }
-  while ((args = strtok (NULL, ",")));
-}
-
+ARGMATCH_VERIFY (feature_args, feature_types);
 
 /*-------------------------------------------.
 | Display the help message and exit STATUS.  |
@@ -195,50 +293,83 @@
 	     program_name);
   else
     {
-      /* Some efforts were made to ease the translators' task, please
-	 continue.  */
-      fputs (_("\
-GNU bison generates parsers for LALR(1) grammars.\n"), stdout);
-      putc ('\n', stdout);
+      /* For ../build-aux/cross-options.pl to work, use the format:
+		^  -S, --long[=ARGS] (whitespace)
+	 A --long option is required.
+	 Otherwise, add exceptions to ../build-aux/cross-options.pl.  */
 
-      fprintf (stdout, _("\
-Usage: %s [OPTION]... FILE\n"), program_name);
-      putc ('\n', stdout);
+      printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
+      fputs (_("\
+Generate a deterministic LR or generalized LR (GLR) parser employing\n\
+LALR(1), IELR(1), or canonical LR(1) parser tables.  IELR(1) and\n\
+canonical LR(1) support is experimental.\n\
+\n\
+"), stdout);
 
       fputs (_("\
-If a long option shows an argument as mandatory, then it is mandatory\n\
-for the equivalent short option also.  Similarly for optional arguments.\n"),
-	     stdout);
-      putc ('\n', stdout);
+Mandatory arguments to long options are mandatory for short options too.\n\
+"), stdout);
+      fputs (_("\
+The same is true for optional arguments.\n\
+"), stdout);
 
       fputs (_("\
+\n\
 Operation modes:\n\
   -h, --help                 display this help and exit\n\
   -V, --version              output version information and exit\n\
       --print-localedir      output directory containing locale-dependent data\n\
-  -y, --yacc                 emulate POSIX yacc\n"), stdout);
-      putc ('\n', stdout);
+      --print-datadir        output directory containing skeletons and XSLT\n\
+  -y, --yacc                 emulate POSIX Yacc\n\
+  -W, --warnings[=CATEGORY]  report the warnings falling in CATEGORY\n\
+  -f, --feature[=FEATURE]    activate miscellaneous features\n\
+\n\
+"), stdout);
 
       fputs (_("\
 Parser:\n\
-  -S, --skeleton=FILE        specify the skeleton to use\n\
-  -t, --debug                instrument the parser for debugging\n\
-      --locations            enable locations computation\n\
-  -p, --name-prefix=PREFIX   prepend PREFIX to the external symbols\n\
-  -l, --no-lines             don't generate `#line' directives\n\
-  -n, --no-parser            generate the tables only\n\
-  -k, --token-table          include a table of token names\n\
+  -L, --language=LANGUAGE          specify the output programming language\n\
+  -S, --skeleton=FILE              specify the skeleton to use\n\
+  -t, --debug                      instrument the parser for debugging\n\
+      --locations                  enable location support\n\
+  -D, --define=NAME[=VALUE]        similar to '%define NAME \"VALUE\"'\n\
+  -F, --force-define=NAME[=VALUE]  override '%define NAME \"VALUE\"'\n\
+  -p, --name-prefix=PREFIX         prepend PREFIX to the external symbols\n\
+                                   deprecated by '-Dapi.prefix=PREFIX'\n\
+  -l, --no-lines                   don't generate '#line' directives\n\
+  -k, --token-table                include a table of token names\n\
+"), stdout);
+      putc ('\n', stdout);
+
+      /* Keep -d and --defines separate so that ../build-aux/cross-options.pl
+       * won't assume that -d also takes an argument.  */
+      fputs (_("\
+Output:\n\
+      --defines[=FILE]       also produce a header file\n\
+  -d                         likewise but cannot specify FILE (for POSIX Yacc)\n\
+  -r, --report=THINGS        also produce details on the automaton\n\
+      --report-file=FILE     write report to FILE\n\
+  -v, --verbose              same as `--report=state'\n\
+  -b, --file-prefix=PREFIX   specify a PREFIX for output files\n\
+  -o, --output=FILE          leave output to FILE\n\
+  -g, --graph[=FILE]         also output a graph of the automaton\n\
+  -x, --xml[=FILE]           also output an XML report of the automaton\n\
+                             (the XML schema is experimental)\n\
 "), stdout);
       putc ('\n', stdout);
 
       fputs (_("\
-Output:\n\
-  -d, --defines              also produce a header file\n\
-  -r, --report=THINGS        also produce details on the automaton\n\
-  -v, --verbose              same as `--report=state'\n\
-  -b, --file-prefix=PREFIX   specify a PREFIX for output files\n\
-  -o, --output=FILE          leave output to FILE\n\
-  -g, --graph                also produce a VCG description of the automaton\n\
+Warning categories include:\n\
+  `midrule-values'  unset or unused midrule values\n\
+  `yacc'            incompatibilities with POSIX Yacc\n\
+  `conflicts-sr'    S/R conflicts (enabled by default)\n\
+  `conflicts-rr'    R/R conflicts (enabled by default)\n\
+  `deprecated'      obsolete constructs\n\
+  `other'           all other warnings (enabled by default)\n\
+  `all'             all the warnings\n\
+  `no-CATEGORY'     turn off warnings in CATEGORY\n\
+  `none'            turn off all the warnings\n\
+  `error'           treat warnings as errors\n\
 "), stdout);
       putc ('\n', stdout);
 
@@ -246,7 +377,7 @@
 THINGS is a list of comma separated words that can include:\n\
   `state'        describe the states\n\
   `itemset'      complete the core item sets with their closure\n\
-  `look-ahead'   explicitly associate look-ahead tokens to items\n\
+  `lookahead'    explicitly associate lookahead tokens to items\n\
   `solved'       describe shift/reduce conflicts solving\n\
   `all'          include all the above information\n\
   `none'         disable the report\n\
@@ -254,7 +385,31 @@
       putc ('\n', stdout);
 
       fputs (_("\
-Report bugs to <bug-bison@gnu.org>.\n"), stdout);
+FEATURE is a list of comma separated words that can include:\n\
+  `caret'        show errors with carets\n\
+  `all'          all of the above\n\
+  `none'         disable all of the above\n\
+  "), stdout);
+
+      putc ('\n', stdout);
+      printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+      printf (_("%s home page: <%s>.\n"), PACKAGE_NAME, PACKAGE_URL);
+      fputs (_("General help using GNU software: "
+               "<http://www.gnu.org/gethelp/>.\n"),
+             stdout);
+      /* Don't output this redundant message for English locales.
+         Note we still output for 'C' so that it gets included in the
+         man page.  */
+      const char *lc_messages = setlocale (LC_MESSAGES, NULL);
+      if (lc_messages && strcmp (lc_messages, "en_"))
+        /* TRANSLATORS: Replace LANG_CODE in this URL with your language
+           code <http://translationproject.org/team/LANG_CODE.html> to
+           form one of the URLs at http://translationproject.org/team/.
+           Otherwise, replace the entire URL with your translation team's
+           email address.  */
+        fputs (_("Report translation bugs to "
+                 "<http://translationproject.org/team/>.\n"), stdout);
+      fputs (_("For complete documentation, run: info bison.\n"), stdout);
     }
 
   exit (status);
@@ -276,7 +431,8 @@
   putc ('\n', stdout);
 
   fprintf (stdout,
-	   _("Copyright (C) %d Free Software Foundation, Inc.\n"), 2006);
+	   _("Copyright (C) %d Free Software Foundation, Inc.\n"),
+	   PACKAGE_COPYRIGHT_YEAR);
 
   fputs (_("\
 This is free software; see the source for copying conditions.  There is NO\n\
@@ -286,26 +442,96 @@
 }
 
 
+/*-------------------------------------.
+| --skeleton and --language handling.  |
+`--------------------------------------*/
+
+void
+skeleton_arg (char const *arg, int prio, location loc)
+{
+  if (prio < skeleton_prio)
+    {
+      skeleton_prio = prio;
+      skeleton = arg;
+    }
+  else if (prio == skeleton_prio)
+    complain_at (loc, _("multiple skeleton declarations are invalid"));
+}
+
+void
+language_argmatch (char const *arg, int prio, location loc)
+{
+  char const *msg;
+
+  if (prio < language_prio)
+    {
+      int i;
+      for (i = 0; valid_languages[i].language[0]; i++)
+        if (c_strcasecmp (arg, valid_languages[i].language) == 0)
+          {
+            language_prio = prio;
+            language = &valid_languages[i];
+            return;
+          }
+      msg = _("%s: invalid language");
+    }
+  else if (language_prio == prio)
+    msg = _("multiple language declarations are invalid");
+  else
+    return;
+
+  complain_at (loc, msg, quotearg_colon (arg));
+}
+
 /*----------------------.
 | Process the options.  |
 `----------------------*/
 
-/* Shorts options.  */
-static char const short_options[] = "yvegdhr:ltknVo:b:p:S:T::";
+/* Shorts options.
+   Should be computed from long_options.  */
+static char const short_options[] =
+  "D:"
+  "F:"
+  "L:"
+  "S:"
+  "T::"
+  "V"
+  "W::"
+  "b:"
+  "d"
+  "f::"
+  "e"
+  "g::"
+  "h"
+  "k"
+  "l"
+  "n"
+  "o:"
+  "p:"
+  "r:"
+  "t"
+  "v"
+  "x::"
+  "y"
+  ;
 
 /* Values for long options that do not have single-letter equivalents.  */
 enum
 {
   LOCATIONS_OPTION = CHAR_MAX + 1,
-  PRINT_LOCALEDIR_OPTION
+  PRINT_LOCALEDIR_OPTION,
+  PRINT_DATADIR_OPTION,
+  REPORT_FILE_OPTION
 };
 
 static struct option const long_options[] =
 {
   /* Operation modes. */
-  { "help",            no_argument,	0,   'h' },
-  { "version",         no_argument,	0,   'V' },
-  { "print-localedir", no_argument,	0,   PRINT_LOCALEDIR_OPTION },
+  { "help",            no_argument,	  0,   'h' },
+  { "version",         no_argument,	  0,   'V' },
+  { "print-localedir", no_argument,	  0,   PRINT_LOCALEDIR_OPTION },
+  { "print-datadir",   no_argument,	  0,   PRINT_DATADIR_OPTION   },
+  { "warnings",        optional_argument, 0,   'W' },
 
   /* Parser. */
   { "name-prefix",   required_argument,	  0,   'p' },
@@ -316,7 +542,9 @@
   { "output",	   required_argument,	0,   'o' },
   { "output-file", required_argument,	0,   'o' },
   { "graph",	   optional_argument,	0,   'g' },
+  { "xml",         optional_argument,   0,   'x' },
   { "report",	   required_argument,   0,   'r' },
+  { "report-file", required_argument,   0,   REPORT_FILE_OPTION },
   { "verbose",	   no_argument,	        0,   'v' },
 
   /* Hidden. */
@@ -324,6 +552,7 @@
 
   /* Output.  */
   { "defines",     optional_argument,   0,   'd' },
+  { "feature",     optional_argument,   0,   'f' },
 
   /* Operation modes.  */
   { "fixed-output-files", no_argument,  0,   'y' },
@@ -331,11 +560,13 @@
 
   /* Parser.  */
   { "debug",	      no_argument,               0,   't' },
+  { "define",	      required_argument,         0,   'D' },
+  { "force-define",   required_argument,         0,   'F' },
   { "locations",      no_argument,		 0, LOCATIONS_OPTION },
   { "no-lines",       no_argument,               0,   'l' },
-  { "no-parser",      no_argument,               0,   'n' },
   { "raw",            no_argument,               0,     0 },
   { "skeleton",       required_argument,         0,   'S' },
+  { "language",       required_argument,         0,   'L' },
   { "token-table",    no_argument,               0,   'k' },
 
   {0, 0, 0, 0}
@@ -349,6 +580,19 @@
 # define AS_FILE_NAME(File) (File)
 #endif
 
+/* Build a location for the current command line argument. */
+static
+location
+command_line_location (void)
+{
+  location res;
+  /* "<command line>" is used in GCC's messages about -D. */
+  boundary_set (&res.start, uniqstr_new ("<command line>"), optind - 1, -1);
+  res.end = res.start;
+  return res;
+}
+
+
 void
 getargs (int argc, char *argv[])
 {
@@ -358,89 +602,139 @@
 	 != -1)
     switch (c)
       {
+        /* ASCII Sorting for short options (i.e., upper case then
+           lower case), and then long-only options.  */
+
       case 0:
 	/* Certain long options cause getopt_long to return 0.  */
 	break;
 
-      case 'y':
-	yacc_flag = true;
-	break;
-
-      case 'h':
-	usage (EXIT_SUCCESS);
-
-      case 'V':
-	version ();
-	exit (EXIT_SUCCESS);
-
-      case PRINT_LOCALEDIR_OPTION:
-	printf ("%s\n", LOCALEDIR);
-	exit (EXIT_SUCCESS);
-
-      case 'g':
-	/* Here, the -g and --graph=FILE options are differentiated.  */
-	graph_flag = true;
-	if (optarg)
-	  spec_graph_file = AS_FILE_NAME (optarg);
-	break;
-
-      case 'v':
-	report_flag |= report_states;
-	break;
-
-      case 'S':
-	skeleton = AS_FILE_NAME (optarg);
+      case 'D': /* -DNAME[=VALUE]. */
+      case 'F': /* -FNAME[=VALUE]. */
+        {
+          char* name = optarg;
+          char* value = mbschr (optarg, '=');
+          if (value)
+            *value++ = 0;
+          muscle_percent_define_insert (name, command_line_location (),
+                                        value ? value : "",
+                                        c == 'D' ? MUSCLE_PERCENT_DEFINE_D
+                                                 : MUSCLE_PERCENT_DEFINE_F);
+        }
 	break;
 
       case 'I':
 	include = AS_FILE_NAME (optarg);
 	break;
 
+      case 'L':
+	language_argmatch (optarg, command_line_prio,
+			   command_line_location ());
+	break;
+
+      case 'S':
+	skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
+		      command_line_location ());
+	break;
+
+      case 'T':
+	FLAGS_ARGMATCH (trace, optarg);
+	break;
+
+      case 'V':
+	version ();
+	exit (EXIT_SUCCESS);
+
+      case 'f':
+        FLAGS_ARGMATCH (feature, optarg);
+        break;
+
+      case 'W':
+	FLAGS_ARGMATCH (warnings, optarg);
+	break;
+
+      case 'b':
+	spec_file_prefix = AS_FILE_NAME (optarg);
+	break;
+
       case 'd':
-	/* Here, the -d and --defines options are differentiated.  */
-	defines_flag = true;
+        /* Here, the -d and --defines options are differentiated.  */
+        defines_flag = true;
+        if (optarg)
+          {
+            free (spec_defines_file);
+            spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
+          }
+        break;
+
+      case 'g':
+	graph_flag = true;
 	if (optarg)
-	  spec_defines_file = AS_FILE_NAME (optarg);
+          {
+            free (spec_graph_file);
+            spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
+          }
+	break;
+
+      case 'h':
+	usage (EXIT_SUCCESS);
+
+      case 'k':
+	token_table_flag = true;
 	break;
 
       case 'l':
 	no_lines_flag = true;
 	break;
 
-      case LOCATIONS_OPTION:
-	locations_flag = true;
-	break;
-
-      case 'k':
-	token_table_flag = true;
-	break;
-
-      case 'n':
-	no_parser_flag = true;
-	break;
-
-      case 't':
-	debug_flag = true;
-	break;
-
       case 'o':
 	spec_outfile = AS_FILE_NAME (optarg);
 	break;
 
-      case 'b':
-	spec_file_prefix = AS_FILE_NAME (optarg);
-	break;
-
       case 'p':
 	spec_name_prefix = optarg;
 	break;
 
       case 'r':
-	report_argmatch (optarg);
+	FLAGS_ARGMATCH (report, optarg);
 	break;
 
-      case 'T':
-	trace_argmatch (optarg);
+      case 't':
+	debug = true;
+	break;
+
+      case 'v':
+	report_flag |= report_states;
+	break;
+
+      case 'x':
+	xml_flag = true;
+	if (optarg)
+          {
+            free (spec_xml_file);
+            spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
+          }
+	break;
+
+      case 'y':
+	yacc_flag = true;
+	break;
+
+      case LOCATIONS_OPTION:
+	locations_flag = true;
+	break;
+
+      case PRINT_LOCALEDIR_OPTION:
+	printf ("%s\n", LOCALEDIR);
+	exit (EXIT_SUCCESS);
+
+      case PRINT_DATADIR_OPTION:
+	printf ("%s\n", compute_pkgdatadir ());
+	exit (EXIT_SUCCESS);
+
+      case REPORT_FILE_OPTION:
+        free (spec_verbose_file);
+	spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
 	break;
 
       default:
@@ -450,11 +744,20 @@
   if (argc - optind != 1)
     {
       if (argc - optind < 1)
-	error (0, 0, _("missing operand after `%s'"), argv[argc - 1]);
+        error (0, 0, _("%s: missing operand"), quotearg_colon (argv[argc - 1]));
       else
-	error (0, 0, _("extra operand `%s'"), argv[optind + 1]);
+        error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
       usage (EXIT_FAILURE);
     }
 
   current_file = grammar_file = uniqstr_new (argv[optind]);
+  MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
+}
+
+void
+tr (char *s, char from, char to)
+{
+  for (; *s; s++)
+    if (*s == from)
+      *s = to;
 }
diff --git a/src/getargs.h b/src/getargs.h
index 816eb95..b2126fc 100644
--- a/src/getargs.h
+++ b/src/getargs.h
@@ -1,41 +1,45 @@
 /* Parse command line arguments for bison.
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+
+   Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef GETARGS_H_
 # define GETARGS_H_
 
+#include "location.h"
+
+enum { command_line_prio, grammar_prio, default_prio };
+
 /* flags set by % directives */
 
 /* for -S */
 extern char const *skeleton;
+extern int skeleton_prio;
 
 /* for -I */
 extern char const *include;
 
-extern bool debug_flag;			/* for -t */
+extern bool debug;			/* for -t */
 extern bool defines_flag;		/* for -d */
 extern bool graph_flag;			/* for -g */
+extern bool xml_flag;			/* for -x */
 extern bool locations_flag;
 extern bool no_lines_flag;		/* for -l */
-extern bool no_parser_flag;		/* for -n */
 extern bool token_table_flag;		/* for -k */
 extern bool yacc_flag;			/* for -y */
 
@@ -48,48 +52,109 @@
 
 extern bool glr_parser;
 
-/* PURE_PARSER is true if should generate a parser that is all pure
-   and reentrant.  */
-
-extern bool pure_parser;
-
 /* NONDETERMINISTIC_PARSER is true iff conflicts are accepted.  This
    is used by the GLR parser, and might be used in BackTracking
    parsers too.  */
 
 extern bool nondeterministic_parser;
 
-/* --trace.  */
-enum trace
-  {
-    trace_none      = 0,
-    trace_scan      = 1 << 0,
-    trace_parse     = 1 << 1,
-    trace_resource  = 1 << 2,
-    trace_sets      = 1 << 3,
-    trace_bitsets   = 1 << 4,
-    trace_tools     = 1 << 5,
-    trace_automaton = 1 << 6,
-    trace_grammar   = 1 << 7,
-    trace_time      = 1 << 8,
-    trace_skeleton  = 1 << 9,
-    trace_m4        = 1 << 10,
-    trace_all       = ~0
-  };
-extern int trace_flag;
 
-/* --report.  */
+/* --language.  */
+struct bison_language
+{
+  char language[sizeof "Java"];
+  char skeleton[sizeof "java-skel.m4"];
+  char src_extension[sizeof ".java"];
+  char header_extension[sizeof ".java"];
+  bool add_tab;
+};
+
+extern int language_prio;
+extern struct bison_language const *language;
+
+/*-----------.
+| --report.  |
+`-----------*/
+
 enum report
   {
     report_none             = 0,
     report_states           = 1 << 0,
     report_itemsets         = 1 << 1,
-    report_look_ahead_tokens= 1 << 2,
+    report_lookahead_tokens = 1 << 2,
     report_solved_conflicts = 1 << 3,
     report_all              = ~0
   };
+/** What appears in the *.output file.  */
 extern int report_flag;
 
+/*----------.
+| --trace.  |
+`----------*/
+enum trace
+  {
+    trace_none      = 0,       /**< No traces. */
+    trace_scan      = 1 << 0,  /**< Grammar scanner traces. */
+    trace_parse     = 1 << 1,  /**< Grammar parser traces. */
+    trace_resource  = 1 << 2,  /**< Memory allocation. */
+    trace_sets      = 1 << 3,  /**< Grammar sets: firsts, nullable etc. */
+    trace_bitsets   = 1 << 4,  /**< Use of bitsets. */
+    trace_tools     = 1 << 5,  /**< m4 invocation. */
+    trace_automaton = 1 << 6,  /**< Construction of the automaton. */
+    trace_grammar   = 1 << 7,  /**< Reading, reducing the grammar. */
+    trace_time      = 1 << 8,  /**< Time consumption. */
+    trace_skeleton  = 1 << 9,  /**< Skeleton postprocessing. */
+    trace_m4        = 1 << 10, /**< M4 traces. */
+    trace_muscles   = 1 << 11, /**< M4 definitions of the muscles. */
+    trace_ielr      = 1 << 12, /**< IELR conversion. */
+    trace_all       = ~0       /**< All of the above.  */
+  };
+/** What debug items bison displays during its run.  */
+extern int trace_flag;
+
+/*-------------.
+| --warnings.  |
+`-------------*/
+
+enum warnings
+  {
+    warnings_none             = 0,      /**< Issue no warnings.  */
+    warnings_error            = 1 << 0, /**< Warnings are treated as errors.  */
+    warnings_midrule_values   = 1 << 1, /**< Unset or unused midrule values.  */
+    warnings_yacc             = 1 << 2, /**< POSIXME.  */
+    warnings_conflicts_sr     = 1 << 3, /**< S/R conflicts.  */
+    warnings_conflicts_rr     = 1 << 4, /**< R/R conflicts.  */
+    warnings_other            = 1 << 5, /**< All other warnings.  */
+    warnings_all              = ~warnings_error /**< All above warnings.  */
+  };
+/** What warnings are issued.  */
+extern int warnings_flag;
+
+/*-------------.
+| --features.  |
+`-------------*/
+
+enum feature
+  {
+    feature_none  = 0,         /**< No additional feature.  */
+    feature_caret = 1 << 0,    /**< Enhance the output of errors with carets.  */
+    feature_all   = ~0         /**< All above features.  */
+  };
+/** What additional features to use.  */
+extern int feature_flag;
+
+/** Process the command line arguments.
+ *
+ *  \param argc   size of \a argv
+ *  \param argv   list of arguments.
+ */
 void getargs (int argc, char *argv[]);
 
+/* Used by parse-gram.y.  */
+void language_argmatch (char const *arg, int prio, location loc);
+void skeleton_arg (const char *arg, int prio, location loc);
+
+/** In the string \c s, replace all characters \c from by \c to.  */
+void tr (char *s, char from, char to);
+
 #endif /* !GETARGS_H_ */
diff --git a/src/gram.c b/src/gram.c
index 28666b0..5730e59 100644
--- a/src/gram.c
+++ b/src/gram.c
@@ -1,31 +1,30 @@
 /* Allocate input grammar variables for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 2001, 2002, 2003, 2005, 2006 Free
-   Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
-#include <quotearg.h>
-
+#include "complain.h"
+#include "getargs.h"
 #include "gram.h"
+#include "print-xml.h"
 #include "reader.h"
 #include "reduce.h"
 #include "symtab.h"
@@ -47,46 +46,24 @@
 
 int max_user_token_number = 256;
 
-/*--------------------------------------------------------------.
-| Return true IFF the rule has a `number' smaller than NRULES.  |
-`--------------------------------------------------------------*/
-
 bool
-rule_useful_p (rule *r)
+rule_useful_in_grammar_p (rule *r)
 {
   return r->number < nrules;
 }
 
-
-/*-------------------------------------------------------------.
-| Return true IFF the rule has a `number' higher than NRULES.  |
-`-------------------------------------------------------------*/
-
 bool
-rule_useless_p (rule *r)
+rule_useless_in_grammar_p (rule *r)
 {
-  return !rule_useful_p (r);
+  return !rule_useful_in_grammar_p (r);
 }
 
-
-/*--------------------------------------------------------------------.
-| Return true IFF the rule is not flagged as useful *and* is useful.  |
-| In other words, it was discarded because of conflicts.              |
-`--------------------------------------------------------------------*/
-
 bool
-rule_never_reduced_p (rule *r)
+rule_useless_in_parser_p (rule *r)
 {
-  return !r->useful && rule_useful_p (r);
+  return !r->useful && rule_useful_in_grammar_p (r);
 }
 
-
-/*----------------------------------------------------------------.
-| Print this RULE's number and lhs on OUT.  If a PREVIOUS_LHS was |
-| already displayed (by a previous call for another rule), avoid  |
-| useless repetitions.                                            |
-`----------------------------------------------------------------*/
-
 void
 rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out)
 {
@@ -104,10 +81,11 @@
     }
 }
 
-
-/*--------------------------------------.
-| Return the number of symbols in RHS.  |
-`--------------------------------------*/
+void
+rule_lhs_print_xml (rule *r, FILE *out, int level)
+{
+  xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
+}
 
 int
 rule_rhs_length (rule *r)
@@ -119,11 +97,6 @@
   return res;
 }
 
-
-/*-------------------------------.
-| Print this rule's RHS on OUT.  |
-`-------------------------------*/
-
 void
 rule_rhs_print (rule *r, FILE *out)
 {
@@ -140,10 +113,25 @@
     }
 }
 
-
-/*-------------------------.
-| Print this rule on OUT.  |
-`-------------------------*/
+static void
+rule_rhs_print_xml (rule *r, FILE *out, int level)
+{
+  if (*r->rhs >= 0)
+    {
+      item_number *rp;
+      xml_puts (out, level, "<rhs>");
+      for (rp = r->rhs; *rp >= 0; rp++)
+	xml_printf (out, level + 1, "<symbol>%s</symbol>",
+		    xml_escape (symbols[*rp]->tag));
+      xml_puts (out, level, "</rhs>");
+    }
+  else
+    {
+      xml_puts (out, level, "<rhs>");
+      xml_puts (out, level + 1, "<empty/>");
+      xml_puts (out, level, "</rhs>");
+    }
+}
 
 void
 rule_print (rule *r, FILE *out)
@@ -152,11 +140,6 @@
   rule_rhs_print (r, out);
 }
 
-
-/*------------------------.
-| Dump RITEM for traces.  |
-`------------------------*/
-
 void
 ritem_print (FILE *out)
 {
@@ -170,11 +153,6 @@
   fputs ("\n\n", out);
 }
 
-
-/*------------------------------------------.
-| Return the size of the longest rule RHS.  |
-`------------------------------------------*/
-
 size_t
 ritem_longest_rhs (void)
 {
@@ -191,11 +169,6 @@
   return max;
 }
 
-
-/*-----------------------------------------------------------------.
-| Print the grammar's rules that match FILTER on OUT under TITLE.  |
-`-----------------------------------------------------------------*/
-
 void
 grammar_rules_partial_print (FILE *out, const char *title,
 			     rule_filter filter)
@@ -222,21 +195,48 @@
     fputs ("\n\n", out);
 }
 
-
-/*------------------------------------------.
-| Print the grammar's useful rules on OUT.  |
-`------------------------------------------*/
-
 void
 grammar_rules_print (FILE *out)
 {
-  grammar_rules_partial_print (out, _("Grammar"), rule_useful_p);
+  grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
 }
 
+void
+grammar_rules_print_xml (FILE *out, int level)
+{
+  rule_number r;
+  bool first = true;
 
-/*-------------------.
-| Dump the grammar.  |
-`-------------------*/
+  for (r = 0; r < nrules + nuseless_productions; r++)
+    {
+      if (first)
+	xml_puts (out, level + 1, "<rules>");
+      first = false;
+      {
+        char const *usefulness;
+        if (rule_useless_in_grammar_p (&rules[r]))
+          usefulness = "useless-in-grammar";
+        else if (rule_useless_in_parser_p (&rules[r]))
+          usefulness = "useless-in-parser";
+        else
+          usefulness = "useful";
+        xml_indent (out, level + 2);
+        fprintf (out, "<rule number=\"%d\" usefulness=\"%s\"",
+                 rules[r].number, usefulness);
+        if (rules[r].precsym)
+          fprintf (out, " percent_prec=\"%s\"",
+                   xml_escape (rules[r].precsym->tag));
+        fputs (">\n", out);
+      }
+      rule_lhs_print_xml (&rules[r], out, level + 3);
+      rule_rhs_print_xml (&rules[r], out, level + 3);
+      xml_puts (out, level + 2, "</rule>");
+    }
+  if (!first)
+    xml_puts (out, level + 1, "</rules>");
+  else
+   xml_puts (out, level + 1, "<rules/>");
+}
 
 void
 grammar_dump (FILE *out, const char *title)
@@ -301,24 +301,24 @@
   fprintf (out, "\n\n");
 }
 
-
-/*------------------------------------------------------------------.
-| Report on STDERR the rules that are not flagged USEFUL, using the |
-| MESSAGE (which can be `useless rule' when invoked after grammar   |
-| reduction, or `never reduced' after conflicts were taken into     |
-| account).                                                         |
-`------------------------------------------------------------------*/
-
 void
-grammar_rules_never_reduced_report (const char *message)
+grammar_rules_useless_report (const char *message)
 {
   rule_number r;
   for (r = 0; r < nrules ; ++r)
     if (!rules[r].useful)
       {
-	location_print (stderr, rules[r].location);
-	fprintf (stderr, ": %s: %s: ", _("warning"), message);
-	rule_print (&rules[r], stderr);
+        if (feature_flag & feature_caret)
+          warn_at (rules[r].location, "%s", message);
+        else
+          {
+            warn_at (rules[r].location, "%s: ", message);
+            if (warnings_flag & warnings_other)
+              {
+                rule_print (&rules[r], stderr);
+                fflush (stderr);
+              }
+          }
       }
 }
 
diff --git a/src/gram.h b/src/gram.h
index b8f316a..3f75dd8 100644
--- a/src/gram.h
+++ b/src/gram.h
@@ -1,24 +1,22 @@
 /* Data definitions for internal representation of Bison's input.
 
-   Copyright (C) 1984, 1986, 1989, 1992, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 2001-2007, 2009-2012 Free
+   Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef GRAM_H_
 # define GRAM_H_
@@ -115,6 +113,7 @@
 extern int nvars;
 
 typedef int item_number;
+#define ITEM_NUMBER_MAX INT_MAX
 extern item_number *ritem;
 extern unsigned int nritems;
 
@@ -146,6 +145,7 @@
 
 /* Rule numbers.  */
 typedef int rule_number;
+#define RULE_NUMBER_MAX INT_MAX
 extern rule_number nrules;
 
 static inline item_number
@@ -204,20 +204,23 @@
 /* A function that selects a rule.  */
 typedef bool (*rule_filter) (rule *);
 
-/* Return true IFF the rule has a `number' smaller than NRULES.  */
-bool rule_useful_p (rule *r);
+/* Return true IFF the rule has a `number' smaller than NRULES.  That is, it is
+   useful in the grammar.  */
+bool rule_useful_in_grammar_p (rule *r);
 
-/* Return true IFF the rule has a `number' higher than NRULES.  */
-bool rule_useless_p (rule *r);
+/* Return true IFF the rule has a `number' higher than NRULES.  That is, it is
+   useless in the grammar.  */
+bool rule_useless_in_grammar_p (rule *r);
 
-/* Return true IFF the rule is not flagged as useful *and* is useful.
-   In other words, it was discarded because of conflicts.  */
-bool rule_never_reduced_p (rule *r);
+/* Return true IFF the rule is not flagged as useful but is useful in the
+   grammar.  In other words, it was discarded because of conflicts.  */
+bool rule_useless_in_parser_p (rule *r);
 
 /* Print this rule's number and lhs on OUT.  If a PREVIOUS_LHS was
    already displayed (by a previous call for another rule), avoid
    useless repetitions.  */
 void rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out);
+void rule_lhs_print_xml (rule *r, FILE *out, int level);
 
 /* Return the length of the RHS.  */
 int rule_rhs_length (rule *r);
@@ -248,22 +251,23 @@
 /* Return the size of the longest rule RHS.  */
 size_t ritem_longest_rhs (void);
 
-/* Print the grammar's rules numbers from BEGIN (inclusive) to END
-   (exclusive) on OUT under TITLE.  */
+/* Print the grammar's rules that match FILTER on OUT under TITLE.  */
 void grammar_rules_partial_print (FILE *out, const char *title,
 				  rule_filter filter);
 
-/* Print the grammar's rules on OUT.  */
+/* Print the grammar's useful rules on OUT.  */
 void grammar_rules_print (FILE *out);
+/* Print all of the grammar's rules with a "usefulness" attribute.  */
+void grammar_rules_print_xml (FILE *out, int level);
 
 /* Dump the grammar. */
 void grammar_dump (FILE *out, const char *title);
 
 /* Report on STDERR the rules that are not flagged USEFUL, using the
-   MESSAGE (which can be `useless rule' when invoked after grammar
-   reduction, or `never reduced' after conflicts were taken into
-   account).  */
-void grammar_rules_never_reduced_report (const char *message);
+   MESSAGE (which can be `rule useless in grammar' when invoked after grammar
+   reduction, or `rule useless in parser due to conflicts' after conflicts
+   were taken into account).  */
+void grammar_rules_useless_report (const char *message);
 
 /* Free the packed grammar. */
 void grammar_free (void);
diff --git a/src/graphviz.c b/src/graphviz.c
new file mode 100644
index 0000000..9da5f6e
--- /dev/null
+++ b/src/graphviz.c
@@ -0,0 +1,218 @@
+/* Output Graphviz specification of a state machine generated by Bison.
+
+   Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert and Satya Kiran Popuri.  */
+
+#include <config.h>
+#include "system.h"
+
+#include <quotearg.h>
+
+#include "files.h"
+#include "gram.h"
+#include "graphviz.h"
+#include "tables.h"
+
+/* Return an unambiguous printable representation for NAME, suitable
+   for C strings.  Use slot 2 since the user may use slots 0 and 1.  */
+
+static char *
+quote (char const *name)
+{
+  return quotearg_n_style (2, c_quoting_style, name);
+}
+
+void
+start_graph (FILE *fout)
+{
+  fprintf (fout,
+           _("// Generated by %s.\n"
+             "// Report bugs to <%s>.\n"
+             "// Home page: <%s>.\n"
+             "\n"),
+           PACKAGE_STRING,
+           PACKAGE_BUGREPORT,
+           PACKAGE_URL);
+  fprintf (fout,
+           "digraph %s\n"
+           "{\n",
+           quote (grammar_file));
+  fprintf (fout,
+           "  node [fontname = courier, shape = box, colorscheme = paired6]\n"
+           "  edge [fontname = courier]\n"
+           "\n");
+}
+
+void
+output_node (int id, char const *label, FILE *fout)
+{
+  fprintf (fout, "  %d [label=\"%s\"]\n", id, label);
+}
+
+void
+output_edge (int source, int destination, char const *label,
+             char const *style, FILE *fout)
+{
+  fprintf (fout, "  %d -> %d [style=%s", source, destination, style);
+  if (label)
+    fprintf (fout, " label=%s", quote (label));
+  fputs ("]\n", fout);
+}
+
+char const *
+escape (char const *name)
+{
+  char *q = quote (name);
+  q[strlen (q) - 1] = '\0';
+  return q + 1;
+}
+
+static void
+no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
+{
+  int n;
+  *no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
+  bitset_zero (*no_reduce_set);
+  FOR_EACH_SHIFT (s->transitions, n)
+    bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
+  for (n = 0; n < s->errs->num; ++n)
+    if (s->errs->symbols[n])
+      bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
+}
+
+static void
+conclude_red (struct obstack *out, int source, rule_number ruleno,
+              bool enabled, bool first, FILE *fout)
+{
+  /* If no lookahead tokens were valid transitions, this reduction is
+     actually hidden, so cancel everything. */
+  if (first)
+    (void) obstack_finish0 (out);
+  else
+    {
+      char const *ed = enabled ? "" : "d";
+      char const *color = enabled ? ruleno ? "3" : "1" : "5";
+
+      /* First, build the edge's head. The name of reduction nodes is "nRm",
+         with n the source state and m the rule number. This is because we
+         don't want all the reductions bearing a same rule number to point to
+         the same state, since that is not the desired format. */
+      fprintf (fout, "  %1$d -> \"%1$dR%2$d%3$s\" [",
+               source, ruleno, ed);
+
+      /* (The lookahead tokens have been added to the beginning of the
+         obstack, in the caller function.) */
+      if (! obstack_empty_p (out))
+        {
+          char *label = obstack_finish0 (out);
+          fprintf (fout, "label=\"[%s]\", ", label);
+          obstack_free (out, label);
+        }
+
+      /* Then, the edge's tail. */
+      fprintf (fout, "style=solid]\n");
+
+      /* Build the associated diamond representation of the target rule. */
+      fprintf (fout, " \"%dR%d%s\" [label=\"",
+               source, ruleno, ed);
+      if (ruleno)
+        fprintf (fout, "R%d", ruleno);
+      else
+        fprintf (fout, "Acc");
+
+      fprintf (fout, "\", fillcolor=%s, shape=diamond, style=filled]\n",
+               color);
+    }
+}
+
+static bool
+print_token (struct obstack *out, bool first, char const *tok)
+{
+  char const *q = escape (tok);
+
+  if (! first)
+    obstack_sgrow (out, ", ");
+  obstack_sgrow (out, q);
+  return false;
+}
+
+void
+output_red (state const *s, reductions const *reds, FILE *fout)
+{
+  bitset no_reduce_set;
+  int j;
+  int source = s->number;
+
+  /* Two obstacks are needed: one for the enabled reductions, and one
+     for the disabled reductions, because in the end we want two
+     separate edges, even though in most cases only one will actually
+     be printed. */
+  struct obstack dout;
+  struct obstack eout;
+
+  no_reduce_bitset_init (s, &no_reduce_set);
+  obstack_init (&dout);
+  obstack_init (&eout);
+
+  for (j = 0; j < reds->num; ++j)
+    {
+      bool defaulted = false;
+      bool firstd = true;
+      bool firste = true;
+      rule_number ruleno = reds->rules[j]->number;
+      rule *default_reduction = NULL;
+
+      if (yydefact[s->number] != 0)
+        default_reduction = &rules[yydefact[s->number] - 1];
+
+      /* Build the lookahead tokens lists, one for enabled transitions and one
+         for disabled transistions. */
+      if (default_reduction && default_reduction == reds->rules[j])
+        defaulted = true;
+      if (reds->lookahead_tokens)
+        {
+          int i;
+          for (i = 0; i < ntokens; i++)
+            if (bitset_test (reds->lookahead_tokens[j], i))
+              {
+                if (bitset_test (no_reduce_set, i))
+                  firstd = print_token (&dout, firstd, symbols[i]->tag);
+                else
+                  {
+                    if (! defaulted)
+                      firste = print_token (&eout, firste, symbols[i]->tag);
+                    bitset_set (no_reduce_set, i);
+                  }
+              }
+        }
+
+      /* Do the actual output. */
+      conclude_red (&dout, source, ruleno, false, firstd, fout);
+      conclude_red (&eout, source, ruleno, true, firste && !defaulted, fout);
+    }
+  obstack_free (&dout, 0);
+  obstack_free (&eout, 0);
+  bitset_free (no_reduce_set);
+}
+
+void
+finish_graph (FILE *fout)
+{
+  fputs ("}\n", fout);
+}
diff --git a/src/graphviz.h b/src/graphviz.h
new file mode 100644
index 0000000..239cdd2
--- /dev/null
+++ b/src/graphviz.h
@@ -0,0 +1,71 @@
+/* Output Graphviz specification of a state machine generated by Bison.
+
+   Copyright (C) 2006, 2010-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert and Satya Kiran Popuri.  */
+
+#ifndef GRAPHVIZ_H_
+# define GRAPHVIZ_H_
+
+#include "state.h"
+
+/** Begin a Dot graph.
+ *
+ * \param fout   output stream.
+ */
+void start_graph (FILE *fout);
+
+/** Output a Dot node.
+ *
+ * \param id     identifier of the node
+ * \param label  human readable label of the node (no Dot escaping needed).
+ * \param fout   output stream.
+ */
+void output_node (int id, char const *label, FILE *fout);
+
+/** Output a Dot edge.
+ * \param source       id of the source node
+ * \param destination  id of the target node
+ * \param label        human readable label of the edge
+ *                     (no Dot escaping needed).  Can be 0.
+ * \param style        Dot style of the edge (e.g., "dotted" or "solid").
+ * \param fout         output stream.
+ */
+void output_edge (int source, int destination, char const *label,
+                  char const *style, FILE *fout);
+
+/** Output a reduction.
+ * \param s            current state
+ * \param reds         the set of reductions
+ * \param fout         output stream.
+ */
+void output_red (state const *s, reductions const *reds, FILE *fout);
+
+/** End a Dot graph.
+ *
+ * \param fout  output stream.
+ */
+void finish_graph (FILE *fout);
+
+/** Escape a lookahead token.
+ *
+ * \param name         the token.
+ */
+char const *escape (char const *name);
+
+#endif /* ! GRAPHVIZ_H_ */
diff --git a/src/ielr.c b/src/ielr.c
new file mode 100644
index 0000000..e6aa6f5
--- /dev/null
+++ b/src/ielr.c
@@ -0,0 +1,1200 @@
+/* IELR main implementation.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include "ielr.h"
+
+#include <bitset.h>
+#include <timevar.h>
+
+#include "AnnotationList.h"
+#include "derives.h"
+#include "getargs.h"
+#include "lalr.h"
+#include "muscle-tab.h"
+#include "nullable.h"
+#include "relation.h"
+#include "state.h"
+#include "symtab.h"
+
+/** Records the value of the \%define variable lr.type.  */
+typedef enum { LR_TYPE__LALR, LR_TYPE__IELR, LR_TYPE__CANONICAL_LR } LrType;
+
+/**
+ * \post:
+ *   - \c result = a new \c bitset of size \c ::nritems such that any bit \c i
+ *     is set iff <tt>ritem[i]</tt> is a nonterminal after which all ritems in
+ *     the same RHS are nullable nonterminals.  In other words, the follows of
+ *     a goto on <tt>ritem[i]</tt> include the lookahead set of the item.
+ */
+static bitset
+ielr_compute_ritem_sees_lookahead_set (void)
+{
+  bitset result = bitset_create (nritems, BITSET_FIXED);
+  unsigned int i = nritems-1;
+  while (i>0)
+    {
+      --i;
+      while (!item_number_is_rule_number (ritem[i])
+             && ISVAR (ritem[i])
+             && nullable [item_number_as_symbol_number (ritem[i]) - ntokens])
+        bitset_set (result, i--);
+      if (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i]))
+        bitset_set (result, i--);
+      while (!item_number_is_rule_number (ritem[i]) && i>0)
+        --i;
+    }
+  if (trace_flag & trace_ielr)
+    {
+      fprintf (stderr, "ritem_sees_lookahead_set:\n");
+      debug_bitset (result);
+      fprintf (stderr, "\n");
+    }
+  return result;
+}
+
+/**
+ * \pre:
+ *   - \c ritem_sees_lookahead_set was computed by
+ *     \c ielr_compute_ritem_sees_lookahead_set.
+ * \post:
+ *   - Each of \c *edgesp and \c *edge_countsp is a new array of size
+ *     \c ::ngotos.
+ *   - <tt>(*edgesp)[i]</tt> points to a \c goto_number array of size
+ *     <tt>(*edge_countsp)[i]+1</tt>.
+ *   - In such a \c goto_number array, the last element is \c ::END_NODE.
+ *   - All remaining elements are the indices of the gotos to which there is an
+ *     internal follow edge from goto \c i.
+ *   - There is an internal follow edge from goto \c i to goto \c j iff both:
+ *     - The from states of gotos \c i and \c j are the same.
+ *     - The transition nonterminal for goto \c i appears as the first RHS
+ *       symbol of at least one production for which both:
+ *       - The LHS is the transition symbol of goto \c j.
+ *       - All other RHS symbols are nullable nonterminals.
+ *     - In other words, the follows of goto \c i include the follows of
+ *       goto \c j and it's an internal edge because the from states are the
+ *       same.
+ */
+static void
+ielr_compute_internal_follow_edges (bitset ritem_sees_lookahead_set,
+                                    goto_number ***edgesp, int **edge_countsp)
+{
+  *edgesp = xnmalloc (ngotos, sizeof **edgesp);
+  *edge_countsp = xnmalloc (ngotos, sizeof **edge_countsp);
+  {
+    bitset sources = bitset_create (ngotos, BITSET_FIXED);
+    goto_number i;
+    for (i = 0; i < ngotos; ++i)
+      (*edge_countsp)[i] = 0;
+    for (i = 0; i < ngotos; ++i)
+      {
+        int nsources = 0;
+        {
+          rule **rulep;
+          for (rulep = derives[states[to_state[i]]->accessing_symbol
+                               - ntokens];
+               *rulep;
+               ++rulep)
+            {
+              /* If there is at least one RHS symbol, if the first RHS symbol
+                 is a nonterminal, and if all remaining RHS symbols (if any)
+                 are nullable nonterminals, create an edge from the LHS
+                 symbol's goto to the first RHS symbol's goto such that the RHS
+                 symbol's goto will be the source of the edge after the
+                 eventual relation_transpose below.
+
+                 Unlike in ielr_compute_always_follows, I use a bitset for
+                 edges rather than an array because it is possible that
+                 multiple RHS's with the same first symbol could fit and thus
+                 that we could end up with redundant edges.  With the
+                 possibility of redundant edges, it's hard to know ahead of
+                 time how large to make such an array.  Another possible
+                 redundancy is that source and destination might be the same
+                 goto.  Eliminating all these possible redundancies now might
+                 possibly help performance a little.  I have not proven any of
+                 this, but I'm guessing the bitset shouldn't entail much of a
+                 performance penalty, if any.  */
+              if (bitset_test (ritem_sees_lookahead_set,
+                               (*rulep)->rhs - ritem))
+                {
+                  goto_number source =
+                    map_goto (from_state[i],
+                              item_number_as_symbol_number (*(*rulep)->rhs));
+                  if (i != source && !bitset_test (sources, source))
+                    {
+                      bitset_set (sources, source);
+                      ++nsources;
+                      ++(*edge_countsp)[source];
+                    }
+                }
+            }
+        }
+        if (nsources == 0)
+          (*edgesp)[i] = NULL;
+        else
+          {
+            (*edgesp)[i] = xnmalloc (nsources + 1, sizeof *(*edgesp)[i]);
+            {
+              bitset_iterator biter_source;
+              bitset_bindex source;
+              int j = 0;
+              BITSET_FOR_EACH (biter_source, sources, source, 0)
+                (*edgesp)[i][j++] = source;
+            }
+            (*edgesp)[i][nsources] = END_NODE;
+          }
+        bitset_zero (sources);
+      }
+    bitset_free (sources);
+  }
+
+  relation_transpose (edgesp, ngotos);
+
+  if (trace_flag & trace_ielr)
+    {
+      fprintf (stderr, "internal_follow_edges:\n");
+      relation_print (*edgesp, ngotos, stderr);
+    }
+}
+
+/**
+ * \pre:
+ *   - \c ritem_sees_lookahead_set was computed by
+ *     \c ielr_compute_ritem_sees_lookahead_set.
+ *   - \c internal_follow_edges was computed by
+ *     \c ielr_compute_internal_follow_edges.
+ * \post:
+ *   - \c *follow_kernel_itemsp is a new \c bitsetv in which the number of rows
+ *     is \c ngotos and the number of columns is maximum number of kernel items
+ *     in any state.
+ *   - <tt>(*follow_kernel_itemsp)[i][j]</tt> is set iff the follows of goto
+ *     \c i include the lookahead set of item \c j in the from state of goto
+ *     \c i.
+ *   - Thus, <tt>(*follow_kernel_itemsp)[i][j]</tt> is always unset if there is
+ *     no item \c j in the from state of goto \c i.
+ */
+static void
+ielr_compute_follow_kernel_items (bitset ritem_sees_lookahead_set,
+                                  goto_number **internal_follow_edges,
+                                  bitsetv *follow_kernel_itemsp)
+{
+  {
+    size_t max_nitems = 0;
+    state_number i;
+    for (i = 0; i < nstates; ++i)
+      if (states[i]->nitems > max_nitems)
+        max_nitems = states[i]->nitems;
+    *follow_kernel_itemsp = bitsetv_create (ngotos, max_nitems, BITSET_FIXED);
+  }
+  {
+    goto_number i;
+    for (i = 0; i < ngotos; ++i)
+      {
+        size_t nitems = states[from_state[i]]->nitems;
+        item_number *items = states[from_state[i]]->items;
+        size_t j;
+        for (j = 0; j < nitems; ++j)
+          /* If this item has this goto and if all subsequent symbols in this
+             RHS (if any) are nullable nonterminals, then record this item as
+             one whose lookahead set is included in this goto's follows.  */
+          if (item_number_is_symbol_number (ritem[items[j]])
+              && item_number_as_symbol_number (ritem[items[j]])
+                == states[to_state[i]]->accessing_symbol
+              && bitset_test (ritem_sees_lookahead_set, items[j]))
+            bitset_set ((*follow_kernel_itemsp)[i], j);
+      }
+  }
+  relation_digraph (internal_follow_edges, ngotos, follow_kernel_itemsp);
+
+  if (trace_flag & trace_ielr)
+    {
+      fprintf (stderr, "follow_kernel_items:\n");
+      debug_bitsetv (*follow_kernel_itemsp);
+    }
+}
+
+/**
+ * \pre
+ *   - \c *edgesp and \c edge_counts were computed by
+ *     \c ielr_compute_internal_follow_edges.
+ * \post
+ *   - \c *always_followsp is a new \c bitsetv with \c ngotos rows and
+ *     \c ntokens columns.
+ *   - <tt>(*always_followsp)[i][j]</tt> is set iff token \c j is an always
+ *     follow (that is, it's computed by internal and successor edges) of goto
+ *     \c i.
+ *   - Rows of \c *edgesp have been realloc'ed and extended to include
+ *     successor follow edges.  \c edge_counts has not been updated.
+ */
+static void
+ielr_compute_always_follows (goto_number ***edgesp,
+                             int const edge_counts[],
+                             bitsetv *always_followsp)
+{
+  *always_followsp = bitsetv_create (ngotos, ntokens, BITSET_FIXED);
+  {
+    goto_number *edge_array = xnmalloc (ngotos, sizeof *edge_array);
+    goto_number i;
+    for (i = 0; i < ngotos; ++i)
+      {
+        goto_number nedges = edge_counts[i];
+        {
+          int j;
+          transitions *trans = states[to_state[i]]->transitions;
+          FOR_EACH_SHIFT (trans, j)
+            bitset_set ((*always_followsp)[i], TRANSITION_SYMBOL (trans, j));
+          for (; j < trans->num; ++j)
+            {
+              symbol_number sym = TRANSITION_SYMBOL (trans, j);
+              if (nullable[sym - ntokens])
+                edge_array[nedges++] = map_goto (to_state[i], sym);
+            }
+        }
+        if (nedges - edge_counts[i])
+          {
+            (*edgesp)[i] =
+              xnrealloc ((*edgesp)[i], nedges + 1, sizeof *(*edgesp)[i]);
+            memcpy ((*edgesp)[i] + edge_counts[i], edge_array + edge_counts[i],
+                    (nedges - edge_counts[i]) * sizeof *(*edgesp)[i]);
+            (*edgesp)[i][nedges] = END_NODE;
+          }
+      }
+    free (edge_array);
+  }
+  relation_digraph (*edgesp, ngotos, always_followsp);
+
+  if (trace_flag & trace_ielr)
+    {
+      fprintf (stderr, "always follow edges:\n");
+      relation_print (*edgesp, ngotos, stderr);
+      fprintf (stderr, "always_follows:\n");
+      debug_bitsetv (*always_followsp);
+    }
+}
+
+/**
+ * \post
+ *   - \c result is a new array of size \c ::nstates.
+ *   - <tt>result[i]</tt> is an array of pointers to the predecessor
+ *     <tt>state</tt>'s of state \c i.
+ *   - The last element of such an array is \c NULL.
+ */
+static state ***
+ielr_compute_predecessors (void)
+{
+  state_number i;
+  int *predecessor_counts = xnmalloc (nstates, sizeof *predecessor_counts);
+  state ***result = xnmalloc (nstates, sizeof *result);
+  for (i = 0; i < nstates; ++i)
+    predecessor_counts[i] = 0;
+  for (i = 0; i < nstates; ++i)
+    {
+      int j;
+      for (j = 0; j < states[i]->transitions->num; ++j)
+        ++predecessor_counts[states[i]->transitions->states[j]->number];
+    }
+  for (i = 0; i < nstates; ++i)
+    {
+      result[i] = xnmalloc (predecessor_counts[i]+1, sizeof *result[i]);
+      result[i][predecessor_counts[i]] = NULL;
+      predecessor_counts[i] = 0;
+    }
+  for (i = 0; i < nstates; ++i)
+    {
+      int j;
+      for (j = 0; j < states[i]->transitions->num; ++j)
+        {
+          state_number k = states[i]->transitions->states[j]->number;
+          result[k][predecessor_counts[k]++] = states[i];
+        }
+    }
+  free (predecessor_counts);
+  return result;
+}
+
+/**
+ * \post
+ *   - \c *follow_kernel_itemsp and \c *always_followsp were computed by
+ *     \c ielr_compute_follow_kernel_items and
+ *     \c ielr_compute_always_follows.
+ *   - Iff <tt>predecessorsp != NULL</tt>, then \c *predecessorsp was computed
+ *     by \c ielr_compute_predecessors.
+ */
+static void
+ielr_compute_auxiliary_tables (bitsetv *follow_kernel_itemsp,
+                               bitsetv *always_followsp,
+                               state ****predecessorsp)
+{
+  goto_number **edges;
+  int *edge_counts;
+  {
+    bitset ritem_sees_lookahead_set = ielr_compute_ritem_sees_lookahead_set ();
+    ielr_compute_internal_follow_edges (ritem_sees_lookahead_set,
+                                        &edges, &edge_counts);
+    ielr_compute_follow_kernel_items (ritem_sees_lookahead_set, edges,
+                                      follow_kernel_itemsp);
+    bitset_free (ritem_sees_lookahead_set);
+  }
+  ielr_compute_always_follows (&edges, edge_counts, always_followsp);
+  {
+    int i;
+    for (i = 0; i < ngotos; ++i)
+      free (edges[i]);
+  }
+  free (edges);
+  free (edge_counts);
+  if (predecessorsp)
+    *predecessorsp = ielr_compute_predecessors ();
+}
+
+/**
+ * \note
+ *   - FIXME: It might be an interesting experiment to compare the space and
+ *     time efficiency of computing \c item_lookahead_sets either:
+ *     - Fully up front.
+ *     - Just-in-time, as implemented below.
+ *     - Not at all.  That is, just let annotations continue even when
+ *       unnecessary.
+ */
+bool
+ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
+                         symbol_number lookahead, state ***predecessors,
+                         bitset **item_lookahead_sets)
+{
+  if (!item_lookahead_sets[s->number])
+    {
+      size_t i;
+      item_lookahead_sets[s->number] =
+        xnmalloc (s->nitems, sizeof item_lookahead_sets[s->number][0]);
+      for (i = 0; i < s->nitems; ++i)
+        item_lookahead_sets[s->number][i] = NULL;
+    }
+  if (!item_lookahead_sets[s->number][item])
+    {
+      item_lookahead_sets[s->number][item] =
+        bitset_create (ntokens, BITSET_FIXED);
+      /* If this kernel item is the beginning of a RHS, it must be the kernel
+         item in the start state, and so its LHS has no follows and no goto to
+         check.  If, instead, this kernel item is the successor of the start
+         state's kernel item, there are still no follows and no goto.  This
+         situation is fortunate because we want to avoid the - 2 below in both
+         cases.
+
+         Actually, IELR(1) should never invoke this function for either of
+         those cases because (1) follow_kernel_items will never reference a
+         kernel item for this RHS because the end token blocks sight of the
+         lookahead set from the RHS's only nonterminal, and (2) no reduction
+         has a lookback dependency on this lookahead set.  Nevertheless, I
+         didn't change this test to an aver just in case the usage of this
+         function evolves to need those two cases.  In both cases, the current
+         implementation returns the right result.  */
+      if (s->items[item] > 1)
+        {
+          /* If the LHS symbol of this item isn't known (because this is a
+             top-level invocation), go get it.  */
+          if (!lhs)
+            {
+              unsigned int i;
+              for (i = s->items[item];
+                   !item_number_is_rule_number (ritem[i]);
+                   ++i)
+                ;
+              lhs = rules[item_number_as_rule_number (ritem[i])].lhs->number;
+            }
+          /* If this kernel item is next to the beginning of the RHS, then
+             check all predecessors' goto follows for the LHS.  */
+          if (item_number_is_rule_number (ritem[s->items[item] - 2]))
+            {
+              state **predecessor;
+              aver (lhs != accept->number);
+              for (predecessor = predecessors[s->number];
+                   *predecessor;
+                   ++predecessor)
+                bitset_or (item_lookahead_sets[s->number][item],
+                           item_lookahead_sets[s->number][item],
+                           goto_follows[map_goto ((*predecessor)->number,
+                                                  lhs)]);
+            }
+          /* If this kernel item is later in the RHS, then check all
+             predecessor items' lookahead sets.  */
+          else
+            {
+              state **predecessor;
+              for (predecessor = predecessors[s->number];
+                   *predecessor;
+                   ++predecessor)
+                {
+                  size_t predecessor_item;
+                  for (predecessor_item = 0;
+                       predecessor_item < (*predecessor)->nitems;
+                       ++predecessor_item)
+                    if ((*predecessor)->items[predecessor_item]
+                        == s->items[item] - 1)
+                      break;
+                  aver (predecessor_item != (*predecessor)->nitems);
+                  ielr_item_has_lookahead (*predecessor, lhs,
+                                           predecessor_item, 0 /*irrelevant*/,
+                                           predecessors, item_lookahead_sets);
+                  bitset_or (item_lookahead_sets[s->number][item],
+                             item_lookahead_sets[s->number][item],
+                             item_lookahead_sets[(*predecessor)->number]
+                                                [predecessor_item]);
+                }
+            }
+        }
+    }
+  return bitset_test (item_lookahead_sets[s->number][item], lookahead);
+}
+
+/**
+ * \pre
+ *   - \c follow_kernel_items, \c always_follows, and \c predecessors
+ *     were computed by \c ielr_compute_auxiliary_tables.
+ * \post
+ *   - Each of <tt>*inadequacy_listsp</tt> and <tt>*annotation_listsp</tt>
+ *     points to a new array of size \c ::nstates.
+ *   - For <tt>0 <= i < ::nstates</tt>:
+ *     - <tt>(*inadequacy_listsp)[i]</tt> contains the \c InadequacyList head
+ *       node for <tt>states[i]</tt>.
+ *     - <tt>(*annotation_listsp)[i]</tt> contains the \c AnnotationList head
+ *       node for <tt>states[i]</tt>.
+ *   - <tt>*max_annotationsp</tt> is the maximum number of annotations per
+ *     state.
+ */
+static void
+ielr_compute_annotation_lists (bitsetv follow_kernel_items,
+                               bitsetv always_follows, state ***predecessors,
+                               AnnotationIndex *max_annotationsp,
+                               InadequacyList ***inadequacy_listsp,
+                               AnnotationList ***annotation_listsp,
+                               struct obstack *annotations_obstackp)
+{
+  bitset **item_lookahead_sets =
+    xnmalloc (nstates, sizeof *item_lookahead_sets);
+  AnnotationIndex *annotation_counts =
+    xnmalloc (nstates, sizeof *annotation_counts);
+  ContributionIndex max_contributions = 0;
+  unsigned int total_annotations = 0;
+  state_number i;
+
+  *inadequacy_listsp = xnmalloc (nstates, sizeof **inadequacy_listsp);
+  *annotation_listsp = xnmalloc (nstates, sizeof **annotation_listsp);
+  for (i = 0; i < nstates; ++i)
+    {
+      item_lookahead_sets[i] = NULL;
+      (*inadequacy_listsp)[i] = NULL;
+      (*annotation_listsp)[i] = NULL;
+      annotation_counts[i] = 0;
+    }
+  {
+    InadequacyListNodeCount inadequacy_list_node_count = 0;
+    for (i = 0; i < nstates; ++i)
+      AnnotationList__compute_from_inadequacies (
+        states[i], follow_kernel_items, always_follows, predecessors,
+        item_lookahead_sets, *inadequacy_listsp, *annotation_listsp,
+        annotation_counts, &max_contributions, annotations_obstackp,
+        &inadequacy_list_node_count);
+  }
+  *max_annotationsp = 0;
+  for (i = 0; i < nstates; ++i)
+    {
+      if (annotation_counts[i] > *max_annotationsp)
+        *max_annotationsp = annotation_counts[i];
+      total_annotations += annotation_counts[i];
+    }
+  if (trace_flag & trace_ielr)
+    {
+      for (i = 0; i < nstates; ++i)
+        {
+          fprintf (stderr, "Inadequacy annotations for state %d:\n", i);
+          AnnotationList__debug ((*annotation_listsp)[i],
+                                 states[i]->nitems, 2);
+        }
+      fprintf (stderr, "Number of LR(0)/LALR(1) states: %d\n", nstates);
+      fprintf (stderr, "Average number of annotations per state: %f\n",
+               (float)total_annotations/nstates);
+      fprintf (stderr, "Max number of annotations per state: %d\n",
+               *max_annotationsp);
+      fprintf (stderr, "Max number of contributions per annotation: %d\n",
+               max_contributions);
+    }
+  for (i = 0; i < nstates; ++i)
+    if (item_lookahead_sets[i])
+      {
+        size_t j;
+        for (j = 0; j < states[i]->nitems; ++j)
+          if (item_lookahead_sets[i][j])
+            bitset_free (item_lookahead_sets[i][j]);
+        free (item_lookahead_sets[i]);
+      }
+  free (item_lookahead_sets);
+  free (annotation_counts);
+}
+
+typedef struct state_list {
+  struct state_list *next;
+  state *state;
+  /** Has this state been recomputed as a successor of another state?  */
+  bool recomputedAsSuccessor;
+  /**
+   * \c NULL iff all lookahead sets are empty.  <tt>lookaheads[i] = NULL</tt>
+   * iff the lookahead set on item \c i is empty.
+   */
+  bitset *lookaheads;
+  /**
+   * nextIsocore is the next state in a circularly linked-list of all states
+   * with the same core.  The one originally computed by generate_states in
+   * LR0.c is lr0Isocore.
+   */
+  struct state_list *lr0Isocore;
+  struct state_list *nextIsocore;
+} state_list;
+
+/**
+ * \pre
+ *   - \c follow_kernel_items and \c always_follows were computed by
+ *     \c ielr_compute_auxiliary_tables.
+ *   - <tt>n->class = nterm_sym</tt>.
+ * \post
+ *   - \c follow_set contains the follow set for the goto on nonterminal \c n
+ *     in state \c s based on the lookaheads stored in <tt>s->lookaheads</tt>.
+ */
+static void
+ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
+                              bitsetv always_follows, state_list *s,
+                              symbol *n, bitset follow_set)
+{
+  goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
+  bitset_copy (follow_set, always_follows[n_goto]);
+  if (s->lookaheads)
+    {
+      bitset_iterator biter_item;
+      bitset_bindex item;
+      BITSET_FOR_EACH (biter_item, follow_kernel_items[n_goto], item, 0)
+        if (s->lookaheads[item])
+          bitset_or (follow_set, follow_set, s->lookaheads[item]);
+    }
+}
+
+/**
+ * \pre
+ *   - \c follow_kernel_items and \c always_follows were computed by
+ *     \c ielr_compute_auxiliary_tables.
+ *   - \c lookahead_filter was computed by
+ *     \c AnnotationList__computeLookaheadFilter for the original LR(0) isocore
+ *     of \c t.
+ *   - The number of rows in \c lookaheads is at least the number of items in
+ *     \c t, and the number of columns is \c ::ntokens.
+ * \post
+ *   - <tt>lookaheads[i][j]</tt> is set iff both:
+ *     - <tt>lookahead_filter[i][j]</tt> is set.
+ *     - The isocore of \c t that will be the transition successor of \c s will
+ *       inherit from \c s token \c j into the lookahead set of item \c i.
+ */
+static void
+ielr_compute_lookaheads (bitsetv follow_kernel_items, bitsetv always_follows,
+                         state_list *s, state *t, bitsetv lookahead_filter,
+                         bitsetv lookaheads)
+{
+  size_t s_item = 0;
+  size_t t_item;
+  bitsetv_zero (lookaheads);
+  for (t_item = 0; t_item < t->nitems; ++t_item)
+    {
+      /* If this kernel item is the beginning of a RHS, it must be the
+         kernel item in the start state, but t is supposed to be a successor
+         state.  If, instead, this kernel item is the successor of the start
+         state's kernel item, the lookahead set is empty.  This second case is
+         a special case to avoid the - 2 below, but the next successor can be
+         handled fine without special casing it.  */
+      aver (t->items[t_item] != 0);
+      if (t->items[t_item] > 1
+          && !bitset_empty_p (lookahead_filter[t_item]))
+        {
+          if (item_number_is_rule_number (ritem[t->items[t_item] - 2]))
+            {
+              unsigned int rule_item;
+              for (rule_item = t->items[t_item];
+                   !item_number_is_rule_number (ritem[rule_item]);
+                   ++rule_item)
+                ;
+              ielr_compute_goto_follow_set (
+                follow_kernel_items, always_follows, s,
+                rules[item_number_as_rule_number (ritem[rule_item])].lhs,
+                lookaheads[t_item]);
+            }
+          else if (s->lookaheads)
+            {
+              /* We don't have to start the s item search at the beginning
+                 every time because items from both states are sorted by their
+                 indices in ritem.  */
+              for (; s_item < s->state->nitems; ++s_item)
+                if (s->state->items[s_item] == t->items[t_item] - 1)
+                  break;
+              aver (s_item != s->state->nitems);
+              if (s->lookaheads[s_item])
+                bitset_copy (lookaheads[t_item], s->lookaheads[s_item]);
+            }
+          bitset_and (lookaheads[t_item],
+                      lookaheads[t_item], lookahead_filter[t_item]);
+        }
+    }
+}
+
+/**
+ * \pre
+ *   - \c follow_kernel_items and \c always_follows were computed by
+ *     \c ielr_compute_auxiliary_tables.
+ *   - Either:
+ *     - <tt>annotation_lists = NULL</tt> and all bits in work2 are set.
+ *     - \c annotation_lists was computed by \c ielr_compute_annotation_lists.
+ *   - The number of rows in each of \c lookaheads and \c work2 is the maximum
+ *     number of items in any state.  The number of columns in each is
+ *     \c ::ntokens.
+ *   - \c lookaheads was computed by \c ielr_compute_lookaheads for \c t.
+ *   - \c ::nstates is the total number of states, some not yet fully computed,
+ *     in the list ending at \c *last_statep.  It is at least the number of
+ *     original LR(0) states.
+ *   - The size of \c work1 is at least the number of annotations for the LR(0)
+ *     isocore of \c t.
+ * \post
+ *   - Either:
+ *     - In the case that <tt>annotation_lists != NULL</tt>,
+ *       <tt>lookaheads \@pre</tt> was merged with some isocore of \c t if
+ *       permitted by the annotations for the original LR(0) isocore of \c t.
+ *       If this changed the lookaheads in that isocore, those changes were
+ *       propagated to all already computed transition successors recursively
+ *       possibly resulting in the splitting of some of those successors.
+ *     - In the case that <tt>annotation_lists = NULL</tt>,
+ *       <tt>lookaheads \@pre</tt> was merged with some isocore of \c t if the
+ *       isocore's lookahead sets were identical to those specified by
+ *       <tt>lookaheads \@pre</tt>.
+ *     - If no such merge was permitted, a new isocore of \c t containing
+ *       <tt>lookaheads \@pre</tt> was appended to the state list whose
+ *       previous tail was <tt>*last_statep \@pre</tt> and \c ::nstates was
+ *       incremented.  It was also appended to \c t's isocore list.
+ *   - <tt>*tp</tt> = the isocore of \c t into which
+ *     <tt>lookaheads \@pre</tt> was placed/merged.
+ *   - \c lookaheads, \c work1, and \c work2 may have been altered.
+ */
+static void
+ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows,
+                    AnnotationList **annotation_lists, state *t,
+                    bitsetv lookaheads, state_list **last_statep,
+                    ContributionIndex work1[], bitsetv work2, state **tp)
+{
+  state_list *lr0_isocore = t->state_list->lr0Isocore;
+  state_list **this_isocorep;
+  bool has_lookaheads;
+
+  /* Determine whether there's an isocore of t with which these lookaheads can
+     be merged.  */
+  {
+    AnnotationIndex ai;
+    AnnotationList *a;
+    if (annotation_lists)
+      for (ai = 0, a = annotation_lists[lr0_isocore->state->number];
+           a;
+           ++ai, a = a->next)
+        work1[ai] =
+          AnnotationList__computeDominantContribution (
+            a, lr0_isocore->state->nitems, lookaheads, false);
+    for (this_isocorep = &t->state_list;
+         this_isocorep == &t->state_list || *this_isocorep != t->state_list;
+         this_isocorep = &(*this_isocorep)->nextIsocore)
+      {
+        if (!(*this_isocorep)->recomputedAsSuccessor)
+          break;
+        if (annotation_lists)
+          {
+            for (ai = 0, a = annotation_lists[lr0_isocore->state->number];
+                 a;
+                 ++ai, a = a->next)
+              {
+                if (work1[ai] != ContributionIndex__none)
+                  {
+                    /* This isocore compatibility test depends on the fact
+                       that, if the dominant contributions are the same for the
+                       two isocores, then merging their lookahead sets will not
+                       produce a state with a different dominant contribution.
+                       */
+                    ContributionIndex ci =
+                      AnnotationList__computeDominantContribution (
+                        a, lr0_isocore->state->nitems,
+                        (*this_isocorep)->lookaheads, false);
+                    if (ci != ContributionIndex__none && work1[ai] != ci)
+                      break;
+                  }
+              }
+            if (!a)
+              break;
+          }
+        else
+          {
+            size_t i;
+            for (i = 0; i < t->nitems; ++i)
+              {
+                if (!(*this_isocorep)->lookaheads
+                    || !(*this_isocorep)->lookaheads[i])
+                  {
+                    if (!bitset_empty_p (lookaheads[i]))
+                      break;
+                  }
+                /* bitset_equal_p uses the size of the first argument,
+                   so lookaheads[i] must be the second argument.  */
+                else if (!bitset_equal_p ((*this_isocorep)->lookaheads[i],
+                                          lookaheads[i]))
+                  break;
+              }
+            if (i == t->nitems)
+              break;
+          }
+      }
+  }
+
+  has_lookaheads = false;
+  {
+    size_t i;
+    for (i = 0; i < lr0_isocore->state->nitems; ++i)
+      if (!bitset_empty_p (lookaheads[i]))
+        {
+          has_lookaheads = true;
+          break;
+        }
+  }
+
+  /* Merge with an existing isocore.  */
+  if (this_isocorep == &t->state_list || *this_isocorep != t->state_list)
+    {
+      bool new_lookaheads = false;
+      *tp = (*this_isocorep)->state;
+
+      /* Merge lookaheads into the state and record whether any of them are
+         actually new.  */
+      if (has_lookaheads)
+        {
+          size_t i;
+          if (!(*this_isocorep)->lookaheads)
+            {
+              (*this_isocorep)->lookaheads =
+                xnmalloc (t->nitems, sizeof (*this_isocorep)->lookaheads);
+              for (i = 0; i < t->nitems; ++i)
+                (*this_isocorep)->lookaheads[i] = NULL;
+            }
+          for (i = 0; i < t->nitems; ++i)
+            if (!bitset_empty_p (lookaheads[i]))
+              {
+                if (!(*this_isocorep)->lookaheads[i])
+                  (*this_isocorep)->lookaheads[i] =
+                    bitset_create (ntokens, BITSET_FIXED);
+                bitset_andn (lookaheads[i],
+                             lookaheads[i], (*this_isocorep)->lookaheads[i]);
+                bitset_or ((*this_isocorep)->lookaheads[i],
+                           lookaheads[i], (*this_isocorep)->lookaheads[i]);
+                if (!bitset_empty_p (lookaheads[i]))
+                  new_lookaheads = true;
+              }
+        }
+
+      /* If new lookaheads were merged, propagate those lookaheads to the
+         successors, possibly splitting them.  If *tp is being recomputed for
+         the first time, this isn't necessary because the main
+         ielr_split_states loop will handle the successors later.  */
+      if (!(*this_isocorep)->recomputedAsSuccessor)
+        (*this_isocorep)->recomputedAsSuccessor = true;
+      else if (new_lookaheads)
+        {
+          int i;
+          /* When merging demands identical lookahead sets, it is impossible to
+             merge new lookaheads.  */
+          aver (annotation_lists);
+          for (i = 0; i < (*tp)->transitions->num; ++i)
+            {
+              state *t2 = (*tp)->transitions->states[i];
+              /* At any time, there's at most one state for which we have so
+                 far initially recomputed only some of its successors in the
+                 main ielr_split_states loop.  Because we recompute successors
+                 in order, we can just stop at the first such successor.  Of
+                 course, *tp might be a state some of whose successors have
+                 been recomputed as successors of other states rather than as
+                 successors of *tp.  It's fine if we go ahead and propagate to
+                 some of those.  We'll propagate to them again (but stop when
+                 we see nothing changes) and to the others when we reach *tp in
+                 the main ielr_split_states loop later.  */
+              if (!t2->state_list->recomputedAsSuccessor)
+                break;
+              AnnotationList__computeLookaheadFilter (
+                annotation_lists[t2->state_list->lr0Isocore->state->number],
+                t2->nitems, work2);
+              ielr_compute_lookaheads (follow_kernel_items, always_follows,
+                                       (*this_isocorep), t2, work2,
+                                       lookaheads);
+              /* FIXME: If splitting t2 here, it's possible that lookaheads
+                 that had already propagated from *tp to t2 will be left in t2
+                 after *tp has been removed as t2's predecessor:
+                 - We're going to recompute all lookaheads in phase 4, so these
+                   extra lookaheads won't appear in the final parser table.
+                 - If t2 has just one annotation, then these extra lookaheads
+                   cannot alter the dominating contribution to the associated
+                   inadequacy and thus cannot needlessly prevent a future merge
+                   of some new state with t2.  We can be sure of this because:
+                   - The fact that we're splitting t2 now means that some
+                     predecessors (at least one) other than *tp must be
+                     propagating contributions to t2.
+                   - The fact that t2 was merged in the first place means that,
+                     if *tp propagated any contributions, the dominating
+                     contribution must be the same as that from those other
+                     predecessors.
+                   - Thus, if some new state to be merged with t2 in the future
+                     proves to be compatible with the contributions propagated
+                     by the other predecessors, it will also be compatible with
+                     the contributions made by the extra lookaheads left behind
+                     by *tp.
+                 - However, if t2 has more than one annotation and these extra
+                   lookaheads contribute to one of their inadequacies, it's
+                   possible these extra lookaheads may needlessly prevent a
+                   future merge with t2.  For example:
+                   - Let's say there's an inadequacy A that makes the split
+                     necessary as follows:
+                     - There's currently just one other predecessor and it
+                       propagates to t2 some contributions to inadequacy A.
+                     - The new lookaheads that we were attempting to propagate
+                       from *tp to t2 made contributions to inadequacy A with a
+                       different dominating contribution than those from that
+                       other predecessor.
+                     - The extra lookaheads either make no contribution to
+                       inadequacy A or have the same dominating contribution as
+                       the contributions from the other predecessor.  Either
+                       way, as explained above, they can't prevent a future
+                       merge.
+                   - Let's say there's an inadequacy B that causes the trouble
+                     with future merges as follows:
+                     - The extra lookaheads make contributions to inadequacy B.
+                     - Those extra contributions did not prevent the original
+                       merge to create t2 because the other predecessor
+                       propagates to t2 no contributions to inadequacy B.
+                     - Thus, those extra contributions may prevent a future
+                       merge with t2 even though the merge would be fine if *tp
+                       had not left them behind.
+                 - Is the latter case common enough to worry about?
+                 - Perhaps we should track all predecessors and iterate them
+                   now to recreate t2 without those extra lookaheads.  */
+              ielr_compute_state (follow_kernel_items, always_follows,
+                                  annotation_lists, t2, lookaheads,
+                                  last_statep, work1, work2,
+                                  &(*tp)->transitions->states[i]);
+            }
+        }
+    }
+
+  /* Create a new isocore.  */
+  else
+    {
+      state_list *old_isocore = *this_isocorep;
+      (*last_statep)->next = *this_isocorep = xmalloc (sizeof **last_statep);
+      *last_statep = *this_isocorep;
+      (*last_statep)->state = *tp = state_new_isocore (t);
+      (*tp)->state_list = *last_statep;
+      (*last_statep)->recomputedAsSuccessor = true;
+      (*last_statep)->next = NULL;
+      (*last_statep)->lookaheads = NULL;
+      if (has_lookaheads)
+        {
+          size_t i;
+          (*last_statep)->lookaheads =
+            xnmalloc (t->nitems, sizeof (*last_statep)->lookaheads);
+          for (i = 0; i < t->nitems; ++i)
+            {
+              if (bitset_empty_p (lookaheads[i]))
+                (*last_statep)->lookaheads[i] = NULL;
+              else
+                {
+                  (*last_statep)->lookaheads[i] =
+                    bitset_create (ntokens, BITSET_FIXED);
+                  bitset_copy ((*last_statep)->lookaheads[i], lookaheads[i]);
+                }
+            }
+        }
+      (*last_statep)->lr0Isocore = lr0_isocore;
+      (*last_statep)->nextIsocore = old_isocore;
+    }
+}
+
+/**
+ * \pre
+ *   - \c follow_kernel_items and \c always_follows were computed by
+ *     \c ielr_compute_auxiliary_tables.
+ *   - Either:
+ *     - <tt>annotation_lists = NULL</tt> and <tt>max_annotations=0</tt>.
+ *     - \c annotation_lists and \c max_annotations were computed by
+ *       \c ielr_compute_annotation_lists.
+ * \post
+ *   - \c ::states is of size \c ::nstates (which might be greater than
+ *     <tt>::nstates \@pre</tt>) and no longer contains any LR(1)-relative
+ *     inadequacy.  \c annotation_lists was used to determine state
+ *     compatibility or, if <tt>annotation_lists = NULL</tt>, the canonical
+ *     LR(1) state compatibility test was used.
+ *   - If <tt>annotation_lists = NULL</tt>, reduction lookahead sets were
+ *     computed in all states.  TV_IELR_PHASE4 was pushed while they were
+ *     computed from item lookahead sets.
+ */
+static void
+ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
+                   AnnotationList **annotation_lists,
+                   AnnotationIndex max_annotations)
+{
+  state_list *first_state;
+  state_list *last_state;
+  bitsetv lookahead_filter = NULL;
+  bitsetv lookaheads;
+
+  /* Set up state list and some reusable bitsets.  */
+  {
+    size_t max_nitems = 0;
+    state_number i;
+    state_list **nodep = &first_state;
+    for (i = 0; i < nstates; ++i)
+      {
+        *nodep = states[i]->state_list = last_state = xmalloc (sizeof **nodep);
+        (*nodep)->state = states[i];
+        (*nodep)->recomputedAsSuccessor = false;
+        (*nodep)->lookaheads = NULL;
+        (*nodep)->lr0Isocore = *nodep;
+        (*nodep)->nextIsocore = *nodep;
+        nodep = &(*nodep)->next;
+        if (states[i]->nitems > max_nitems)
+          max_nitems = states[i]->nitems;
+      }
+    *nodep = NULL;
+    lookahead_filter = bitsetv_create (max_nitems, ntokens, BITSET_FIXED);
+    if (!annotation_lists)
+      bitsetv_ones (lookahead_filter);
+    lookaheads = bitsetv_create (max_nitems, ntokens, BITSET_FIXED);
+  }
+
+  /* Recompute states.  */
+  {
+    ContributionIndex *work = xnmalloc (max_annotations, sizeof *work);
+    state_list *this_state;
+    for (this_state = first_state; this_state; this_state = this_state->next)
+      {
+        state *s = this_state->state;
+        int i;
+        for (i = 0; i < s->transitions->num; ++i)
+          {
+            state *t = s->transitions->states[i];
+            if (annotation_lists)
+              AnnotationList__computeLookaheadFilter (
+                annotation_lists[t->state_list->lr0Isocore->state->number],
+                t->nitems, lookahead_filter);
+            ielr_compute_lookaheads (follow_kernel_items, always_follows,
+                                     this_state, t, lookahead_filter,
+                                     lookaheads);
+            ielr_compute_state (follow_kernel_items, always_follows,
+                                annotation_lists, t, lookaheads, &last_state,
+                                work, lookahead_filter,
+                                &s->transitions->states[i]);
+          }
+      }
+    free (work);
+  }
+
+  bitsetv_free (lookahead_filter);
+  bitsetv_free (lookaheads);
+
+  /* Store states back in the states array.  */
+  states = xnrealloc (states, nstates, sizeof *states);
+  {
+    state_list *node;
+    for (node = first_state; node; node = node->next)
+      states[node->state->number] = node->state;
+  }
+
+  /* In the case of canonical LR(1), copy item lookahead sets to reduction
+     lookahead sets.  */
+  if (!annotation_lists)
+    {
+      timevar_push (TV_IELR_PHASE4);
+      initialize_LA ();
+      state_list *node;
+      for (node = first_state; node; node = node->next)
+        if (!node->state->consistent)
+          {
+            size_t i = 0;
+            item_number *itemset = node->state->items;
+            size_t r;
+            for (r = 0; r < node->state->reductions->num; ++r)
+              {
+                rule *this_rule = node->state->reductions->rules[r];
+                bitset lookahead_set =
+                  node->state->reductions->lookahead_tokens[r];
+                if (item_number_is_rule_number (*this_rule->rhs))
+                  ielr_compute_goto_follow_set (follow_kernel_items,
+                                                always_follows, node,
+                                                this_rule->lhs, lookahead_set);
+                else if (node->lookaheads)
+                  {
+                    /* We don't need to start the kernel item search back at
+                       i=0 because both items and reductions are sorted on rule
+                       number.  */
+                    while (!item_number_is_rule_number (ritem[itemset[i]])
+                           || item_number_as_rule_number (ritem[itemset[i]])
+                              != this_rule->number)
+                      {
+                        ++i;
+                        aver (i < node->state->nitems);
+                      }
+                    if (node->lookaheads[i])
+                      bitset_copy (lookahead_set, node->lookaheads[i]);
+                  }
+              }
+          }
+      timevar_pop (TV_IELR_PHASE4);
+    }
+
+  /* Free state list.  */
+  while (first_state)
+    {
+      state_list *node = first_state;
+      if (node->lookaheads)
+        {
+          size_t i;
+          for (i = 0; i < node->state->nitems; ++i)
+            if (node->lookaheads[i])
+              bitset_free (node->lookaheads[i]);
+          free (node->lookaheads);
+        }
+      first_state = node->next;
+      free (node);
+    }
+}
+
+void
+ielr (void)
+{
+  LrType lr_type;
+
+  /* Examine user options.  */
+  {
+    char *type = muscle_percent_define_get ("lr.type");
+    if (0 == strcmp (type, "lalr"))
+      lr_type = LR_TYPE__LALR;
+    else if (0 == strcmp (type, "ielr"))
+      lr_type = LR_TYPE__IELR;
+    else if (0 == strcmp (type, "canonical-lr"))
+      lr_type = LR_TYPE__CANONICAL_LR;
+    else
+      aver (false);
+    free (type);
+  }
+
+  /* Phase 0: LALR(1).  */
+  timevar_push (TV_LALR);
+  if (lr_type == LR_TYPE__CANONICAL_LR)
+    set_goto_map ();
+  else
+    lalr ();
+  if (lr_type == LR_TYPE__LALR)
+    {
+      bitsetv_free (goto_follows);
+      timevar_pop (TV_LALR);
+      return;
+    }
+  timevar_pop (TV_LALR);
+
+  {
+    bitsetv follow_kernel_items;
+    bitsetv always_follows;
+    InadequacyList **inadequacy_lists = NULL;
+    AnnotationList **annotation_lists = NULL;
+    struct obstack annotations_obstack;
+    AnnotationIndex max_annotations = 0;
+
+    {
+      /* Phase 1: Compute Auxiliary Tables.  */
+      state ***predecessors;
+      timevar_push (TV_IELR_PHASE1);
+      ielr_compute_auxiliary_tables (
+        &follow_kernel_items, &always_follows,
+        lr_type == LR_TYPE__CANONICAL_LR ? NULL : &predecessors);
+      timevar_pop (TV_IELR_PHASE1);
+
+      /* Phase 2: Compute Annotations.  */
+      timevar_push (TV_IELR_PHASE2);
+      if (lr_type != LR_TYPE__CANONICAL_LR)
+        {
+          obstack_init (&annotations_obstack);
+          ielr_compute_annotation_lists (follow_kernel_items, always_follows,
+                                         predecessors, &max_annotations,
+                                         &inadequacy_lists, &annotation_lists,
+                                         &annotations_obstack);
+          {
+            state_number i;
+            for (i = 0; i < nstates; ++i)
+              free (predecessors[i]);
+          }
+          free (predecessors);
+          bitsetv_free (goto_follows);
+          lalr_free ();
+        }
+      timevar_pop (TV_IELR_PHASE2);
+    }
+
+    /* Phase 3: Split States.  */
+    timevar_push (TV_IELR_PHASE3);
+    {
+      state_number nstates_lr0 = nstates;
+      ielr_split_states (follow_kernel_items, always_follows,
+                         annotation_lists, max_annotations);
+      if (inadequacy_lists)
+        {
+          state_number i;
+          for (i = 0; i < nstates_lr0; ++i)
+            InadequacyList__delete (inadequacy_lists[i]);
+        }
+    }
+    free (inadequacy_lists);
+    if (annotation_lists)
+      obstack_free (&annotations_obstack, NULL);
+    free (annotation_lists);
+    bitsetv_free (follow_kernel_items);
+    bitsetv_free (always_follows);
+    timevar_pop (TV_IELR_PHASE3);
+  }
+
+  /* Phase 4: Compute Reduction Lookaheads.  */
+  timevar_push (TV_IELR_PHASE4);
+  free (goto_map);
+  free (from_state);
+  free (to_state);
+  if (lr_type == LR_TYPE__CANONICAL_LR)
+    {
+      /* Reduction lookaheads are computed in ielr_split_states above
+         but are timed as part of phase 4. */
+      set_goto_map ();
+    }
+  else
+    {
+      lalr ();
+      bitsetv_free (goto_follows);
+    }
+  timevar_pop (TV_IELR_PHASE4);
+}
diff --git a/src/ielr.h b/src/ielr.h
new file mode 100644
index 0000000..7b22380
--- /dev/null
+++ b/src/ielr.h
@@ -0,0 +1,46 @@
+/* IELR main implementation.
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef IELR_H_
+# define IELR_H_
+
+#include <bitset.h>
+
+#include "state.h"
+
+/**
+ * \pre
+ *   - \c ::states is of size \c ::nstates and defines an LR(0) parser
+ *     for the users's grammar.
+ *   - \c ::ntokens is the number of tokens in the grammar.
+ * \post
+ *   - \c ::states is of size \c ::nstates (which might be greater than
+ *     <tt>::nstates \@pre</tt>) and defines the type of parser specified by
+ *     the value of the \c \%define variable \c lr.type.  Its value can be:
+ *     - \c "lalr".
+ *     - \c "ielr".
+ *     - \c "canonical-lr".
+ */
+void ielr (void);
+
+bool ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
+                              symbol_number lookahead, state ***predecessors,
+                              bitset **item_lookahead_sets);
+
+#endif /* !IELR_H_ */
diff --git a/src/lalr.c b/src/lalr.c
index 65c55ab..9866154 100644
--- a/src/lalr.c
+++ b/src/lalr.c
@@ -1,28 +1,25 @@
-/* Compute look-ahead criteria for Bison.
+/* Compute lookahead criteria for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 2000-2012 Free Software Foundation,
+   Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-/* Compute how to make the finite state machine deterministic; find
-   which rules need look-ahead in each state, and which look-ahead
+/* Find which rules need lookahead in each state, and which lookahead
    tokens they accept.  */
 
 #include <config.h>
@@ -30,7 +27,6 @@
 
 #include <bitset.h>
 #include <bitsetv.h>
-#include <quotearg.h>
 
 #include "LR0.h"
 #include "complain.h"
@@ -38,15 +34,17 @@
 #include "getargs.h"
 #include "gram.h"
 #include "lalr.h"
+#include "muscle-tab.h"
 #include "nullable.h"
 #include "reader.h"
 #include "relation.h"
 #include "symtab.h"
 
 goto_number *goto_map;
-static goto_number ngotos;
+goto_number ngotos;
 state_number *from_state;
 state_number *to_state;
+bitsetv goto_follows = NULL;
 
 /* Linked list of goto numbers.  */
 typedef struct goto_list
@@ -56,7 +54,7 @@
 } goto_list;
 
 
-/* LA is a LR by NTOKENS matrix of bits.  LA[l, i] is 1 if the rule
+/* LA is an NLA by NTOKENS matrix of bits.  LA[l, i] is 1 if the rule
    LArule[l] is applicable in the appropriate state when the next
    token is symbol i.  If LA[l, i] and LA[l, j] are both 1 for i != j,
    it is a conflict.  */
@@ -65,17 +63,13 @@
 size_t nLA;
 
 
-/* And for the famous F variable, which name is so descriptive that a
-   comment is hardly needed.  <grin>.  */
-static bitsetv F = NULL;
-
 static goto_number **includes;
 static goto_list **lookback;
 
 
 
 
-static void
+void
 set_goto_map (void)
 {
   state_number s;
@@ -94,7 +88,7 @@
 	  ngotos++;
 
 	  /* Abort if (ngotos + 1) would overflow.  */
-	  assert (ngotos != GOTO_NUMBER_MAXIMUM);
+	  aver (ngotos != GOTO_NUMBER_MAXIMUM);
 
 	  goto_map[TRANSITION_SYMBOL (sp, i) - ntokens]++;
 	}
@@ -135,12 +129,7 @@
 }
 
 
-
-/*----------------------------------------------------------.
-| Map a state/symbol pair into its numeric representation.  |
-`----------------------------------------------------------*/
-
-static goto_number
+goto_number
 map_goto (state_number s0, symbol_number sym)
 {
   goto_number high;
@@ -153,7 +142,7 @@
 
   for (;;)
     {
-      assert (low <= high);
+      aver (low <= high);
       middle = (low + high) / 2;
       s = from_state[middle];
       if (s == s0)
@@ -175,7 +164,7 @@
 
   goto_number i;
 
-  F = bitsetv_create (ngotos, ntokens, BITSET_FIXED);
+  goto_follows = bitsetv_create (ngotos, ntokens, BITSET_FIXED);
 
   for (i = 0; i < ngotos; i++)
     {
@@ -184,7 +173,7 @@
 
       int j;
       FOR_EACH_SHIFT (sp, j)
-	bitset_set (F[i], TRANSITION_SYMBOL (sp, j));
+	bitset_set (goto_follows[i], TRANSITION_SYMBOL (sp, j));
 
       for (; j < sp->num; j++)
 	{
@@ -204,7 +193,7 @@
 	}
     }
 
-  relation_digraph (reads, ngotos, &F);
+  relation_digraph (reads, ngotos, &goto_follows);
 
   for (i = 0; i < ngotos; i++)
     free (reads[i]);
@@ -219,9 +208,9 @@
 {
   int ri = state_reduction_find (s, r);
   goto_list *sp = xmalloc (sizeof *sp);
-  sp->next = lookback[(s->reductions->look_ahead_tokens - LA) + ri];
+  sp->next = lookback[(s->reductions->lookahead_tokens - LA) + ri];
   sp->value = gotono;
-  lookback[(s->reductions->look_ahead_tokens - LA) + ri] = sp;
+  lookback[(s->reductions->lookahead_tokens - LA) + ri] = sp;
 }
 
 
@@ -264,8 +253,8 @@
 	  while (!done)
 	    {
 	      done = true;
-	      /* Each rhs ends in an item number, and there is a
-		 sentinel before the first rhs, so it is safe to
+	      /* Each rhs ends in a rule number, and there is a
+		 sentinel (ritem[-1]=0) before the first rhs, so it is safe to
 		 decrement RP here.  */
 	      rp--;
 	      if (ISVAR (*rp))
@@ -304,7 +293,7 @@
 {
   goto_number i;
 
-  relation_digraph (includes, ngotos, &F);
+  relation_digraph (includes, ngotos, &goto_follows);
 
   for (i = 0; i < ngotos; i++)
     free (includes[i]);
@@ -314,128 +303,142 @@
 
 
 static void
-compute_look_ahead_tokens (void)
+compute_lookahead_tokens (void)
 {
   size_t i;
   goto_list *sp;
 
   for (i = 0; i < nLA; i++)
     for (sp = lookback[i]; sp; sp = sp->next)
-      bitset_or (LA[i], LA[i], F[sp->value]);
+      bitset_or (LA[i], LA[i], goto_follows[sp->value]);
 
   /* Free LOOKBACK. */
   for (i = 0; i < nLA; i++)
     LIST_FREE (goto_list, lookback[i]);
 
   free (lookback);
-  bitsetv_free (F);
 }
 
 
-/*-----------------------------------------------------.
-| Count the number of look-ahead tokens required for S |
-| (N_LOOK_AHEAD_TOKENS member).                        |
-`-----------------------------------------------------*/
+/*----------------------------------------------------.
+| Count the number of lookahead tokens required for S |
+| (N_LOOKAHEAD_TOKENS member).                        |
+`----------------------------------------------------*/
 
 static int
-state_look_ahead_tokens_count (state *s)
+state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
 {
-  int k;
-  int n_look_ahead_tokens = 0;
+  int n_lookahead_tokens = 0;
   reductions *rp = s->reductions;
   transitions *sp = s->transitions;
 
-  /* We need a look-ahead either to distinguish different
-     reductions (i.e., there are two or more), or to distinguish a
-     reduction from a shift.  Otherwise, it is straightforward,
-     and the state is `consistent'.  */
+  /* Transitions are only disabled during conflict resolution, and that
+     hasn't happened yet, so there should be no need to check that
+     transition 0 hasn't been disabled before checking if it is a shift.
+     However, this check was performed at one time, so we leave it as an
+     aver.  */
+  aver (sp->num == 0 || !TRANSITION_IS_DISABLED (sp, 0));
+
+  /* We need a lookahead either to distinguish different reductions
+     (i.e., there are two or more), or to distinguish a reduction from a
+     shift.  Otherwise, it is straightforward, and the state is
+     `consistent'.  However, do not treat a state with any reductions as
+     consistent unless it is the accepting state (because there is never
+     a lookahead token that makes sense there, and so no lookahead token
+     should be read) if the user has otherwise disabled default
+     reductions.  */
   if (rp->num > 1
-      || (rp->num == 1 && sp->num &&
-	  !TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0)))
-    n_look_ahead_tokens += rp->num;
+      || (rp->num == 1 && sp->num && TRANSITION_IS_SHIFT (sp, 0))
+      || (rp->num == 1 && rp->rules[0]->number != 0
+          && default_reduction_only_for_accept))
+    n_lookahead_tokens += rp->num;
   else
     s->consistent = 1;
 
-  for (k = 0; k < sp->num; k++)
-    if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k))
-      {
-	s->consistent = 0;
-	break;
-      }
-
-  return n_look_ahead_tokens;
+  return n_lookahead_tokens;
 }
 
 
-/*-----------------------------------------------------.
-| Compute LA, NLA, and the look_ahead_tokens members.  |
-`-----------------------------------------------------*/
+/*----------------------------------------------------.
+| Compute LA, NLA, and the lookahead_tokens members.  |
+`----------------------------------------------------*/
 
-static void
+void
 initialize_LA (void)
 {
   state_number i;
   bitsetv pLA;
+  bool default_reduction_only_for_accept;
+  {
+    char *default_reductions =
+      muscle_percent_define_get ("lr.default-reductions");
+    default_reduction_only_for_accept =
+      0 == strcmp (default_reductions, "accepting");
+    free (default_reductions);
+  }
 
-  /* Compute the total number of reductions requiring a look-ahead.  */
+  /* Compute the total number of reductions requiring a lookahead.  */
   nLA = 0;
   for (i = 0; i < nstates; i++)
-    nLA += state_look_ahead_tokens_count (states[i]);
+    nLA +=
+      state_lookahead_tokens_count (states[i],
+                                    default_reduction_only_for_accept);
   /* Avoid having to special case 0.  */
   if (!nLA)
     nLA = 1;
 
   pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
-  lookback = xcalloc (nLA, sizeof *lookback);
 
-  /* Initialize the members LOOK_AHEAD_TOKENS for each state whose reductions
-     require look-ahead tokens.  */
+  /* Initialize the members LOOKAHEAD_TOKENS for each state whose reductions
+     require lookahead tokens.  */
   for (i = 0; i < nstates; i++)
     {
-      int count = state_look_ahead_tokens_count (states[i]);
+      int count =
+        state_lookahead_tokens_count (states[i],
+                                      default_reduction_only_for_accept);
       if (count)
 	{
-	  states[i]->reductions->look_ahead_tokens = pLA;
+	  states[i]->reductions->lookahead_tokens = pLA;
 	  pLA += count;
 	}
     }
 }
 
 
-/*----------------------------------------------.
-| Output the look-ahead tokens for each state.  |
-`----------------------------------------------*/
+/*---------------------------------------------.
+| Output the lookahead tokens for each state.  |
+`---------------------------------------------*/
 
 static void
-look_ahead_tokens_print (FILE *out)
+lookahead_tokens_print (FILE *out)
 {
   state_number i;
   int j, k;
-  fprintf (out, "Look-ahead tokens: BEGIN\n");
+  fprintf (out, "Lookahead tokens: BEGIN\n");
   for (i = 0; i < nstates; ++i)
     {
       reductions *reds = states[i]->reductions;
       bitset_iterator iter;
-      int n_look_ahead_tokens = 0;
+      int n_lookahead_tokens = 0;
 
-      if (reds->look_ahead_tokens)
+      if (reds->lookahead_tokens)
 	for (k = 0; k < reds->num; ++k)
-	  if (reds->look_ahead_tokens[k])
-	    ++n_look_ahead_tokens;
+	  if (reds->lookahead_tokens[k])
+	    ++n_lookahead_tokens;
 
-      fprintf (out, "State %d: %d look-ahead tokens\n",
-	       i, n_look_ahead_tokens);
+      fprintf (out, "State %d: %d lookahead tokens\n",
+	       i, n_lookahead_tokens);
 
-      if (reds->look_ahead_tokens)
+      if (reds->lookahead_tokens)
 	for (j = 0; j < reds->num; ++j)
-	  BITSET_FOR_EACH (iter, reds->look_ahead_tokens[j], k, 0)
+	  BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
 	  {
 	    fprintf (out, "   on %d (%s) -> rule %d\n",
 		     k, symbols[k]->tag,
 		     reds->rules[j]->number);
 	  };
     }
-  fprintf (out, "Look-ahead tokens: END\n");
+  fprintf (out, "Lookahead tokens: END\n");
 }
 
 void
@@ -444,12 +447,47 @@
   initialize_LA ();
   set_goto_map ();
   initialize_F ();
+  lookback = xcalloc (nLA, sizeof *lookback);
   build_relations ();
   compute_FOLLOWS ();
-  compute_look_ahead_tokens ();
+  compute_lookahead_tokens ();
 
   if (trace_flag & trace_sets)
-    look_ahead_tokens_print (stderr);
+    lookahead_tokens_print (stderr);
+}
+
+
+void
+lalr_update_state_numbers (state_number old_to_new[], state_number nstates_old)
+{
+  goto_number ngotos_reachable = 0;
+  symbol_number nonterminal = 0;
+  aver (nsyms == nvars + ntokens);
+  {
+    goto_number i;
+    for (i = 0; i < ngotos; ++i)
+      {
+        while (i == goto_map[nonterminal])
+          goto_map[nonterminal++] = ngotos_reachable;
+        /* If old_to_new[from_state[i]] = nstates_old, remove this goto
+           entry.  */
+        if (old_to_new[from_state[i]] != nstates_old)
+          {
+            /* from_state[i] is not removed, so it and thus to_state[i] are
+               reachable, so to_state[i] != nstates_old.  */
+            aver (old_to_new[to_state[i]] != nstates_old);
+            from_state[ngotos_reachable] = old_to_new[from_state[i]];
+            to_state[ngotos_reachable] = old_to_new[to_state[i]];
+            ++ngotos_reachable;
+          }
+      }
+  }
+  while (nonterminal <= nvars)
+    {
+      aver (ngotos == goto_map[nonterminal]);
+      goto_map[nonterminal++] = ngotos_reachable;
+    }
+  ngotos = ngotos_reachable;
 }
 
 
@@ -458,6 +496,6 @@
 {
   state_number s;
   for (s = 0; s < nstates; ++s)
-    states[s]->reductions->look_ahead_tokens = NULL;
+    states[s]->reductions->lookahead_tokens = NULL;
   bitsetv_free (LA);
 }
diff --git a/src/lalr.h b/src/lalr.h
index a2c1753..75e957e 100644
--- a/src/lalr.h
+++ b/src/lalr.h
@@ -1,24 +1,22 @@
-/* Compute look-ahead criteria for bison,
+/* Compute lookahead criteria for bison,
 
-   Copyright (C) 1984, 1986, 1989, 2000, 2002, 2004 Free Software
-   Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 2000, 2002, 2004, 2006-2007,
+   2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef LALR_H_
 # define LALR_H_
@@ -32,36 +30,77 @@
 /* Import the definition of CORE, TRANSITIONS and REDUCTIONS. */
 # include "state.h"
 
-/* Compute how to make the finite state machine deterministic; find
-   which rules need look-ahead in each state, and which look-ahead
-   tokens they accept.  */
 
+/** Build the LALR(1) automaton.
+
+   Find which rules need lookahead in each state, and which lookahead
+   tokens they accept.
+
+   Also builds:
+     - #goto_map
+     - #from_state
+     - #to_state
+     - #goto_follows
+*/
 void lalr (void);
 
-/* Release the information related to look-ahead tokens.  Can be performed
-   once the action tables are computed.  */
+/**
+ * Set #nLA and allocate all reduction lookahead sets.  Normally invoked by
+ * #lalr.
+ */
+void initialize_LA (void);
 
+/**
+ * Build only:
+ *   - #goto_map
+ *   - #from_state
+ *   - #to_state
+ * Normally invoked by #lalr.
+ */
+void set_goto_map (void);
+
+/**
+ * Update state numbers recorded in #goto_map, #from_state, and #to_state such
+ * that:
+ *   - \c nstates_old is the old number of states.
+ *   - Where \c i is the old state number, <tt>old_to_new[i]</tt> is either:
+ *     - \c nstates_old if state \c i is removed because it is unreachable.
+ *       Thus, remove all goto entries involving this state.
+ *     - The new state number.
+ */
+void lalr_update_state_numbers (state_number old_to_new[],
+                                state_number nstates_old);
+
+
+/** Release the information related to lookahead tokens.
+
+   Can be performed once the action tables are computed.  */
 void lalr_free (void);
 
-
-/* lalr() builds these data structures. */
-
-/* GOTO_MAP, FROM_STATE and TO_STATE -- record each shift transition
-   which accepts a variable (a nonterminal).
-
-   FROM_STATE[T] -- state number which a transition leads from.
-   TO_STATE[T] -- state number it leads to.
-
-   All the transitions that accept a particular variable are grouped
-   together and GOTO_MAP[I - NTOKENS] is the index in FROM_STATE and
-   TO_STATE of the first of them.  */
-
 typedef size_t goto_number;
 # define GOTO_NUMBER_MAXIMUM ((goto_number) -1)
 
+/** Index into #from_state and #to_state.
+
+   All the transitions that accept a particular variable are grouped
+   together and GOTO_MAP[I - NTOKENS] is the index in FROM_STATE and
+   TO_STATE of the first of them.  */
 extern goto_number *goto_map;
+
+/** The size of #from_state and #to_state.  */
+extern goto_number ngotos;
+
+/** State number which a transition leads from.  */
 extern state_number *from_state;
+
+/** State number it leads to.  */
 extern state_number *to_state;
 
+/** Map a state/symbol pair into its numeric representation.  */
+goto_number map_goto (state_number s0, symbol_number sym);
+
+/* goto_follows[i] is the set of tokens following goto i.  */
+extern bitsetv goto_follows;
+
 
 #endif /* !LALR_H_ */
diff --git a/src/location.c b/src/location.c
index ecd3658..24301ec 100644
--- a/src/location.c
+++ b/src/location.c
@@ -1,48 +1,230 @@
 /* Locations for Bison
 
-   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
+#include <mbswidth.h>
 #include <quotearg.h>
 
+#include "complain.h"
 #include "location.h"
 
-location const empty_location;
+location const empty_location = EMPTY_LOCATION_INIT;
+
+/* If BUF is null, add BUFSIZE (which in this case must be less than
+   INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
+   COLUMN.  If an overflow occurs, or might occur but is undetectable,
+   return INT_MAX.  Assume COLUMN is nonnegative.  */
+
+static inline int
+add_column_width (int column, char const *buf, size_t bufsize)
+{
+  size_t width;
+  unsigned int remaining_columns = INT_MAX - column;
+
+  if (buf)
+    {
+      if (INT_MAX / 2 <= bufsize)
+	return INT_MAX;
+      width = mbsnwidth (buf, bufsize, 0);
+    }
+  else
+    width = bufsize;
+
+  return width <= remaining_columns ? column + width : INT_MAX;
+}
+
+/* Set *LOC and adjust scanner cursor to account for token TOKEN of
+   size SIZE.  */
+
+void
+location_compute (location *loc, boundary *cur, char const *token, size_t size)
+{
+  int line = cur->line;
+  int column = cur->column;
+  char const *p0 = token;
+  char const *p = token;
+  char const *lim = token + size;
+
+  loc->start = *cur;
+
+  for (p = token; p < lim; p++)
+    switch (*p)
+      {
+      case '\n':
+	line += line < INT_MAX;
+	column = 1;
+	p0 = p + 1;
+	break;
+
+      case '\t':
+	column = add_column_width (column, p0, p - p0);
+	column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
+	p0 = p + 1;
+	break;
+
+      default:
+	break;
+      }
+
+  cur->line = line;
+  cur->column = column = add_column_width (column, p0, p - p0);
+
+  loc->end = *cur;
+
+  if (line == INT_MAX && loc->start.line != INT_MAX)
+    warn_at (*loc, _("line number overflow"));
+  if (column == INT_MAX && loc->start.column != INT_MAX)
+    warn_at (*loc, _("column number overflow"));
+}
+
 
 /* Output to OUT the location LOC.
    Warning: it uses quotearg's slot 3.  */
-void
+unsigned
 location_print (FILE *out, location loc)
 {
-  fprintf (out, "%s:%d.%d",
-	   quotearg_n_style (3, escape_quoting_style, loc.start.file),
-	   loc.start.line, loc.start.column);
-
+  unsigned res = 0;
+  int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
+  res += fprintf (out, "%s",
+                  quotearg_n_style (3, escape_quoting_style, loc.start.file));
+  if (0 <= loc.start.line)
+    {
+      res += fprintf (out, ":%d", loc.start.line);
+      if (0 <= loc.start.column)
+        res += fprintf (out, ".%d", loc.start.column);
+    }
   if (loc.start.file != loc.end.file)
-    fprintf (out, "-%s:%d.%d",
-	     quotearg_n_style (3, escape_quoting_style, loc.end.file),
-	     loc.end.line, loc.end.column - 1);
-  else if (loc.start.line < loc.end.line)
-    fprintf (out, "-%d.%d", loc.end.line, loc.end.column - 1);
-  else if (loc.start.column < loc.end.column - 1)
-    fprintf (out, "-%d", loc.end.column - 1);
+    {
+      res += fprintf (out, "-%s",
+                      quotearg_n_style (3, escape_quoting_style,
+                                        loc.end.file));
+      if (0 <= loc.end.line)
+        {
+          res += fprintf (out, ":%d", loc.end.line);
+          if (0 <= end_col)
+            res += fprintf (out, ".%d", end_col);
+        }
+    }
+  else if (0 <= loc.end.line)
+    {
+      if (loc.start.line < loc.end.line)
+        {
+          res += fprintf (out, "-%d", loc.end.line);
+          if (0 <= end_col)
+            res += fprintf (out, ".%d", end_col);
+        }
+      else if (0 <= end_col && loc.start.column < end_col)
+        res += fprintf (out, "-%d", end_col);
+    }
+
+  return res;
+}
+
+
+/* Persistant data used by location_caret to avoid reopening and rereading the
+   same file all over for each error.  */
+struct caret_info
+{
+  FILE *source;
+  size_t line;
+  size_t offset;
+};
+
+static struct caret_info caret_info = { NULL, 1, 0 };
+
+void
+cleanup_caret ()
+{
+  if (caret_info.source)
+    fclose (caret_info.source);
+}
+
+void
+location_caret (FILE *out, location loc)
+{
+  /* FIXME: find a way to support multifile locations, and only open once each
+     file. That would make the procedure future-proof.  */
+  if (! (caret_info.source
+         || (caret_info.source = fopen (loc.start.file, "r")))
+      || loc.start.column == -1 || loc.start.line == -1)
+    return;
+
+  /* If the line we want to quote is seekable (the same line as the previous
+     location), just seek it. If it was before, we lost track of it, so
+     return to the start of file.  */
+  if (caret_info.line <= loc.start.line)
+    fseek (caret_info.source, caret_info.offset, SEEK_SET);
+  else
+    {
+      caret_info.line = 1;
+      caret_info.offset = 0;
+      fseek (caret_info.source, caret_info.offset, SEEK_SET);
+    }
+
+  /* Advance to the line's position, keeping track of the offset.  */
+  while (caret_info.line < loc.start.line)
+    caret_info.line += fgetc (caret_info.source) == '\n';
+  caret_info.offset = ftell (caret_info.source);
+
+  /* Read the actual line.  Don't update the offset, so that we keep a pointer
+     to the start of the line.  */
+  {
+    char *buf = NULL;
+    size_t size = 0;
+    ssize_t len = getline (&buf, &size, caret_info.source);
+    if (0 < len)
+      {
+        /* The caret of a multiline location ends with the first line.  */
+        int end = loc.start.line != loc.end.line ? len : loc.end.column;
+
+        /* Quote the file, indent by a single column.  */
+        fputc (' ', out);
+        fwrite (buf, 1, len, out);
+
+        /* Print the caret, with the same indent as above.  */
+        fprintf (out, " %*s", loc.start.column - 1, "");
+        {
+          int i = loc.start.column;
+          do
+            fputc ('^', out);
+          while (++i < end);
+        }
+        fputc ('\n', out);
+      }
+    free (buf);
+  }
+}
+
+void
+boundary_set_from_string (boundary *bound, char *loc_str)
+{
+  /* Must search in reverse since the file name field may
+   * contain `.' or `:'.  */
+  char *delim = mbsrchr (loc_str, '.');
+  aver (delim);
+  *delim = '\0';
+  bound->column = atoi (delim+1);
+  delim = mbsrchr (loc_str, ':');
+  aver (delim);
+  *delim = '\0';
+  bound->line = atoi (delim+1);
+  bound->file = uniqstr_new (loc_str);
 }
diff --git a/src/location.h b/src/location.h
index 49d2a2e..c1859ae 100644
--- a/src/location.h
+++ b/src/location.h
@@ -1,22 +1,21 @@
 /* Locations for Bison
-   Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+   Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef LOCATION_H_
 # define LOCATION_H_
@@ -29,17 +28,46 @@
   /* The name of the file that contains the boundary.  */
   uniqstr file;
 
-  /* The (origin-1) line that contains the boundary.
-     If this is INT_MAX, the line number has overflowed.  */
+  /* If nonnegative, the (origin-1) line that contains the boundary.
+     If this is INT_MAX, the line number has overflowed.
+
+     Meaningless and not displayed if negative.
+  */
   int line;
 
-  /* The (origin-1) column just after the boundary.  This is neither a
-     byte count, nor a character count; it is a column count.
-     If this is INT_MAX, the column number has overflowed.  */
+  /* If nonnegative, the (origin-1) column just after the boundary.
+     This is neither a byte count, nor a character count; it is a
+     column count.  If this is INT_MAX, the column number has
+     overflowed.
+
+     Meaningless and not displayed if negative.
+  */
   int column;
 
 } boundary;
 
+/* Set the position of \a a. */
+static inline void
+boundary_set (boundary *b, const char *f, int l, int c)
+{
+  b->file = f;
+  b->line = l;
+  b->column = c;
+}
+
+/* Return -1, 0, 1, depending whether a is before, equal, or
+   after b.  */
+static inline int
+boundary_cmp (boundary a, boundary b)
+{
+  int res = strcmp (a.file, b.file);
+  if (!res)
+    res = a.line - b.line;
+  if (!res)
+    res = a.column - b.column;
+  return res;
+}
+
 /* Return nonzero if A and B are equal boundaries.  */
 static inline bool
 equal_boundaries (boundary a, boundary b)
@@ -60,10 +88,39 @@
 
 } location;
 
-#define YYLTYPE location
+#define GRAM_LTYPE location
 
+#define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
 extern location const empty_location;
 
-void location_print (FILE *out, location loc);
+/* Set *LOC and adjust scanner cursor to account for token TOKEN of
+   size SIZE.  */
+void location_compute (location *loc,
+		       boundary *cur, char const *token, size_t size);
+
+/* Print location to file. Return number of actually printed
+   characters.  */
+unsigned location_print (FILE *out, location loc);
+
+/* Free any allocated ressources and close any open file handles that are
+   left-over by the usage of location_caret.  */
+void cleanup_caret (void);
+
+/* Output to OUT the line and caret corresponding to location LOC.  */
+void location_caret (FILE *out, location loc);
+
+/* Return -1, 0, 1, depending whether a is before, equal, or
+   after b.  */
+static inline int
+location_cmp (location a, location b)
+{
+  int res = boundary_cmp (a.start, b.start);
+  if (!res)
+    res = boundary_cmp (a.end, b.end);
+  return res;
+}
+
+/* LOC_STR must be formatted as `file:line.column', it will be modified.  */
+void boundary_set_from_string (boundary *bound, char *loc_str);
 
 #endif /* ! defined LOCATION_H_ */
diff --git a/src/main.c b/src/main.c
index 8769fef..184d789 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,33 +1,35 @@
 /* Top level entry point of Bison.
 
-   Copyright (C) 1984, 1986, 1989, 1992, 1995, 2000, 2001, 2002, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 1995, 2000-2002, 2004-2012 Free
+   Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
 #include <bitset_stats.h>
 #include <bitset.h>
+#include <configmake.h>
+#include <progname.h>
+#include <quotearg.h>
 #include <timevar.h>
 
 #include "LR0.h"
+#include "closeout.h"
 #include "complain.h"
 #include "conflicts.h"
 #include "derives.h"
@@ -35,32 +37,45 @@
 #include "getargs.h"
 #include "gram.h"
 #include "lalr.h"
-#include "muscle_tab.h"
+#include "ielr.h"
+#include "muscle-tab.h"
 #include "nullable.h"
 #include "output.h"
 #include "print.h"
 #include "print_graph.h"
+#include "print-xml.h"
+#include <quote.h>
 #include "reader.h"
 #include "reduce.h"
+#include "scan-code.h"
+#include "scan-gram.h"
+#include "scan-skel.h"
 #include "symtab.h"
 #include "tables.h"
 #include "uniqstr.h"
 
-/* The name this program was run with, for messages.  */
-char *program_name;
-
-
 
 int
 main (int argc, char *argv[])
 {
-  program_name = argv[0];
+  set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   (void) bindtextdomain (PACKAGE, LOCALEDIR);
   (void) bindtextdomain ("bison-runtime", LOCALEDIR);
   (void) textdomain (PACKAGE);
 
+  {
+    char const *cp = getenv ("LC_CTYPE");
+    if (cp && !strcmp (cp, "C"))
+      set_custom_quoting (&quote_quoting_options, "'", "'");
+    else
+      set_quoting_style (&quote_quoting_options, locale_quoting_style);
+  }
+
+  atexit (close_stdout);
+
   uniqstrs_new ();
+  muscle_init ();
 
   getargs (argc, argv);
 
@@ -71,8 +86,6 @@
   if (trace_flag & trace_bitsets)
     bitset_stats_enable ();
 
-  muscle_init ();
-
   /* Read the input.  Copy some parts of it to FGUARD, FACTION, FTABLE
      and FATTRS.  In file reader.c.  The other parts are recorded in
      the grammar; see gram.h.  */
@@ -96,23 +109,31 @@
   nullable_compute ();
   timevar_pop (TV_SETS);
 
-  /* Convert to nondeterministic finite state machine.  In file LR0.
-     See state.h for more info.  */
+  /* Compute LR(0) parser states.  See state.h for more info.  */
   timevar_push (TV_LR0);
   generate_states ();
   timevar_pop (TV_LR0);
 
-  /* make it deterministic.  In file lalr.  */
-  timevar_push (TV_LALR);
-  lalr ();
-  timevar_pop (TV_LALR);
+  /* Add lookahead sets to parser states.  Except when LALR(1) is
+     requested, split states to eliminate LR(1)-relative
+     inadequacies.  */
+  ielr ();
 
   /* Find and record any conflicts: places where one token of
-     look-ahead is not enough to disambiguate the parsing.  In file
+     lookahead is not enough to disambiguate the parsing.  In file
      conflicts.  Also resolve s/r conflicts based on precedence
      declarations.  */
   timevar_push (TV_CONFLICTS);
   conflicts_solve ();
+  if (!muscle_percent_define_flag_if ("lr.keep-unreachable-states"))
+    {
+      state_number *old_to_new = xnmalloc (nstates, sizeof *old_to_new);
+      state_number nstates_old = nstates;
+      state_remove_unreachable_states (old_to_new);
+      lalr_update_state_numbers (old_to_new, nstates_old);
+      conflicts_update_state_numbers (old_to_new, nstates_old);
+      free (old_to_new);
+    }
   conflicts_print ();
   timevar_pop (TV_CONFLICTS);
 
@@ -121,8 +142,8 @@
   tables_generate ();
   timevar_pop (TV_ACTIONS);
 
-  grammar_rules_never_reduced_report
-    (_("rule never reduced because of conflicts"));
+  grammar_rules_useless_report
+    (_("rule useless in parser due to conflicts"));
 
   /* Output file names. */
   compute_output_file_names ();
@@ -135,7 +156,7 @@
       timevar_pop (TV_REPORT);
     }
 
-  /* Output the VCG graph.  */
+  /* Output the graph.  */
   if (graph_flag)
     {
       timevar_push (TV_GRAPH);
@@ -143,12 +164,20 @@
       timevar_pop (TV_GRAPH);
     }
 
+  /* Output xml.  */
+  if (xml_flag)
+    {
+      timevar_push (TV_XML);
+      print_xml ();
+      timevar_pop (TV_XML);
+    }
+
   /* Stop if there were errors, to avoid trashing previous output
      files.  */
   if (complaint_issued)
     goto finish;
 
-  /* Look-ahead tokens are no longer needed. */
+  /* Lookahead tokens are no longer needed. */
   timevar_push (TV_FREE);
   lalr_free ();
   timevar_pop (TV_FREE);
@@ -166,12 +195,16 @@
   reduce_free ();
   conflicts_free ();
   grammar_free ();
+  output_file_names_free ();
 
   /* The scanner memory cannot be released right after parsing, as it
      contains things such as user actions, prologue, epilogue etc.  */
-  scanner_free ();
+  gram_scanner_free ();
   muscle_free ();
   uniqstrs_free ();
+  code_scanner_free ();
+  skel_scanner_free ();
+  quotearg_free ();
   timevar_pop (TV_FREE);
 
   if (trace_flag & trace_bitsets)
@@ -183,5 +216,7 @@
   timevar_stop (TV_TOTAL);
   timevar_print (stderr);
 
+  cleanup_caret ();
+
   return complaint_issued ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
new file mode 100644
index 0000000..936af70
--- /dev/null
+++ b/src/muscle-tab.c
@@ -0,0 +1,669 @@
+/* Muscle table manager for Bison.
+
+   Copyright (C) 2001-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include <hash.h>
+
+#include "complain.h"
+#include "files.h"
+#include "getargs.h"
+#include "muscle-tab.h"
+#include "quote.h"
+
+/* A key-value pair, along with storage that can be reclaimed when
+   this pair is no longer needed.  */
+typedef struct
+{
+  char const *key;
+  char const *value;
+  char *storage;
+} muscle_entry;
+
+/* An obstack used to create some entries.  */
+struct obstack muscle_obstack;
+
+/* Initial capacity of muscles hash table.  */
+#define HT_INITIAL_CAPACITY 257
+
+static struct hash_table *muscle_table = NULL;
+
+static bool
+hash_compare_muscles (void const *x, void const *y)
+{
+  muscle_entry const *m1 = x;
+  muscle_entry const *m2 = y;
+  return strcmp (m1->key, m2->key) == 0;
+}
+
+static size_t
+hash_muscle (const void *x, size_t tablesize)
+{
+  muscle_entry const *m = x;
+  return hash_string (m->key, tablesize);
+}
+
+/*-----------------------------------------------------------------.
+| Create the MUSCLE_TABLE, and initialize it with default values.  |
+| Also set up the MUSCLE_OBSTACK.                                  |
+`-----------------------------------------------------------------*/
+
+static void
+muscle_entry_free (void *entry)
+{
+  muscle_entry *mentry = entry;
+  free (mentry->storage);
+  free (mentry);
+}
+
+void
+muscle_init (void)
+{
+  /* Initialize the muscle obstack.  */
+  obstack_init (&muscle_obstack);
+
+  muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
+				  hash_compare_muscles, muscle_entry_free);
+
+  /* Version and input file.  */
+  MUSCLE_INSERT_STRING ("version", VERSION);
+}
+
+
+/*------------------------------------------------------------.
+| Free all the memory consumed by the muscle machinery only.  |
+`------------------------------------------------------------*/
+
+void
+muscle_free (void)
+{
+  hash_free (muscle_table);
+  obstack_free (&muscle_obstack, NULL);
+}
+
+
+
+/*------------------------------------------------------------.
+| Insert (KEY, VALUE).  If KEY already existed, overwrite the |
+| previous value.                                             |
+`------------------------------------------------------------*/
+
+void
+muscle_insert (char const *key, char const *value)
+{
+  muscle_entry probe;
+  muscle_entry *entry;
+
+  probe.key = key;
+  entry = hash_lookup (muscle_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      entry = xmalloc (sizeof *entry);
+      entry->key = key;
+      if (!hash_insert (muscle_table, entry))
+        xalloc_die ();
+    }
+  else
+    free (entry->storage);
+  entry->value = value;
+  entry->storage = NULL;
+}
+
+
+/*-------------------------------------------------------------------.
+| Append VALUE to the current value of KEY.  If KEY did not already  |
+| exist, create it.  Use MUSCLE_OBSTACK.  De-allocate the previously |
+| associated value.  Copy VALUE and SEPARATOR.                       |
+`-------------------------------------------------------------------*/
+
+void
+muscle_grow (const char *key, const char *val, const char *separator)
+{
+  muscle_entry probe;
+  muscle_entry *entry = NULL;
+
+  probe.key = key;
+  entry = hash_lookup (muscle_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      entry = xmalloc (sizeof *entry);
+      entry->key = key;
+      if (!hash_insert (muscle_table, entry))
+        xalloc_die ();
+      entry->value = entry->storage = xstrdup (val);
+    }
+  else
+    {
+      /* Grow the current value. */
+      char *new_val;
+      obstack_sgrow (&muscle_obstack, entry->value);
+      free (entry->storage);
+      obstack_sgrow (&muscle_obstack, separator);
+      obstack_sgrow (&muscle_obstack, val);
+      obstack_1grow (&muscle_obstack, 0);
+      new_val = obstack_finish (&muscle_obstack);
+      entry->value = entry->storage = xstrdup (new_val);
+      obstack_free (&muscle_obstack, new_val);
+    }
+}
+
+/*------------------------------------------------------------------.
+| Using muscle_grow, append a synchronization line for the location |
+| LOC to the current value of KEY.                                  |
+`------------------------------------------------------------------*/
+
+static void
+muscle_syncline_grow (char const *key, location loc)
+{
+  char *extension = NULL;
+  obstack_printf (&muscle_obstack, "]b4_syncline(%d, ", loc.start.line);
+  obstack_quote (&muscle_obstack,
+                 quotearg_style (c_quoting_style, loc.start.file));
+  obstack_sgrow (&muscle_obstack, ")[");
+  obstack_1grow (&muscle_obstack, 0);
+  extension = obstack_finish (&muscle_obstack);
+  muscle_grow (key, extension, "");
+  obstack_free (&muscle_obstack, extension);
+}
+
+/*------------------------------------------------------------------.
+| Append VALUE to the current value of KEY, using muscle_grow.  But |
+| in addition, issue a synchronization line for the location LOC    |
+| using muscle_syncline_grow.                                       |
+`------------------------------------------------------------------*/
+
+void
+muscle_code_grow (const char *key, const char *val, location loc)
+{
+  muscle_syncline_grow (key, loc);
+  muscle_grow (key, val, "\n");
+}
+
+
+void muscle_pair_list_grow (const char *muscle,
+			    const char *a1, const char *a2)
+{
+  char *pair;
+  obstack_sgrow (&muscle_obstack, "[");
+  obstack_quote (&muscle_obstack, a1);
+  obstack_sgrow (&muscle_obstack, ", ");
+  obstack_quote (&muscle_obstack, a2);
+  obstack_sgrow (&muscle_obstack, "]");
+  obstack_1grow (&muscle_obstack, 0);
+  pair = obstack_finish (&muscle_obstack);
+  muscle_grow (muscle, pair, ",\n");
+  obstack_free (&muscle_obstack, pair);
+}
+
+
+/*----------------------------------------------------------------------------.
+| Find the value of muscle KEY.  Unlike MUSCLE_FIND, this is always reliable  |
+| to determine whether KEY has a value.                                       |
+`----------------------------------------------------------------------------*/
+
+char const *
+muscle_find_const (char const *key)
+{
+  muscle_entry probe;
+  muscle_entry *result = NULL;
+
+  probe.key = key;
+  result = hash_lookup (muscle_table, &probe);
+  if (result)
+    return result->value;
+  return NULL;
+}
+
+
+/*----------------------------------------------------------------------------.
+| Find the value of muscle KEY.  Abort if muscle_insert was invoked more      |
+| recently than muscle_grow for KEY since muscle_find can't return a          |
+| char const *.                                                               |
+`----------------------------------------------------------------------------*/
+
+char *
+muscle_find (char const *key)
+{
+  muscle_entry probe;
+  muscle_entry *result = NULL;
+
+  probe.key = key;
+  result = hash_lookup (muscle_table, &probe);
+  if (result)
+    {
+      aver (result->value == result->storage);
+      return result->storage;
+    }
+  return NULL;
+}
+
+
+/* In the format `file_name:line.column', append BOUND to MUSCLE.  Use
+   digraphs for special characters in the file name.  */
+
+static void
+muscle_boundary_grow (char const *key, boundary bound)
+{
+  char *extension;
+  obstack_sgrow  (&muscle_obstack, "[[");
+  obstack_escape (&muscle_obstack, bound.file);
+  obstack_1grow  (&muscle_obstack, ':');
+  obstack_printf (&muscle_obstack, "%d", bound.line);
+  obstack_1grow  (&muscle_obstack, '.');
+  obstack_printf (&muscle_obstack, "%d", bound.column);
+  obstack_sgrow  (&muscle_obstack, "]]");
+  obstack_1grow  (&muscle_obstack, '\0');
+  extension = obstack_finish (&muscle_obstack);
+  muscle_grow (key, extension, "");
+  obstack_free (&muscle_obstack, extension);
+}
+
+
+/* In the format `[[file_name:line.column]], [[file_name:line.column]]',
+   append LOC to MUSCLE.  Use digraphs for special characters in each
+   file name.  */
+
+static void
+muscle_location_grow (char const *key, location loc)
+{
+  muscle_boundary_grow (key, loc.start);
+  muscle_grow (key, "", ", ");
+  muscle_boundary_grow (key, loc.end);
+}
+
+#define COMMON_DECODE(Value)                                    \
+  case '$':                                                     \
+    aver (*++(Value) == ']');                                   \
+    aver (*++(Value) == '[');                                   \
+    obstack_sgrow (&muscle_obstack, "$");                       \
+    break;                                                      \
+  case '@':                                                     \
+    switch (*++(Value))                                         \
+      {                                                         \
+        case '@': obstack_sgrow (&muscle_obstack, "@" ); break; \
+        case '{': obstack_sgrow (&muscle_obstack, "[" ); break; \
+        case '}': obstack_sgrow (&muscle_obstack, "]" ); break; \
+        default: aver (false); break;                           \
+      }                                                         \
+    break;                                                      \
+  default:                                                      \
+    obstack_1grow (&muscle_obstack, *(Value));                  \
+    break;
+
+/* Reverse of obstack_escape.  */
+static char *
+string_decode (char const *key)
+{
+  char const *value;
+  char *value_decoded;
+  char *result;
+
+  value = muscle_find_const (key);
+  if (!value)
+    return NULL;
+  do {
+    switch (*value)
+      {
+        COMMON_DECODE (value)
+        case '[':
+        case ']':
+          aver (false);
+          break;
+      }
+  } while (*value++);
+  value_decoded = obstack_finish (&muscle_obstack);
+  result = xstrdup (value_decoded);
+  obstack_free (&muscle_obstack, value_decoded);
+  return result;
+}
+
+/* Reverse of muscle_location_grow.  */
+static location
+location_decode (char const *key)
+{
+  location loc;
+  char const *value = muscle_find_const (key);
+  aver (value);
+  aver (*value == '[');
+  aver (*++value == '[');
+  while (*++value)
+    switch (*value)
+      {
+        COMMON_DECODE (value)
+        case '[':
+          aver (false);
+          break;
+        case ']':
+          {
+            char *boundary_str;
+            aver (*++value == ']');
+            obstack_1grow (&muscle_obstack, '\0');
+            boundary_str = obstack_finish (&muscle_obstack);
+            switch (*++value)
+              {
+                case ',':
+                  boundary_set_from_string (&loc.start, boundary_str);
+                  obstack_free (&muscle_obstack, boundary_str);
+                  aver (*++value == ' ');
+                  aver (*++value == '[');
+                  aver (*++value == '[');
+                  break;
+                case '\0':
+                  boundary_set_from_string (&loc.end, boundary_str);
+                  obstack_free (&muscle_obstack, boundary_str);
+                  return loc;
+                  break;
+                default:
+                  aver (false);
+                  break;
+              }
+          }
+          break;
+      }
+  aver (false);
+  return loc;
+}
+
+void
+muscle_user_name_list_grow (char const *key, char const *user_name,
+                            location loc)
+{
+  muscle_grow (key, "[[[[", ",");
+  muscle_grow (key, user_name, "");
+  muscle_grow (key, "]], ", "");
+  muscle_location_grow (key, loc);
+  muscle_grow (key, "]]", "");
+}
+
+/** If the \a variable name is obsolete, return the name to use,
+ * otherwise \a variable. */
+static
+char const *
+muscle_percent_variable_update (char const *variable)
+{
+  typedef struct
+  {
+    const char *obsolete;
+    const char *updated;
+  } conversion_type;
+  const conversion_type conversion[] =
+    {
+      { "api.push_pull", "api.push-pull", },
+      { "location_type", "api.location.type", },
+      { "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
+    };
+  char const *res = variable;
+  int i;
+  for (i = 0; i < ARRAY_CARDINALITY (conversion); ++i)
+    if (STREQ (conversion[i].obsolete, variable))
+      {
+        res = conversion[i].updated;
+        break;
+      }
+  return res;
+}
+
+void
+muscle_percent_define_insert (char const *var, location variable_loc,
+                              char const *value,
+                              muscle_percent_define_how how)
+{
+  /* Backward compatibility.  */
+  char const *variable = muscle_percent_variable_update (var);
+  char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+  char const *syncline_name =
+    UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
+  char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
+
+  /* Command-line options are processed before the grammar file.  */
+  if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
+      && muscle_find_const (name))
+    {
+      unsigned i = 0;
+      muscle_percent_define_how how_old =
+        atoi (muscle_find_const (how_name));
+      if (how_old == MUSCLE_PERCENT_DEFINE_F)
+        return;
+      complain_at_indent (variable_loc, &i,
+                          _("%%define variable %s redefined"), quote (variable));
+      i += SUB_INDENT;
+      complain_at_indent (muscle_percent_define_get_loc (variable), &i,
+                          _("previous definition"));
+    }
+
+  MUSCLE_INSERT_STRING (name, value);
+  muscle_insert (loc_name, "");
+  muscle_location_grow (loc_name, variable_loc);
+  muscle_insert (syncline_name, "");
+  muscle_syncline_grow (syncline_name, variable_loc);
+  muscle_user_name_list_grow ("percent_define_user_variables", variable,
+                              variable_loc);
+  MUSCLE_INSERT_INT (how_name, how);
+}
+
+char *
+muscle_percent_define_get (char const *variable)
+{
+  char const *name;
+  char const *usage_name;
+  char *value;
+
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  usage_name = UNIQSTR_CONCAT ("percent_define_bison_variables(",
+                               variable, ")");
+
+  muscle_insert (usage_name, "");
+  value = string_decode (name);
+  if (!value)
+    value = xstrdup ("");
+  return value;
+}
+
+location
+muscle_percent_define_get_loc (char const *variable)
+{
+  char const *loc_name;
+  loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+  if (!muscle_find_const (loc_name))
+    fatal(_("%s: undefined %%define variable %s"),
+          "muscle_percent_define_get_loc", quote (variable));
+  return location_decode (loc_name);
+}
+
+char const *
+muscle_percent_define_get_syncline (char const *variable)
+{
+  char const *syncline_name;
+  char const *syncline;
+  syncline_name =
+    UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
+  syncline = muscle_find_const (syncline_name);
+  if (!syncline)
+    fatal(_("%s: undefined %%define variable %s"),
+          "muscle_percent_define_get_syncline", quote (variable));
+  return syncline;
+}
+
+bool
+muscle_percent_define_ifdef (char const *variable)
+{
+  char const *name;
+  char const *usage_name;
+  char const *value;
+
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  usage_name =
+    UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
+
+  value = muscle_find_const (name);
+  if (value)
+    {
+      muscle_insert (usage_name, "");
+      return true;
+    }
+
+  return false;
+}
+
+bool
+muscle_percent_define_flag_if (char const *variable)
+{
+  char const *invalid_boolean_name;
+  bool result = false;
+
+  invalid_boolean_name =
+    UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")");
+
+  if (muscle_percent_define_ifdef (variable))
+    {
+      char *value = muscle_percent_define_get (variable);
+      if (value[0] == '\0' || 0 == strcmp (value, "true"))
+        result = true;
+      else if (0 == strcmp (value, "false"))
+        result = false;
+      else if (!muscle_find_const (invalid_boolean_name))
+        {
+          muscle_insert (invalid_boolean_name, "");
+          complain_at(muscle_percent_define_get_loc (variable),
+                      _("invalid value for %%define Boolean variable %s"),
+                      quote (variable));
+        }
+      free (value);
+    }
+  else
+    fatal(_("%s: undefined %%define variable %s"),
+          "muscle_percent_define_flag", quote (variable));
+
+  return result;
+}
+
+void
+muscle_percent_define_default (char const *variable, char const *value)
+{
+  char const *name;
+  char const *loc_name;
+  char const *syncline_name;
+  name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+  loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+  syncline_name =
+    UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
+  if (!muscle_find_const (name))
+    {
+      location loc;
+      MUSCLE_INSERT_STRING (name, value);
+      loc.start.file = loc.end.file = "<default value>";
+      loc.start.line = loc.end.line = -1;
+      loc.start.column = loc.end.column = -1;
+      muscle_insert (loc_name, "");
+      muscle_location_grow (loc_name, loc);
+      muscle_insert (syncline_name, "");
+    }
+}
+
+void
+muscle_percent_define_check_values (char const * const *values)
+{
+  for (; *values; ++values)
+    {
+      char const * const *variablep = values;
+      char const *name;
+      char *value;
+
+      name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
+
+      value = string_decode (name);
+      if (value)
+        {
+          for (++values; *values; ++values)
+            {
+              if (0 == strcmp (value, *values))
+                break;
+            }
+          if (!*values)
+            {
+              unsigned i = 0;
+              location loc = muscle_percent_define_get_loc (*variablep);
+              complain_at_indent (loc, &i,
+                                _("invalid value for %%define variable %s: %s"),
+                                  quote (*variablep), quote_n (1, value));
+              i += SUB_INDENT;
+              for (values = variablep + 1; *values; ++values)
+                complain_at_indent (loc, &i, _("accepted value: %s"),
+                                    quote (*values));
+            }
+          else
+            {
+              while (*values)
+                ++values;
+            }
+          free (value);
+        }
+      else
+        fatal (_("%s: undefined %%define variable %s"),
+               "muscle_percent_define_check_values", quote (*variablep));
+    }
+}
+
+void
+muscle_percent_code_grow (char const *qualifier, location qualifier_loc,
+                          char const *code, location code_loc)
+{
+  char const *name;
+  name = UNIQSTR_CONCAT ("percent_code(", qualifier, ")");
+  muscle_code_grow (name, code, code_loc);
+  muscle_user_name_list_grow ("percent_code_user_qualifiers", qualifier,
+                               qualifier_loc);
+}
+
+
+/*------------------------------------------------.
+| Output the definition of ENTRY as a m4_define.  |
+`------------------------------------------------*/
+
+static inline bool
+muscle_m4_output (muscle_entry *entry, FILE *out)
+{
+  fprintf (out, "m4_define([b4_%s],\n", entry->key);
+  fprintf (out, "[[%s]])\n\n\n", entry->value);
+  return true;
+}
+
+static bool
+muscle_m4_output_processor (void *entry, void *out)
+{
+  return muscle_m4_output (entry, out);
+}
+
+
+/*----------------------------------------------------------------.
+| Output the definition of all the current muscles into a list of |
+| m4_defines.                                                     |
+`----------------------------------------------------------------*/
+
+void
+muscles_m4_output (FILE *out)
+{
+  hash_do_for_each (muscle_table, muscle_m4_output_processor, out);
+}
diff --git a/src/muscle-tab.h b/src/muscle-tab.h
new file mode 100644
index 0000000..696103f
--- /dev/null
+++ b/src/muscle-tab.h
@@ -0,0 +1,191 @@
+/* Muscle table manager for Bison,
+
+   Copyright (C) 2001-2003, 2006-2007, 2009-2012 Free Software
+   Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef MUSCLE_TAB_H_
+# define MUSCLE_TAB_H_
+
+# include <quotearg.h>
+
+# include "location.h"
+
+void muscle_init (void);
+void muscle_insert (char const *key, char const *value);
+char const *muscle_find_const (char const *key);
+char *muscle_find (char const *key);
+void muscle_free (void);
+
+
+/* An obstack dedicated to receive muscle keys and values.  */
+extern struct obstack muscle_obstack;
+
+#define MUSCLE_INSERT_BOOL(Key, Value)                          \
+  do {                                                          \
+    int v = Value;                                              \
+    MUSCLE_INSERT_INT (Key, v);                                 \
+  } while (0)
+
+#define MUSCLE_INSERT_INT(Key, Value)                           \
+  do {                                                          \
+    obstack_printf (&muscle_obstack, "%d", Value);              \
+    obstack_1grow (&muscle_obstack, 0);                         \
+    muscle_insert (Key, obstack_finish (&muscle_obstack));      \
+  } while (0)
+
+#define MUSCLE_INSERT_LONG_INT(Key, Value)                      \
+  do {                                                          \
+    obstack_printf (&muscle_obstack, "%ld", Value);             \
+    obstack_1grow (&muscle_obstack, 0);                         \
+    muscle_insert (Key, obstack_finish (&muscle_obstack));      \
+  } while (0)
+
+#define MUSCLE_INSERT_STRING_RAW(Key, Value)                    \
+  do {                                                          \
+    obstack_sgrow (&muscle_obstack, Value);                     \
+    obstack_1grow (&muscle_obstack, 0);                         \
+    muscle_insert (Key, obstack_finish (&muscle_obstack));      \
+  } while (0)
+
+#define MUSCLE_INSERT_STRING(Key, Value)                        \
+  do {                                                          \
+    obstack_escape (&muscle_obstack, Value);                    \
+    obstack_1grow (&muscle_obstack, 0);                         \
+    muscle_insert (Key, obstack_finish (&muscle_obstack));      \
+  } while (0)
+
+#define MUSCLE_INSERT_C_STRING(Key, Value)                      \
+  do {                                                          \
+    obstack_escape (&muscle_obstack,                            \
+                    quotearg_style (c_quoting_style, Value));   \
+    obstack_1grow (&muscle_obstack, 0);                         \
+    muscle_insert (Key, obstack_finish (&muscle_obstack));      \
+  } while (0)
+
+/* Append VALUE to the current value of KEY.  If KEY did not already
+   exist, create it.  Use MUSCLE_OBSTACK.  De-allocate the previously
+   associated value.  Copy VALUE and SEPARATOR.  */
+
+void muscle_grow (const char *key, const char *value, const char *separator);
+
+
+/* Append VALUE to the current value of KEY, using muscle_grow.  But
+   in addition, issue a synchronization line for the location LOC.  */
+
+void muscle_code_grow (const char *key, const char *value, location loc);
+
+
+/* MUSCLE is an M4 list of pairs.  Create or extend it with the pair
+   (A1, A2) after escaping both values with digraphs.  Note that because the
+   muscle values are output *double* quoted, one needs to strip the first level
+   of quotes to reach the list itself.  */
+void muscle_pair_list_grow (const char *muscle,
+                            const char *a1, const char *a2);
+
+/* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for
+   use with b4_check_user_names in ../data/bison.m4.  USER_NAME is not escaped
+   with digraphs, so it must not contain `[' or `]'.  */
+void muscle_user_name_list_grow (char const *key, char const *user_name,
+                                 location loc);
+
+/* Indicates whether a variable's value was specified with -D/--define, with
+   -F/--force-define, or in the grammar file.  */
+typedef enum {
+  MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F,
+  MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
+} muscle_percent_define_how;
+
+/* Define the muscles for %define variable VARIABLE with VALUE specified
+   at VARIABLE_LOC in the manner HOW unless it was specified in the
+   grammar file while the previous definition for VARIABLE was specified
+   with -F/--force-define.  Complain if a previous definition is being
+   overridden and the new definition is specified in the grammar file.
+   (These rules support the documented behavior as long as command-line
+   definitions are processed before grammar file definitions.)  Record
+   this as a user occurrence of VARIABLE by invoking
+   muscle_user_name_list_grow.  */
+void muscle_percent_define_insert (char const *variable, location variable_loc,
+                                   char const *value,
+                                   muscle_percent_define_how how);
+
+/* Mimic b4_percent_define_get in ../data/bison.m4 exactly.  That is, if the
+   %define variable VARIABLE is defined, return its value.  Otherwise, return
+   the empty string.  Also, record Bison's usage of VARIABLE by defining
+   b4_percent_define_bison_variables(VARIABLE).  The caller is responsible for
+   freeing the memory of the returned string.  */
+char *muscle_percent_define_get (char const *variable);
+
+/* Mimic muscle_percent_define_get_loc in ../data/bison.m4 exactly.  That is,
+   if the %define variable VARIABLE is undefined, complain fatally since that's
+   a Bison error.  Otherwise, return its definition location in a form
+   approriate for the first argument of warn_at, complain_at, or fatal_at.
+   Don't record this as a Bison usage of VARIABLE as there's no reason to
+   suspect that the user-supplied value has yet influenced the output.  */
+location muscle_percent_define_get_loc (char const *variable);
+
+/* Mimic muscle_percent_define_get_syncline in ../data/bison.m4 exactly.  That
+   is, if the %define variable VARIABLE is undefined, complain fatally since
+   that's a Bison error.  Otherwise, return its definition location as a
+   b4_syncline invocation.  Don't record this as a Bison usage of VARIABLE as
+   there's no reason to suspect that the user-supplied value has yet influenced
+   the output.  */
+char const *muscle_percent_define_get_syncline (char const *variable);
+
+/* Mimic b4_percent_define_ifdef in ../data/bison.m4 exactly.  That is, if the
+   %define variable VARIABLE is defined, return true.  Otherwise, return false.
+   Also, record Bison's usage of VARIABLE by defining
+   b4_percent_define_bison_variables(VARIABLE).  */
+bool muscle_percent_define_ifdef (char const *variable);
+
+/* Mimic b4_percent_define_flag_if in ../data/bison.m4 exactly.  That is, if
+   the %define variable VARIABLE is defined to "" or "true", return true.  If
+   it is defined to "false", return false.  Complain if it is undefined (a
+   Bison error since the default value should have been set already) or defined
+   to any other value (possibly a user error).  Also, record Bison's usage of
+   VARIABLE by defining b4_percent_define_bison_variables(VARIABLE).  */
+bool muscle_percent_define_flag_if (char const *variable);
+
+/* Mimic b4_percent_define_default in ../data/bison.m4 exactly.  That is, if
+   the %define variable VARIABLE is undefined, set its value to VALUE.
+   Don't record this as a Bison usage of VARIABLE as there's no reason to
+   suspect that the value has yet influenced the output.  */
+void muscle_percent_define_default (char const *variable, char const *value);
+
+/* Mimic b4_percent_define_check_values in ../data/bison.m4 exactly except that
+   the VALUES structure is more appropriate for C.  That is, VALUES points to a
+   list of strings that is partitioned into sublists by NULL's, one terminating
+   each sublist.  The last sublist is followed by a second NULL.  For each
+   sublist, the first string is the name of a %define variable, and all
+   remaining strings in that sublist are the valid values for that variable.
+   Complain if such a variable is undefined (a Bison error since the default
+   value should have been set already) or defined to any other value (possibly
+   a user error).  Don't record this as a Bison usage of the variable as
+   there's no reason to suspect that the value has yet influenced the
+   output.  */
+void muscle_percent_define_check_values (char const * const *values);
+
+/* Grow the muscle for the %code qualifier QUALIFIER appearing at
+   QUALIFIER_LOC with code CODE appearing at CODE_LOC.  Record this as a
+   user occurrence of QUALIFIER by invoking
+   muscle_user_name_list_grow.  */
+void muscle_percent_code_grow (char const *qualifier, location qualifier_loc,
+                               char const *code, location code_loc);
+
+void muscles_m4_output (FILE *out);
+
+#endif /* not MUSCLE_TAB_H_ */
diff --git a/src/muscle_tab.c b/src/muscle_tab.c
deleted file mode 100644
index 2d71085..0000000
--- a/src/muscle_tab.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Muscle table manager for Bison.
-
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software
-   Foundation, Inc.
-
-   This file is part of Bison, the GNU Compiler Compiler.
-
-   Bison 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 2, or (at your option)
-   any later version.
-
-   Bison 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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
-#include <config.h>
-#include "system.h"
-
-#include <hash.h>
-#include <quotearg.h>
-
-#include "files.h"
-#include "muscle_tab.h"
-#include "getargs.h"
-
-typedef struct
-{
-  const char *key;
-  char *value;
-} muscle_entry;
-
-/* An obstack used to create some entries.  */
-struct obstack muscle_obstack;
-
-/* Initial capacity of muscles hash table.  */
-#define HT_INITIAL_CAPACITY 257
-
-static struct hash_table *muscle_table = NULL;
-
-static bool
-hash_compare_muscles (void const *x, void const *y)
-{
-  muscle_entry const *m1 = x;
-  muscle_entry const *m2 = y;
-  return strcmp (m1->key, m2->key) == 0;
-}
-
-static size_t
-hash_muscle (const void *x, size_t tablesize)
-{
-  muscle_entry const *m = x;
-  return hash_string (m->key, tablesize);
-}
-
-/*-----------------------------------------------------------------.
-| Create the MUSCLE_TABLE, and initialize it with default values.  |
-| Also set up the MUSCLE_OBSTACK.                                  |
-`-----------------------------------------------------------------*/
-
-void
-muscle_init (void)
-{
-  /* Initialize the muscle obstack.  */
-  obstack_init (&muscle_obstack);
-
-  muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
-				  hash_compare_muscles, free);
-
-  /* Version and input file.  */
-  MUSCLE_INSERT_STRING ("version", VERSION);
-  MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
-}
-
-
-/*------------------------------------------------------------.
-| Free all the memory consumed by the muscle machinery only.  |
-`------------------------------------------------------------*/
-
-void
-muscle_free (void)
-{
-  hash_free (muscle_table);
-  obstack_free (&muscle_obstack, NULL);
-}
-
-
-
-/*------------------------------------------------------------.
-| Insert (KEY, VALUE).  If KEY already existed, overwrite the |
-| previous value.                                             |
-`------------------------------------------------------------*/
-
-void
-muscle_insert (const char *key, char *value)
-{
-  muscle_entry probe;
-  muscle_entry *entry;
-
-  probe.key = key;
-  entry = hash_lookup (muscle_table, &probe);
-
-  if (!entry)
-    {
-      /* First insertion in the hash. */
-      entry = xmalloc (sizeof *entry);
-      entry->key = key;
-      hash_insert (muscle_table, entry);
-    }
-  entry->value = value;
-}
-
-
-/*-------------------------------------------------------------------.
-| Append VALUE to the current value of KEY.  If KEY did not already  |
-| exist, create it.  Use MUSCLE_OBSTACK.  De-allocate the previously |
-| associated value.  Copy VALUE and SEPARATOR.                       |
-`-------------------------------------------------------------------*/
-
-void
-muscle_grow (const char *key, const char *val, const char *separator)
-{
-  muscle_entry probe;
-  muscle_entry *entry = NULL;
-
-  probe.key = key;
-  entry = hash_lookup (muscle_table, &probe);
-
-  if (!entry)
-    {
-      /* First insertion in the hash. */
-      entry = xmalloc (sizeof *entry);
-      entry->key = key;
-      hash_insert (muscle_table, entry);
-      entry->value = xstrdup (val);
-    }
-  else
-    {
-      /* Grow the current value. */
-      char *new_val;
-      obstack_sgrow (&muscle_obstack, entry->value);
-      free (entry->value);
-      obstack_sgrow (&muscle_obstack, separator);
-      obstack_sgrow (&muscle_obstack, val);
-      obstack_1grow (&muscle_obstack, 0);
-      new_val = obstack_finish (&muscle_obstack);
-      entry->value = xstrdup (new_val);
-      obstack_free (&muscle_obstack, new_val);
-    }
-}
-
-
-/*------------------------------------------------------------------.
-| Append VALUE to the current value of KEY, using muscle_grow.  But |
-| in addition, issue a synchronization line for the location LOC.   |
-`------------------------------------------------------------------*/
-
-void
-muscle_code_grow (const char *key, const char *val, location loc)
-{
-  char *extension = NULL;
-  obstack_fgrow1 (&muscle_obstack, "]b4_syncline(%d, [[", loc.start.line);
-  MUSCLE_OBSTACK_SGROW (&muscle_obstack,
-			quotearg_style (c_quoting_style, loc.start.file));
-  obstack_sgrow (&muscle_obstack, "]])[\n");
-  obstack_sgrow (&muscle_obstack, val);
-  obstack_1grow (&muscle_obstack, 0);
-  extension = obstack_finish (&muscle_obstack);
-  muscle_grow (key, extension, "");
-}
-
-
-/*-------------------------------------------------------------------.
-| MUSCLE is an M4 list of pairs.  Create or extend it with the pair  |
-| (A1, A2).  Note that because the muscle values are output *double* |
-| quoted, one needs to strip the first level of quotes to reach the  |
-| list itself.                                                       |
-`-------------------------------------------------------------------*/
-
-void muscle_pair_list_grow (const char *muscle,
-			    const char *a1, const char *a2)
-{
-  char *pair;
-  obstack_fgrow2 (&muscle_obstack, "[[[%s]], [[%s]]]", a1, a2);
-  obstack_1grow (&muscle_obstack, 0);
-  pair = obstack_finish (&muscle_obstack);
-  muscle_grow (muscle, pair, ",\n");
-  obstack_free (&muscle_obstack, pair);
-}
-
-/*-------------------------------.
-| Find the value of muscle KEY.  |
-`-------------------------------*/
-
-char *
-muscle_find (const char *key)
-{
-  muscle_entry probe;
-  muscle_entry *result = NULL;
-
-  probe.key = key;
-  result = hash_lookup (muscle_table, &probe);
-  return result ? result->value : NULL;
-}
-
-
-/*------------------------------------------------.
-| Output the definition of ENTRY as a m4_define.  |
-`------------------------------------------------*/
-
-static inline bool
-muscle_m4_output (muscle_entry *entry, FILE *out)
-{
-  fprintf (out, "m4_define([b4_%s],\n", entry->key);
-  fprintf (out, "[[%s]])\n\n\n", entry->value);
-  return true;
-}
-
-static bool
-muscle_m4_output_processor (void *entry, void *out)
-{
-  return muscle_m4_output (entry, out);
-}
-
-
-/*----------------------------------------------------------------.
-| Output the definition of all the current muscles into a list of |
-| m4_defines.                                                     |
-`----------------------------------------------------------------*/
-
-void
-muscles_m4_output (FILE *out)
-{
-  hash_do_for_each (muscle_table, muscle_m4_output_processor, out);
-}
diff --git a/src/muscle_tab.h b/src/muscle_tab.h
deleted file mode 100644
index 9e8ac24..0000000
--- a/src/muscle_tab.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Muscle table manager for Bison,
-   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-
-   This file is part of Bison, the GNU Compiler Compiler.
-
-   Bison 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 2, or (at your option)
-   any later version.
-
-   Bison 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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
-#ifndef MUSCLE_TAB_H_
-# define MUSCLE_TAB_H_
-
-# include "location.h"
-
-void muscle_init (void);
-void muscle_insert (const char *key, char *value);
-char *muscle_find (const char *key);
-void muscle_free (void);
-
-
-/* An obstack dedicated to receive muscle keys and values.  */
-extern struct obstack muscle_obstack;
-
-#define MUSCLE_INSERT_BOOL(Key, Value)				\
-{								\
-  int v = Value;						\
-  MUSCLE_INSERT_INT (Key, v);					\
-}
-
-#define MUSCLE_INSERT_INT(Key, Value)				\
-{								\
-  obstack_fgrow1 (&muscle_obstack, "%d", Value);		\
-  obstack_1grow (&muscle_obstack, 0);				\
-  muscle_insert (Key, obstack_finish (&muscle_obstack));	\
-}
-
-#define MUSCLE_INSERT_LONG_INT(Key, Value)			\
-{								\
-  obstack_fgrow1 (&muscle_obstack, "%ld", Value);		\
-  obstack_1grow (&muscle_obstack, 0);				\
-  muscle_insert (Key, obstack_finish (&muscle_obstack));	\
-}
-
-#define MUSCLE_INSERT_STRING(Key, Value)			\
-{								\
-  obstack_sgrow (&muscle_obstack, Value);			\
-  obstack_1grow (&muscle_obstack, 0);				\
-  muscle_insert (Key, obstack_finish (&muscle_obstack));	\
-}
-
-#define MUSCLE_OBSTACK_SGROW(Obstack, Value)			\
-{								\
-  char const *p;						\
-  for (p = Value; *p; p++)					\
-    switch (*p)							\
-      {								\
-      case '$':	obstack_sgrow (Obstack, "$]["); break;		\
-      case '@':	obstack_sgrow (Obstack, "@@" ); break;		\
-      case '[':	obstack_sgrow (Obstack, "@{" ); break;		\
-      case ']':	obstack_sgrow (Obstack, "@}" ); break;		\
-      default: obstack_1grow (Obstack, *p); break;		\
-      }								\
-}
-
-#define MUSCLE_INSERT_C_STRING(Key, Value)			\
-{								\
-  MUSCLE_OBSTACK_SGROW (&muscle_obstack,			\
-			quotearg_style (c_quoting_style,	\
-					Value));		\
-  obstack_1grow (&muscle_obstack, 0);				\
-  muscle_insert (Key, obstack_finish (&muscle_obstack));	\
-}
-
-/* Insert (KEY, VALUE).  If KEY already existed, overwrite the
-   previous value.  Uses MUSCLE_OBSTACK.  De-allocates the previously
-   associated value.  VALUE and SEPARATOR are copied.  */
-
-void muscle_grow (const char *key, const char *value, const char *separator);
-
-
-/* Append VALUE to the current value of KEY, using muscle_grow.  But
-   in addition, issue a synchronization line for the location LOC.  */
-
-void muscle_code_grow (const char *key, const char *value, location loc);
-
-
-/* MUSCLE is an M4 list of pairs.  Create or extend it with the pair
-   (A1, A2).  Note that because the muscle values are output *double*
-   quoted, one needs to strip the first level of quotes to reach the
-   list itself.  */
-
-void muscle_pair_list_grow (const char *muscle,
-			    const char *a1, const char *a2);
-
-void muscles_m4_output (FILE *out);
-
-#endif /* not MUSCLE_TAB_H_ */
diff --git a/src/named-ref.c b/src/named-ref.c
new file mode 100644
index 0000000..bf7a3f7
--- /dev/null
+++ b/src/named-ref.c
@@ -0,0 +1,46 @@
+/* Named symbol references for Bison
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include "named-ref.h"
+
+named_ref *
+named_ref_new (uniqstr id, location loc)
+{
+  named_ref *res = xmalloc (sizeof *res);
+
+  res->id = id;
+  res->loc = loc;
+
+  return res;
+}
+
+named_ref *
+named_ref_copy (const named_ref *r)
+{
+  return named_ref_new (r->id, r->loc);
+}
+
+void
+named_ref_free (named_ref *r)
+{
+  free (r);
+}
diff --git a/src/named-ref.h b/src/named-ref.h
new file mode 100644
index 0000000..00c972c
--- /dev/null
+++ b/src/named-ref.h
@@ -0,0 +1,46 @@
+/* Named symbol references for Bison
+
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef NAMED_REF_H_
+# define NAMED_REF_H_
+
+#include "location.h"
+#include "uniqstr.h"
+
+/* Named reference object. Keeps information about
+   a symbolic name of a symbol in a rule. */
+typedef struct named_ref
+{
+  /* Symbolic named given by user. */
+  uniqstr id;
+
+  /* Location of the symbolic name. Not including brackets. */
+  location loc;
+} named_ref;
+
+/* Allocate a named reference object. */
+named_ref *named_ref_new (uniqstr id, location loc);
+
+/* Allocate and return a copy.  */
+named_ref *named_ref_copy (const named_ref *r);
+
+/* Free a named reference object. */
+void named_ref_free (named_ref *r);
+
+#endif /* !NAMED_REF_H_ */
diff --git a/src/nullable.c b/src/nullable.c
index 83a90e9..1e7f5d1 100644
--- a/src/nullable.c
+++ b/src/nullable.c
@@ -1,24 +1,22 @@
 /* Calculate which nonterminals can expand into the null string for Bison.
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 2000-2006, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 /* Set up NULLABLE, a vector saying which nonterminals can expand into
@@ -104,8 +102,8 @@
 	else
 	  {
 	    /* This rule has an empty RHS. */
-	    assert (item_number_as_rule_number (rules_ruleno->rhs[0])
-		    == ruleno);
+	    aver (item_number_as_rule_number (rules_ruleno->rhs[0])
+		  == ruleno);
 	    if (rules_ruleno->useful
 		&& ! nullable[rules_ruleno->lhs->number - ntokens])
 	      {
diff --git a/src/nullable.h b/src/nullable.h
index d5106c7..f7b2912 100644
--- a/src/nullable.h
+++ b/src/nullable.h
@@ -1,22 +1,21 @@
 /* Part of the bison parser generator,
-   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+
+   Copyright (C) 2000, 2002, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef NULLABLE_H_
 # define NULLABLE_H_
diff --git a/src/output.c b/src/output.c
index 6a02bb3..3852729 100644
--- a/src/output.c
+++ b/src/output.c
@@ -1,46 +1,46 @@
 /* Output the generated parsing program for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
+#include <configmake.h>
 #include <error.h>
 #include <get-errno.h>
 #include <quotearg.h>
-#include <subpipe.h>
+#include <spawn-pipe.h>
 #include <timevar.h>
+#include <wait-process.h>
 
 #include "complain.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "muscle_tab.h"
+#include "muscle-tab.h"
 #include "output.h"
 #include "reader.h"
+#include "scan-code.h"    /* max_left_semantic_context */
 #include "scan-skel.h"
 #include "symtab.h"
 #include "tables.h"
 
-
 static struct obstack format_obstack;
 
 
@@ -68,7 +68,7 @@
   int i;								\
   int j = 1;								\
 									\
-  obstack_fgrow1 (&format_obstack, "%6d", first);			\
+  obstack_printf (&format_obstack, "%6d", first);			\
   for (i = begin; i < end; ++i)						\
     {									\
       obstack_1grow (&format_obstack, ',');				\
@@ -79,7 +79,7 @@
 	}								\
       else								\
 	++j;								\
-      obstack_fgrow1 (&format_obstack, "%6d", table_data[i]);		\
+      obstack_printf (&format_obstack, "%6d", table_data[i]);		\
       if (table_data[i] < min)						\
 	min = table_data[i];						\
       if (max < table_data[i])						\
@@ -91,10 +91,10 @@
   lmin = min;								\
   lmax = max;								\
   /* Build `NAME_min' and `NAME_max' in the obstack. */			\
-  obstack_fgrow1 (&format_obstack, "%s_min", name);			\
+  obstack_printf (&format_obstack, "%s_min", name);			\
   obstack_1grow (&format_obstack, 0);					\
   MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin);	\
-  obstack_fgrow1 (&format_obstack, "%s_max", name);			\
+  obstack_printf (&format_obstack, "%s_max", name);			\
   obstack_1grow (&format_obstack, 0);					\
   MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax);	\
 }
@@ -108,29 +108,39 @@
 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
 
 
-/*--------------------------------------------------------------------.
-| Print to OUT a representation of STRING escaped both for C and M4.  |
-`--------------------------------------------------------------------*/
+/*----------------------------------------------------------------.
+| Print to OUT a representation of CP quoted and escaped for M4.  |
+`----------------------------------------------------------------*/
 
 static void
-escaped_output (FILE *out, char const *string)
+quoted_output (FILE *out, char const *cp)
 {
-  char const *p;
   fprintf (out, "[[");
 
-  for (p = quotearg_style (c_quoting_style, string); *p; p++)
-    switch (*p)
+  for (; *cp; cp++)
+    switch (*cp)
       {
       case '$': fputs ("$][", out); break;
       case '@': fputs ("@@",  out); break;
       case '[': fputs ("@{",  out); break;
       case ']': fputs ("@}",  out); break;
-      default: fputc (*p, out); break;
+      default:  fputc (*cp,   out); break;
       }
 
   fprintf (out, "]]");
 }
 
+/*----------------------------------------------------------------.
+| Print to OUT a representation of STRING quoted and escaped both |
+| for C and M4.                                                   |
+`----------------------------------------------------------------*/
+
+static void
+string_output (FILE *out, char const *string)
+{
+  quoted_output (out, quotearg_style (c_quoting_style, string));
+}
+
 
 /*------------------------------------------------------------------.
 | Prepare the muscles related to the symbols: translate, tname, and |
@@ -140,7 +150,6 @@
 static void
 prepare_symbols (void)
 {
-  MUSCLE_INSERT_BOOL ("token_table", token_table_flag);
   MUSCLE_INSERT_INT ("tokens_number", ntokens);
   MUSCLE_INSERT_INT ("nterms_number", nvars);
   MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
@@ -156,9 +165,12 @@
     int i;
     /* We assume that the table will be output starting at column 2. */
     int j = 2;
+    struct quoting_options *qo = clone_quoting_options (0);
+    set_quoting_style (qo, c_quoting_style);
+    set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
     for (i = 0; i < nsyms; i++)
       {
-	char const *cp = quotearg_style (c_quoting_style, symbols[i]->tag);
+	char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
 	/* Width of the next token, including the two quotes, the
 	   comma and the space.  */
 	int width = strlen (cp) + 2;
@@ -171,13 +183,13 @@
 
 	if (i)
 	  obstack_1grow (&format_obstack, ' ');
-	MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
+	obstack_escape (&format_obstack, cp);
+        free (cp);
 	obstack_1grow (&format_obstack, ',');
 	j += width;
       }
-    /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
-       defined).  */
-    obstack_sgrow (&format_obstack, " 0");
+    free (qo);
+    obstack_sgrow (&format_obstack, " ]b4_null[");
 
     /* Finish table and store. */
     obstack_1grow (&format_obstack, 0);
@@ -236,7 +248,7 @@
       /* Merger-function index (GLR).  */
       merger[r] = rules[r].merger;
     }
-  assert (i == nritems);
+  aver (i == nritems);
 
   muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
   muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
@@ -289,20 +301,16 @@
 {
   rule_number r;
 
-  fputs ("m4_define([b4_actions], \n[[", out);
+  fputs ("m4_define([b4_actions], \n[", out);
   for (r = 0; r < nrules; ++r)
     if (rules[r].action)
       {
-	fprintf (out, "  case %d:\n", r + 1);
-
-	fprintf (out, "]b4_syncline(%d, ",
+	fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1,
 		 rules[r].action_location.start.line);
-	escaped_output (out, rules[r].action_location.start.file);
-	fprintf (out, ")[\n");
-	fprintf (out, "    %s\n    break;\n\n",
-		 rules[r].action);
+	string_output (out, rules[r].action_location.start.file);
+	fprintf (out, ")\n[    %s]])\n\n", rules[r].action);
       }
-  fputs ("]])\n\n", out);
+  fputs ("])\n\n", out);
 }
 
 /*--------------------------------------.
@@ -344,10 +352,10 @@
       symbol *sym = symbols[i];
       int number = sym->user_token_number;
 
-      /* At this stage, if there are literal aliases, they are part of
-	 SYMBOLS, so we should not find symbols which are the aliases
-	 here.  */
-      assert (number != USER_NUMBER_ALIAS);
+      /* At this stage, if there are literal string aliases, they are
+         part of SYMBOLS, so we should not find their aliased symbols
+         here.  */
+      aver (number != USER_NUMBER_HAS_STRING_ALIAS);
 
       /* Skip error token.  */
       if (sym == errtoken)
@@ -364,9 +372,11 @@
       if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
 	continue;
 
-      /* Don't #define nonliteral tokens whose names contain periods
-	 or '$' (as does the default value of the EOF token).  */
-      if (strchr (sym->tag, '.') || strchr (sym->tag, '$'))
+      /* Don't #define nonliteral tokens whose names contain periods,
+         dashes or '$' (as does the default value of the EOF token).  */
+      if (mbschr (sym->tag, '.')
+          || mbschr (sym->tag, '-')
+          || mbschr (sym->tag, '$'))
 	continue;
 
       fprintf (out, "%s[[[%s]], %d]",
@@ -377,68 +387,44 @@
 }
 
 
-/*---------------------------------------.
-| Output the symbol destructors to OUT.  |
-`---------------------------------------*/
+/*---------------------------------------------------.
+| Output the symbol destructors or printers to OUT.  |
+`---------------------------------------------------*/
 
 static void
-symbol_destructors_output (FILE *out)
+symbol_code_props_output (FILE *out, char const *what,
+                          code_props const *(*get)(symbol const *))
 {
   int i;
   char const *sep = "";
 
-  fputs ("m4_define([b4_symbol_destructors], \n[", out);
+  fputs ("m4_define([b4_symbol_", out);
+  fputs (what, out);
+  fputs ("], \n[", out);
   for (i = 0; i < nsyms; ++i)
-    if (symbols[i]->destructor)
-      {
-	symbol *sym = symbols[i];
-
-	/* Filename, lineno,
-	   Symbol-name, Symbol-number,
-	   destructor, optional typename.  */
-	fprintf (out, "%s[", sep);
-	sep = ",\n";
-	escaped_output (out, sym->destructor_location.start.file);
-	fprintf (out, ", %d, ", sym->destructor_location.start.line);
-	escaped_output (out, sym->tag);
-	fprintf (out, ", %d, [[%s]]", sym->number, sym->destructor);
-	if (sym->type_name)
-	  fprintf (out, ", [[%s]]", sym->type_name);
-	fputc (']', out);
-      }
-  fputs ("])\n\n", out);
-}
-
-
-/*------------------------------------.
-| Output the symbol printers to OUT.  |
-`------------------------------------*/
-
-static void
-symbol_printers_output (FILE *out)
-{
-  int i;
-  char const *sep = "";
-
-  fputs ("m4_define([b4_symbol_printers], \n[", out);
-  for (i = 0; i < nsyms; ++i)
-    if (symbols[i]->printer)
-      {
-	symbol *sym = symbols[i];
-
-	/* Filename, lineno,
-	   Symbol-name, Symbol-number,
-	   printer, optional typename.  */
-	fprintf (out, "%s[", sep);
-	sep = ",\n";
-	escaped_output (out, sym->printer_location.start.file);
-	fprintf (out, ", %d, ", sym->printer_location.start.line);
-	escaped_output (out, sym->tag);
-	fprintf (out, ", %d, [[%s]]", sym->number, sym->printer);
-	if (sym->type_name)
-	  fprintf (out, ", [[%s]]", sym->type_name);
-	fputc (']', out);
-      }
+    {
+      symbol *sym = symbols[i];
+      char const *code = (*get) (sym)->code;
+      if (code)
+        {
+          location loc = (*get) (sym)->location;
+          /* Filename, lineno,
+             Symbol-name, Symbol-number,
+             code, optional typename.  */
+          fprintf (out, "%s[", sep);
+          sep = ",\n";
+          string_output (out, loc.start.file);
+          fprintf (out, ", %d, ", loc.start.line);
+          quoted_output (out, sym->tag);
+          fprintf (out, ", %d, [[%s]]", sym->number, code);
+          if (sym->type_name)
+            {
+              fputs (", ", out);
+              quoted_output (out, sym->type_name);
+            }
+          fputc (']', out);
+        }
+    }
   fputs ("])\n\n", out);
 }
 
@@ -447,7 +433,7 @@
 prepare_actions (void)
 {
   /* Figure out the actions for the specified state, indexed by
-     look-ahead token type.  */
+     lookahead token type.  */
 
   muscle_insert_rule_number_table ("defact", yydefact,
 				   yydefact[0], 1, nstates);
@@ -490,6 +476,23 @@
 				    0, 1, conflict_list_cnt);
 }
 
+/*--------------------------------------------.
+| Output the definitions of all the muscles.  |
+`--------------------------------------------*/
+
+static void
+muscles_output (FILE *out)
+{
+  fputs ("m4_init()\n", out);
+
+  user_actions_output (out);
+  merger_output (out);
+  token_definitions_output (out);
+  symbol_code_props_output (out, "destructors", &symbol_destructor_get);
+  symbol_code_props_output (out, "printers", &symbol_printer_get);
+
+  muscles_m4_output (out);
+}
 
 /*---------------------------.
 | Call the skeleton parser.  |
@@ -499,21 +502,19 @@
 output_skeleton (void)
 {
   FILE *in;
-  FILE *out;
   int filter_fd[2];
-  char const *argv[6];
+  char const *argv[10];
   pid_t pid;
 
-  /* Compute the names of the package data dir and skeleton file.
-     Test whether m4sugar.m4 is readable, to check for proper
-     installation.  A faulty installation can cause deadlock, so a
-     cheap sanity check is worthwhile.  */
+  /* Compute the names of the package data dir and skeleton files.  */
   char const m4sugar[] = "m4sugar/m4sugar.m4";
+  char const m4bison[] = "bison.m4";
   char *full_m4sugar;
+  char *full_m4bison;
   char *full_skeleton;
   char const *p;
   char const *m4 = (p = getenv ("M4")) ? p : M4;
-  char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
+  char const *pkgdatadir = compute_pkgdatadir ();
   size_t skeleton_size = strlen (skeleton) + 1;
   size_t pkgdatadirlen = strlen (pkgdatadir);
   while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
@@ -521,77 +522,128 @@
   full_skeleton = xmalloc (pkgdatadirlen + 1
 			   + (skeleton_size < sizeof m4sugar
 			      ? sizeof m4sugar : skeleton_size));
-  strcpy (full_skeleton, pkgdatadir);
+  memcpy (full_skeleton, pkgdatadir, pkgdatadirlen);
   full_skeleton[pkgdatadirlen] = '/';
   strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
   full_m4sugar = xstrdup (full_skeleton);
-  strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
+  strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
+  full_m4bison = xstrdup (full_skeleton);
+  if (mbschr (skeleton, '/'))
+    strcpy (full_skeleton, skeleton);
+  else
+    strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
+
+  /* Test whether m4sugar.m4 is readable, to check for proper
+     installation.  A faulty installation can cause deadlock, so a
+     cheap sanity check is worthwhile.  */
   xfclose (xfopen (full_m4sugar, "r"));
 
   /* Create an m4 subprocess connected to us via two pipes.  */
 
   if (trace_flag & trace_tools)
-    fprintf (stderr, "running: %s %s - %s\n",
-	     m4, full_m4sugar, full_skeleton);
+    fprintf (stderr, "running: %s %s - %s %s\n",
+             m4, full_m4sugar, full_m4bison, full_skeleton);
 
-  argv[0] = m4;
-  argv[1] = full_m4sugar;
-  argv[2] = "-";
-  argv[3] = full_skeleton;
-  argv[4] = trace_flag & trace_m4 ? "-dV" : NULL;
-  argv[5] = NULL;
+  /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
+     position-dependent manner.  Keep it as the first argument so that all
+     files are traced.
 
-  init_subpipe ();
-  pid = create_subpipe (argv, filter_fd);
+     See the thread starting at
+     <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
+     for details.  */
+  {
+    int i = 0;
+    argv[i++] = m4;
+
+    /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU
+       extensions, which Bison's skeletons depend on.  With older M4,
+       it has no effect.  M4 1.4.12 added a -g/--gnu command-line
+       option to make it explicit that a program wants GNU M4
+       extensions even when POSIXLY_CORRECT is set.
+
+       See the thread starting at
+       <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
+       for details.  */
+    if (*M4_GNU_OPTION)
+      argv[i++] = M4_GNU_OPTION;
+
+    argv[i++] = "-I";
+    argv[i++] = pkgdatadir;
+    if (trace_flag & trace_m4)
+      argv[i++] = "-dV";
+    argv[i++] = full_m4sugar;
+    argv[i++] = "-";
+    argv[i++] = full_m4bison;
+    argv[i++] = full_skeleton;
+    argv[i++] = NULL;
+    aver (i <= ARRAY_CARDINALITY (argv));
+  }
+
+  /* The ugly cast is because gnulib gets the const-ness wrong.  */
+  pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
+                          true, filter_fd);
   free (full_m4sugar);
+  free (full_m4bison);
   free (full_skeleton);
 
-  out = fdopen (filter_fd[0], "w");
-  if (! out)
-    error (EXIT_FAILURE, get_errno (),
-	   "fdopen");
-
-  /* Output the definitions of all the muscles.  */
-  fputs ("m4_init()\n", out);
-
-  user_actions_output (out);
-  merger_output (out);
-  token_definitions_output (out);
-  symbol_destructors_output (out);
-  symbol_printers_output (out);
-
-  muscles_m4_output (out);
-
-  fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
-  fputs ("m4_divert_push(0)dnl\n", out);
-  xfclose (out);
+  if (trace_flag & trace_muscles)
+    muscles_output (stderr);
+  {
+    FILE *out = fdopen (filter_fd[1], "w");
+    if (! out)
+      error (EXIT_FAILURE, get_errno (),
+             "fdopen");
+    muscles_output (out);
+    xfclose (out);
+  }
 
   /* Read and process m4's output.  */
   timevar_push (TV_M4);
-  end_of_output_subpipe (pid, filter_fd);
-  in = fdopen (filter_fd[1], "r");
+  in = fdopen (filter_fd[0], "r");
   if (! in)
     error (EXIT_FAILURE, get_errno (),
 	   "fdopen");
   scan_skel (in);
+  /* scan_skel should have read all of M4's output.  Otherwise, when we
+     close the pipe, we risk letting M4 report a broken-pipe to the
+     Bison user.  */
+  aver (feof (in));
   xfclose (in);
-  reap_subpipe (pid, m4);
+  wait_subprocess (pid, "m4", false, false, true, true, NULL);
   timevar_pop (TV_M4);
 }
 
 static void
 prepare (void)
 {
+  /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented
+     for the user.  */
+  char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL");
+  bool use_push_for_pull_flag = false;
+  if (use_push_for_pull_env != NULL
+      && use_push_for_pull_env[0] != '\0'
+      && 0 != strcmp (use_push_for_pull_env, "0"))
+    use_push_for_pull_flag = true;
+
   /* Flags. */
-  MUSCLE_INSERT_BOOL ("debug_flag", debug_flag);
+  MUSCLE_INSERT_BOOL ("debug_flag", debug);
   MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
   MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose);
+  MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
   MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
-  MUSCLE_INSERT_BOOL ("pure_flag", pure_parser);
+  MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
   MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
+  MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
+  MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag);
+  MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
+  MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
 
   /* File names.  */
-  MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
+  if (spec_name_prefix)
+    MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
+
+  MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
+
 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
   DEFINE (dir_prefix);
   DEFINE (parser_file_name);
@@ -603,26 +655,18 @@
   DEFINE (spec_verbose_file);
 #undef DEFINE
 
-  /* User Code.  */
-  obstack_1grow (&pre_prologue_obstack, 0);
-  obstack_1grow (&post_prologue_obstack, 0);
-  muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
-  muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
-
-  /* Find the right skeleton file.  */
-  if (!skeleton)
-    {
-      if (glr_parser || nondeterministic_parser)
-	skeleton = "glr.c";
-      else
-	skeleton = "yacc.c";
-    }
-
-  /* About the skeletons. */
-  {
-    char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
-    MUSCLE_INSERT_STRING ("pkgdatadir", pkgdatadir ? pkgdatadir : PKGDATADIR);
+  /* Find the right skeleton file, and add muscles about the skeletons.  */
+  if (skeleton)
     MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
+  else
+    skeleton = language->skeleton;
+
+  /* About the skeletons.  */
+  {
+    /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
+       would never be expanded.  Hopefully no one has M4-special characters in
+       his Bison installation path.  */
+    MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ());
   }
 }
 
@@ -647,6 +691,11 @@
   output_skeleton ();
 
   obstack_free (&format_obstack, NULL);
-  obstack_free (&pre_prologue_obstack, NULL);
-  obstack_free (&post_prologue_obstack, NULL);
+}
+
+char const *
+compute_pkgdatadir (void)
+{
+  char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
+  return pkgdatadir ? pkgdatadir : PKGDATADIR;
 }
diff --git a/src/output.h b/src/output.h
index 784f227..6c428d5 100644
--- a/src/output.h
+++ b/src/output.h
@@ -1,27 +1,28 @@
 /* Output the generated parsing program for bison,
-   Copyright (C) 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+
+   Copyright (C) 2000-2003, 2006-2007, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef OUTPUT_H_
 # define OUTPUT_H_
 
 /* Output the parsing tables and the parser code to FTABLE.  */
 void output (void);
+char const *compute_pkgdatadir (void);
 
 #endif /* !OUTPUT_H_ */
diff --git a/src/parse-gram.c b/src/parse-gram.c
index 2b77f3e..5633b4e 100644
--- a/src/parse-gram.c
+++ b/src/parse-gram.c
@@ -1,24 +1,21 @@
-/* A Bison parser, made by GNU Bison 2.2a.  */
+/* A Bison parser, made by GNU Bison 2.6.5.63-3ada.  */
 
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
+/* Bison implementation for Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989-1990, 2000-2012 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 2, or (at your option)
-   any later version.
-
+   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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +26,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -47,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.2a"
+#define YYBISON_VERSION "2.6.5.63-3ada"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -55,143 +52,37 @@
 /* Pure parsers.  */
 #define YYPURE 1
 
-/* Using locations.  */
-#define YYLSP_NEEDED 1
+/* Push parsers.  */
+#define YYPUSH 0
 
+/* Pull parsers.  */
+#define YYPULL 1
+
+/* Substitute the type names.  */
+#define YYSTYPE         GRAM_STYPE
+#define YYLTYPE         GRAM_LTYPE
 /* Substitute the variable and function names.  */
-#define yyparse gram_parse
-#define yylex   gram_lex
-#define yyerror gram_error
-#define yylval  gram_lval
-#define yychar  gram_char
-#define yydebug gram_debug
-#define yynerrs gram_nerrs
-#define yylloc gram_lloc
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     GRAM_EOF = 0,
-     STRING = 258,
-     INT = 259,
-     PERCENT_TOKEN = 260,
-     PERCENT_NTERM = 261,
-     PERCENT_TYPE = 262,
-     PERCENT_DESTRUCTOR = 263,
-     PERCENT_PRINTER = 264,
-     PERCENT_UNION = 265,
-     PERCENT_LEFT = 266,
-     PERCENT_RIGHT = 267,
-     PERCENT_NONASSOC = 268,
-     PERCENT_PREC = 269,
-     PERCENT_DPREC = 270,
-     PERCENT_MERGE = 271,
-     PERCENT_DEBUG = 272,
-     PERCENT_DEFAULT_PREC = 273,
-     PERCENT_DEFINE = 274,
-     PERCENT_DEFINES = 275,
-     PERCENT_ERROR_VERBOSE = 276,
-     PERCENT_EXPECT = 277,
-     PERCENT_EXPECT_RR = 278,
-     PERCENT_FILE_PREFIX = 279,
-     PERCENT_GLR_PARSER = 280,
-     PERCENT_INITIAL_ACTION = 281,
-     PERCENT_LEX_PARAM = 282,
-     PERCENT_LOCATIONS = 283,
-     PERCENT_NAME_PREFIX = 284,
-     PERCENT_NO_DEFAULT_PREC = 285,
-     PERCENT_NO_LINES = 286,
-     PERCENT_NONDETERMINISTIC_PARSER = 287,
-     PERCENT_OUTPUT = 288,
-     PERCENT_PARSE_PARAM = 289,
-     PERCENT_PURE_PARSER = 290,
-     PERCENT_REQUIRE = 291,
-     PERCENT_SKELETON = 292,
-     PERCENT_START = 293,
-     PERCENT_TOKEN_TABLE = 294,
-     PERCENT_VERBOSE = 295,
-     PERCENT_YACC = 296,
-     TYPE = 297,
-     EQUAL = 298,
-     SEMICOLON = 299,
-     PIPE = 300,
-     ID = 301,
-     ID_COLON = 302,
-     PERCENT_PERCENT = 303,
-     PROLOGUE = 304,
-     EPILOGUE = 305,
-     BRACED_CODE = 306
-   };
-#endif
-/* Tokens.  */
-#define GRAM_EOF 0
-#define STRING 258
-#define INT 259
-#define PERCENT_TOKEN 260
-#define PERCENT_NTERM 261
-#define PERCENT_TYPE 262
-#define PERCENT_DESTRUCTOR 263
-#define PERCENT_PRINTER 264
-#define PERCENT_UNION 265
-#define PERCENT_LEFT 266
-#define PERCENT_RIGHT 267
-#define PERCENT_NONASSOC 268
-#define PERCENT_PREC 269
-#define PERCENT_DPREC 270
-#define PERCENT_MERGE 271
-#define PERCENT_DEBUG 272
-#define PERCENT_DEFAULT_PREC 273
-#define PERCENT_DEFINE 274
-#define PERCENT_DEFINES 275
-#define PERCENT_ERROR_VERBOSE 276
-#define PERCENT_EXPECT 277
-#define PERCENT_EXPECT_RR 278
-#define PERCENT_FILE_PREFIX 279
-#define PERCENT_GLR_PARSER 280
-#define PERCENT_INITIAL_ACTION 281
-#define PERCENT_LEX_PARAM 282
-#define PERCENT_LOCATIONS 283
-#define PERCENT_NAME_PREFIX 284
-#define PERCENT_NO_DEFAULT_PREC 285
-#define PERCENT_NO_LINES 286
-#define PERCENT_NONDETERMINISTIC_PARSER 287
-#define PERCENT_OUTPUT 288
-#define PERCENT_PARSE_PARAM 289
-#define PERCENT_PURE_PARSER 290
-#define PERCENT_REQUIRE 291
-#define PERCENT_SKELETON 292
-#define PERCENT_START 293
-#define PERCENT_TOKEN_TABLE 294
-#define PERCENT_VERBOSE 295
-#define PERCENT_YACC 296
-#define TYPE 297
-#define EQUAL 298
-#define SEMICOLON 299
-#define PIPE 300
-#define ID 301
-#define ID_COLON 302
-#define PERCENT_PERCENT 303
-#define PROLOGUE 304
-#define EPILOGUE 305
-#define BRACED_CODE 306
-
-
-
+#define yyparse         gram_parse
+#define yylex           gram_lex
+#define yyerror         gram_error
+#define yylval          gram_lval
+#define yychar          gram_char
+#define yydebug         gram_debug
+#define yynerrs         gram_nerrs
+#define yylloc          gram_lloc
 
 /* Copy the first part of user declarations.  */
+/* Line 360 of yacc.c  */
 #line 1 "parse-gram.y"
 /* Bison Grammar Parser                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   This program is free software; you can redistribute it and/or modify
+   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 2 of the License, or
+   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,
@@ -200,24 +91,25 @@
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301  USA
-*/
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
+#include "c-ctype.h"
 #include "complain.h"
 #include "conflicts.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "muscle_tab.h"
+#include "muscle-tab.h"
+#include "named-ref.h"
 #include "quotearg.h"
 #include "reader.h"
 #include "symlist.h"
-#include "strverscmp.h"
+#include "scan-gram.h"
+#include "scan-code.h"
+#include "xmemdup0.h"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
@@ -234,32 +126,58 @@
 	gram_error (&yylloc, Msg)
 static void gram_error (location const *, char const *);
 
-static void add_param (char const *, char *, location);
+static char const *char_name (char);
+
+/** Add a lex-param or a parse-param.
+ *
+ * \param type  \a lex_param or \a parse_param
+ * \param decl  the formal argument
+ * \param loc   the location in the source.
+ */
+static void add_param (char const *type, char *decl, location loc);
+
 
 static symbol_class current_class = unknown_sym;
-static uniqstr current_type = 0;
-static symbol *current_lhs;
+static uniqstr current_type = NULL;
+static symbol *current_lhs_symbol;
 static location current_lhs_location;
+static named_ref *current_lhs_named_ref;
 static int current_prec = 0;
 
-#ifdef UINT_FAST8_MAX
-# define YYTYPE_UINT8 uint_fast8_t
-#endif
-#ifdef INT_FAST8_MAX
-# define YYTYPE_INT8 int_fast8_t
-#endif
-#ifdef UINT_FAST16_MAX
-# define YYTYPE_UINT16 uint_fast16_t
-#endif
-#ifdef INT_FAST16_MAX
-# define YYTYPE_INT16 int_fast16_t
-#endif
+/** Set the new current left-hand side symbol, possibly common
+ * to several right-hand side parts of rule.
+ */
+static
+void
+current_lhs(symbol *sym, location loc, named_ref *ref)
+{
+  current_lhs_symbol = sym;
+  current_lhs_location = loc;
+  /* In order to simplify memory management, named references for lhs
+     are always assigned by deep copy into the current symbol_list
+     node.  This is because a single named-ref in the grammar may
+     result in several uses when the user factors lhs between several
+     rules using "|".  Therefore free the parser's original copy.  */
+  free (current_lhs_named_ref);
+  current_lhs_named_ref = ref;
+}
 
 
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
+#define YYTYPE_INT16 int_fast16_t
+#define YYTYPE_INT8 int_fast8_t
+#define YYTYPE_UINT16 uint_fast16_t
+#define YYTYPE_UINT8 uint_fast8_t
+
+/* Line 360 of yacc.c  */
+#line 173 "parse-gram.c"
+
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -269,49 +187,209 @@
 # define YYERROR_VERBOSE 1
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "parse-gram.h".  */
+#ifndef YY_GRAM_Y_TAB_H_INCLUDED
+# define YY_GRAM_Y_TAB_H_INCLUDED
+/* Enabling traces.  */
+#ifndef GRAM_DEBUG
+# if defined YYDEBUG
+#  if YYDEBUG
+#   define GRAM_DEBUG 1
+#  else
+#   define GRAM_DEBUG 0
+#  endif
+# else /* ! defined YYDEBUG */
+#  define GRAM_DEBUG 1
+# endif /* ! defined YYDEBUG */
+#endif  /* ! defined GRAM_DEBUG */
+#if GRAM_DEBUG
+extern int gram_debug;
 #endif
 
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 94 "parse-gram.y"
+/* Tokens.  */
+#ifndef GRAM_TOKENTYPE
+# define GRAM_TOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum gram_tokentype {
+     GRAM_EOF = 0,
+     STRING = 258,
+     INT = 259,
+     PERCENT_TOKEN = 260,
+     PERCENT_NTERM = 261,
+     PERCENT_TYPE = 262,
+     PERCENT_DESTRUCTOR = 263,
+     PERCENT_PRINTER = 264,
+     PERCENT_LEFT = 265,
+     PERCENT_RIGHT = 266,
+     PERCENT_NONASSOC = 267,
+     PERCENT_PREC = 268,
+     PERCENT_DPREC = 269,
+     PERCENT_MERGE = 270,
+     PERCENT_CODE = 271,
+     PERCENT_DEBUG = 272,
+     PERCENT_DEFAULT_PREC = 273,
+     PERCENT_DEFINE = 274,
+     PERCENT_DEFINES = 275,
+     PERCENT_ERROR_VERBOSE = 276,
+     PERCENT_EXPECT = 277,
+     PERCENT_EXPECT_RR = 278,
+     PERCENT_FILE_PREFIX = 279,
+     PERCENT_GLR_PARSER = 280,
+     PERCENT_INITIAL_ACTION = 281,
+     PERCENT_LANGUAGE = 282,
+     PERCENT_LEX_PARAM = 283,
+     PERCENT_LOCATIONS = 284,
+     PERCENT_NAME_PREFIX = 285,
+     PERCENT_NO_DEFAULT_PREC = 286,
+     PERCENT_NO_LINES = 287,
+     PERCENT_NONDETERMINISTIC_PARSER = 288,
+     PERCENT_OUTPUT = 289,
+     PERCENT_PARSE_PARAM = 290,
+     PERCENT_PURE_PARSER = 291,
+     PERCENT_REQUIRE = 292,
+     PERCENT_SKELETON = 293,
+     PERCENT_START = 294,
+     PERCENT_TOKEN_TABLE = 295,
+     PERCENT_VERBOSE = 296,
+     PERCENT_YACC = 297,
+     BRACED_CODE = 298,
+     BRACKETED_ID = 299,
+     CHAR = 300,
+     EPILOGUE = 301,
+     EQUAL = 302,
+     ID = 303,
+     ID_COLON = 304,
+     PERCENT_PERCENT = 305,
+     PIPE = 306,
+     PROLOGUE = 307,
+     SEMICOLON = 308,
+     TYPE = 309,
+     TYPE_TAG_ANY = 310,
+     TYPE_TAG_NONE = 311,
+     PERCENT_UNION = 312
+   };
+#endif
+/* Tokens.  */
+#define GRAM_EOF 0
+#define STRING 258
+#define INT 259
+#define PERCENT_TOKEN 260
+#define PERCENT_NTERM 261
+#define PERCENT_TYPE 262
+#define PERCENT_DESTRUCTOR 263
+#define PERCENT_PRINTER 264
+#define PERCENT_LEFT 265
+#define PERCENT_RIGHT 266
+#define PERCENT_NONASSOC 267
+#define PERCENT_PREC 268
+#define PERCENT_DPREC 269
+#define PERCENT_MERGE 270
+#define PERCENT_CODE 271
+#define PERCENT_DEBUG 272
+#define PERCENT_DEFAULT_PREC 273
+#define PERCENT_DEFINE 274
+#define PERCENT_DEFINES 275
+#define PERCENT_ERROR_VERBOSE 276
+#define PERCENT_EXPECT 277
+#define PERCENT_EXPECT_RR 278
+#define PERCENT_FILE_PREFIX 279
+#define PERCENT_GLR_PARSER 280
+#define PERCENT_INITIAL_ACTION 281
+#define PERCENT_LANGUAGE 282
+#define PERCENT_LEX_PARAM 283
+#define PERCENT_LOCATIONS 284
+#define PERCENT_NAME_PREFIX 285
+#define PERCENT_NO_DEFAULT_PREC 286
+#define PERCENT_NO_LINES 287
+#define PERCENT_NONDETERMINISTIC_PARSER 288
+#define PERCENT_OUTPUT 289
+#define PERCENT_PARSE_PARAM 290
+#define PERCENT_PURE_PARSER 291
+#define PERCENT_REQUIRE 292
+#define PERCENT_SKELETON 293
+#define PERCENT_START 294
+#define PERCENT_TOKEN_TABLE 295
+#define PERCENT_VERBOSE 296
+#define PERCENT_YACC 297
+#define BRACED_CODE 298
+#define BRACKETED_ID 299
+#define CHAR 300
+#define EPILOGUE 301
+#define EQUAL 302
+#define ID 303
+#define ID_COLON 304
+#define PERCENT_PERCENT 305
+#define PIPE 306
+#define PROLOGUE 307
+#define SEMICOLON 308
+#define TYPE 309
+#define TYPE_TAG_ANY 310
+#define TYPE_TAG_NONE 311
+#define PERCENT_UNION 312
+
+
+
+#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
+typedef union GRAM_STYPE
 {
+/* Line 376 of yacc.c  */
+#line 115 "parse-gram.y"
+
   symbol *symbol;
   symbol_list *list;
   int integer;
-  char *chars;
+  char const *chars;
+  char *code;
   assoc assoc;
   uniqstr uniqstr;
-}
-/* Line 193 of yacc.c.  */
-#line 290 "parse-gram.c"
-	YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
+  unsigned char character;
+  named_ref *named_ref;
+
+
+/* Line 376 of yacc.c  */
+#line 353 "parse-gram.c"
+} GRAM_STYPE;
+# define GRAM_STYPE_IS_TRIVIAL 1
+# define gram_stype GRAM_STYPE /* obsolescent; will be withdrawn */
+# define GRAM_STYPE_IS_DECLARED 1
 #endif
 
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
+#if ! defined GRAM_LTYPE && ! defined GRAM_LTYPE_IS_DECLARED
+typedef struct GRAM_LTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
+} GRAM_LTYPE;
+# define gram_ltype GRAM_LTYPE /* obsolescent; will be withdrawn */
+# define GRAM_LTYPE_IS_DECLARED 1
+# define GRAM_LTYPE_IS_TRIVIAL 1
 #endif
 
 
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int gram_parse (void *YYPARSE_PARAM);
+#else
+int gram_parse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int gram_parse (void);
+#else
+int gram_parse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_GRAM_Y_TAB_H_INCLUDED  */
+
 /* Copy the second part of user declarations.  */
 
-
-/* Line 216 of yacc.c.  */
-#line 315 "parse-gram.c"
+/* Line 379 of yacc.c  */
+#line 393 "parse-gram.c"
 
 #ifdef short
 # undef short
@@ -361,70 +439,46 @@
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
 #endif
 
 /* Identity function, used to suppress warnings about constant conditions.  */
 #ifndef lint
-# define YYID(n) (n)
+# define YYID(N) (N)
 #else
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int i)
+YYID (int yyi)
 #else
 static int
-YYID (i)
-    int i;
+YYID (yyi)
+    int yyi;
 #endif
 {
-  return i;
+  return yyi;
 }
 #endif
 
-#if ! defined yyoverflow || YYERROR_VERBOSE
+#if 1
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
 
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
 # ifdef YYSTACK_ALLOC
    /* Pacify GCC's `empty if-body' warning.  */
 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
@@ -441,43 +495,44 @@
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 # endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+# define YYCOPY_NEEDED 1
+#endif
 
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
-	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+	 || (defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL \
+	     && defined GRAM_STYPE_IS_TRIVIAL && GRAM_STYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss;
-  YYSTYPE yyvs;
-    YYLTYPE yyls;
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+  YYLTYPE yyls_alloc;
 };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
@@ -489,35 +544,19 @@
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
       + 2 * YYSTACK_GAP_MAXIMUM)
 
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)		\
-      do					\
-	{					\
-	  YYSIZE_T yyi;				\
-	  for (yyi = 0; yyi < (Count); yyi++)	\
-	    (To)[yyi] = (From)[yyi];		\
-	}					\
-      while (YYID (0))
-#  endif
-# endif
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack)					\
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
     do									\
       {									\
 	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack, Stack, yysize);				\
-	Stack = &yyptr->Stack;						\
+	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
+	Stack = &yyptr->Stack_alloc;					\
 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 	yyptr += yynewbytes / sizeof (*yyptr);				\
       }									\
@@ -525,23 +564,43 @@
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   161
+#define YYLAST   160
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  52
+#define YYNTOKENS  58
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  26
+#define YYNNTS  34
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  82
+#define YYNRULES  108
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  111
+#define YYNSTATES  148
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   306
+#define YYMAXUTOK   312
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -579,90 +638,105 @@
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
-      45,    46,    47,    48,    49,    50,    51
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57
 };
 
-#if YYDEBUG
+#if GRAM_DEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
-static const yytype_uint8 yyprhs[] =
+static const yytype_uint16 yyprhs[] =
 {
-       0,     0,     3,     8,     9,    12,    14,    16,    18,    21,
-      25,    27,    29,    32,    35,    39,    41,    43,    45,    47,
-      51,    53,    55,    59,    61,    63,    66,    69,    71,    73,
-      75,    77,    79,    81,    84,    86,    89,    92,    94,    96,
-      97,   101,   102,   106,   110,   114,   116,   118,   120,   121,
-     123,   125,   128,   130,   132,   135,   138,   142,   144,   147,
-     149,   152,   154,   157,   160,   161,   165,   167,   171,   174,
-     175,   178,   181,   185,   189,   193,   195,   197,   198,   201,
-     203,   205,   206
+       0,     0,     3,     8,     9,    12,    14,    16,    18,    22,
+      24,    27,    29,    32,    35,    38,    42,    44,    47,    50,
+      53,    55,    58,    62,    64,    66,    69,    73,    76,    78,
+      81,    84,    86,    88,    90,    92,    94,    96,    99,   103,
+     107,   109,   111,   114,   118,   119,   121,   125,   126,   130,
+     131,   135,   139,   143,   145,   147,   149,   150,   152,   154,
+     157,   159,   162,   164,   167,   169,   172,   174,   176,   178,
+     180,   182,   184,   187,   190,   194,   196,   199,   201,   204,
+     206,   209,   212,   213,   218,   220,   224,   227,   228,   232,
+     236,   240,   244,   248,   249,   251,   253,   255,   256,   258,
+     260,   262,   264,   266,   268,   270,   272,   274,   275
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      53,     0,    -1,    54,    48,    66,    77,    -1,    -1,    54,
-      55,    -1,    56,    -1,    49,    -1,    17,    -1,    19,    76,
-      -1,    19,    76,    76,    -1,    20,    -1,    21,    -1,    22,
-       4,    -1,    23,     4,    -1,    24,    43,    76,    -1,    25,
-      -1,    26,    -1,    27,    -1,    28,    -1,    29,    43,    76,
-      -1,    31,    -1,    32,    -1,    33,    43,    76,    -1,    34,
-      -1,    35,    -1,    36,    76,    -1,    37,    76,    -1,    39,
-      -1,    40,    -1,    41,    -1,    44,    -1,    60,    -1,    57,
-      -1,    38,    72,    -1,    10,    -1,     8,    63,    -1,     9,
-      63,    -1,    18,    -1,    30,    -1,    -1,     6,    58,    65,
-      -1,    -1,     5,    59,    65,    -1,     7,    42,    63,    -1,
-      61,    62,    63,    -1,    11,    -1,    12,    -1,    13,    -1,
-      -1,    42,    -1,    72,    -1,    63,    72,    -1,    42,    -1,
-      46,    -1,    46,     4,    -1,    46,    75,    -1,    46,     4,
-      75,    -1,    64,    -1,    65,    64,    -1,    67,    -1,    66,
-      67,    -1,    68,    -1,    56,    44,    -1,     1,    44,    -1,
-      -1,    47,    69,    70,    -1,    71,    -1,    70,    45,    71,
-      -1,    70,    44,    -1,    -1,    71,    72,    -1,    71,    73,
-      -1,    71,    14,    72,    -1,    71,    15,     4,    -1,    71,
-      16,    42,    -1,    46,    -1,    75,    -1,    -1,    74,    51,
-      -1,     3,    -1,     3,    -1,    -1,    48,    50,    -1
+      59,     0,    -1,    60,    50,    77,    91,    -1,    -1,    60,
+      61,    -1,    62,    -1,    52,    -1,    17,    -1,    19,    84,
+      85,    -1,    20,    -1,    20,     3,    -1,    21,    -1,    22,
+       4,    -1,    23,     4,    -1,    24,     3,    -1,    24,    47,
+       3,    -1,    25,    -1,    26,    43,    -1,    27,     3,    -1,
+      28,    43,    -1,    29,    -1,    30,     3,    -1,    30,    47,
+       3,    -1,    32,    -1,    33,    -1,    34,     3,    -1,    34,
+      47,     3,    -1,    35,    43,    -1,    36,    -1,    37,     3,
+      -1,    38,     3,    -1,    40,    -1,    41,    -1,    42,    -1,
+      53,    -1,    67,    -1,    64,    -1,    39,    89,    -1,     8,
+      43,    73,    -1,     9,    43,    73,    -1,    18,    -1,    31,
+      -1,    16,    86,    -1,    16,    48,    86,    -1,    -1,    48,
+      -1,    57,    63,    86,    -1,    -1,     6,    65,    76,    -1,
+      -1,     5,    66,    76,    -1,     7,    54,    72,    -1,    68,
+      69,    70,    -1,    10,    -1,    11,    -1,    12,    -1,    -1,
+      54,    -1,    71,    -1,    70,    71,    -1,    89,    -1,    89,
+       4,    -1,    89,    -1,    72,    89,    -1,    74,    -1,    73,
+      74,    -1,    89,    -1,    54,    -1,    55,    -1,    56,    -1,
+      54,    -1,    87,    -1,    87,     4,    -1,    87,    90,    -1,
+      87,     4,    90,    -1,    75,    -1,    76,    75,    -1,    78,
+      -1,    77,    78,    -1,    79,    -1,    62,    53,    -1,     1,
+      53,    -1,    -1,    88,    83,    80,    81,    -1,    82,    -1,
+      81,    51,    82,    -1,    81,    53,    -1,    -1,    82,    89,
+      83,    -1,    82,    43,    83,    -1,    82,    13,    89,    -1,
+      82,    14,     4,    -1,    82,    15,    54,    -1,    -1,    44,
+      -1,    48,    -1,     3,    -1,    -1,    48,    -1,     3,    -1,
+      43,    -1,    48,    -1,    45,    -1,    49,    -1,    87,    -1,
+      90,    -1,     3,    -1,    -1,    50,    46,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   202,   202,   210,   212,   216,   217,   218,   219,   224,
-     225,   226,   227,   228,   229,   230,   235,   239,   240,   241,
-     242,   243,   244,   245,   246,   247,   248,   249,   250,   251,
-     252,   256,   257,   258,   262,   278,   285,   292,   296,   303,
-     303,   308,   308,   313,   323,   338,   339,   340,   344,   345,
-     351,   352,   357,   361,   366,   372,   378,   389,   390,   399,
-     400,   406,   407,   408,   415,   415,   419,   420,   421,   426,
-     427,   429,   430,   432,   434,   439,   440,   456,   456,   462,
-     471,   476,   478
+       0,   230,   230,   238,   240,   244,   245,   255,   256,   261,
+     262,   267,   268,   269,   270,   271,   272,   277,   286,   287,
+     288,   289,   290,   291,   292,   293,   294,   295,   296,   311,
+     312,   336,   337,   338,   339,   343,   344,   345,   349,   361,
+     373,   377,   381,   388,   403,   404,   408,   420,   420,   425,
+     425,   430,   441,   456,   457,   458,   462,   463,   468,   470,
+     475,   476,   481,   483,   488,   489,   493,   494,   495,   496,
+     501,   506,   511,   517,   523,   534,   535,   544,   545,   551,
+     552,   553,   560,   560,   568,   569,   570,   575,   577,   579,
+     581,   583,   585,   590,   592,   603,   604,   609,   610,   611,
+     620,   640,   642,   651,   656,   657,   662,   669,   671
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if GRAM_DEBUG || YYERROR_VERBOSE || 1
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
   "\"end of file\"", "error", "$undefined", "\"string\"", "\"integer\"",
-  "\"%token\"", "\"%nterm\"", "\"%type\"", "\"%destructor {...}\"",
-  "\"%printer {...}\"", "\"%union {...}\"", "\"%left\"", "\"%right\"",
-  "\"%nonassoc\"", "\"%prec\"", "\"%dprec\"", "\"%merge\"", "\"%debug\"",
+  "\"%token\"", "\"%nterm\"", "\"%type\"", "\"%destructor\"",
+  "\"%printer\"", "\"%left\"", "\"%right\"", "\"%nonassoc\"", "\"%prec\"",
+  "\"%dprec\"", "\"%merge\"", "\"%code\"", "\"%debug\"",
   "\"%default-prec\"", "\"%define\"", "\"%defines\"", "\"%error-verbose\"",
   "\"%expect\"", "\"%expect-rr\"", "\"%file-prefix\"", "\"%glr-parser\"",
-  "\"%initial-action {...}\"", "\"%lex-param {...}\"", "\"%locations\"",
-  "\"%name-prefix\"", "\"%no-default-prec\"", "\"%no-lines\"",
-  "\"%nondeterministic-parser\"", "\"%output\"", "\"%parse-param {...}\"",
-  "\"%pure-parser\"", "\"%require\"", "\"%skeleton\"", "\"%start\"",
-  "\"%token-table\"", "\"%verbose\"", "\"%yacc\"", "\"type\"", "\"=\"",
-  "\";\"", "\"|\"", "\"identifier\"", "\"identifier:\"", "\"%%\"",
-  "\"%{...%}\"", "\"epilogue\"", "\"{...}\"", "$accept", "input",
-  "declarations", "declaration", "grammar_declaration",
-  "symbol_declaration", "@1", "@2", "precedence_declaration",
-  "precedence_declarator", "type.opt", "symbols.1", "symbol_def",
-  "symbol_defs.1", "grammar", "rules_or_grammar_declaration", "rules",
-  "@3", "rhses.1", "rhs", "symbol", "action", "@4", "string_as_id",
-  "string_content", "epilogue.opt", 0
+  "\"%initial-action\"", "\"%language\"", "\"%lex-param\"",
+  "\"%locations\"", "\"%name-prefix\"", "\"%no-default-prec\"",
+  "\"%no-lines\"", "\"%nondeterministic-parser\"", "\"%output\"",
+  "\"%parse-param\"", "\"%pure-parser\"", "\"%require\"", "\"%skeleton\"",
+  "\"%start\"", "\"%token-table\"", "\"%verbose\"", "\"%yacc\"",
+  "\"{...}\"", "\"[identifier]\"", "\"char\"", "\"epilogue\"", "\"=\"",
+  "\"identifier\"", "\"identifier:\"", "\"%%\"", "\"|\"", "\"%{...%}\"",
+  "\";\"", "\"type\"", "\"<*>\"", "\"<>\"", "\"%union\"", "$accept",
+  "input", "prologue_declarations", "prologue_declaration",
+  "grammar_declaration", "union_name", "symbol_declaration", "$@1", "$@2",
+  "precedence_declaration", "precedence_declarator", "type.opt",
+  "symbols.prec", "symbol.prec", "symbols.1", "generic_symlist",
+  "generic_symlist_item", "symbol_def", "symbol_defs.1", "grammar",
+  "rules_or_grammar_declaration", "rules", "$@3", "rhses.1", "rhs",
+  "named_ref.opt", "variable", "content.opt", "braceless", "id",
+  "id_colon", "symbol", "string_as_id", "epilogue.opt", YY_NULL
 };
 #endif
 
@@ -676,155 +750,175 @@
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
      295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
-     305,   306
+     305,   306,   307,   308,   309,   310,   311,   312
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    52,    53,    54,    54,    55,    55,    55,    55,    55,
-      55,    55,    55,    55,    55,    55,    55,    55,    55,    55,
-      55,    55,    55,    55,    55,    55,    55,    55,    55,    55,
-      55,    56,    56,    56,    56,    56,    56,    56,    56,    58,
-      57,    59,    57,    57,    60,    61,    61,    61,    62,    62,
-      63,    63,    64,    64,    64,    64,    64,    65,    65,    66,
-      66,    67,    67,    67,    69,    68,    70,    70,    70,    71,
-      71,    71,    71,    71,    71,    72,    72,    74,    73,    75,
-      76,    77,    77
+       0,    58,    59,    60,    60,    61,    61,    61,    61,    61,
+      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
+      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
+      61,    61,    61,    61,    61,    62,    62,    62,    62,    62,
+      62,    62,    62,    62,    63,    63,    62,    65,    64,    66,
+      64,    64,    67,    68,    68,    68,    69,    69,    70,    70,
+      71,    71,    72,    72,    73,    73,    74,    74,    74,    74,
+      75,    75,    75,    75,    75,    76,    76,    77,    77,    78,
+      78,    78,    80,    79,    81,    81,    81,    82,    82,    82,
+      82,    82,    82,    83,    83,    84,    84,    85,    85,    85,
+      86,    87,    87,    88,    89,    89,    90,    91,    91
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     4,     0,     2,     1,     1,     1,     2,     3,
-       1,     1,     2,     2,     3,     1,     1,     1,     1,     3,
-       1,     1,     3,     1,     1,     2,     2,     1,     1,     1,
-       1,     1,     1,     2,     1,     2,     2,     1,     1,     0,
-       3,     0,     3,     3,     3,     1,     1,     1,     0,     1,
-       1,     2,     1,     1,     2,     2,     3,     1,     2,     1,
-       2,     1,     2,     2,     0,     3,     1,     3,     2,     0,
-       2,     2,     3,     3,     3,     1,     1,     0,     2,     1,
-       1,     0,     2
+       0,     2,     4,     0,     2,     1,     1,     1,     3,     1,
+       2,     1,     2,     2,     2,     3,     1,     2,     2,     2,
+       1,     2,     3,     1,     1,     2,     3,     2,     1,     2,
+       2,     1,     1,     1,     1,     1,     1,     2,     3,     3,
+       1,     1,     2,     3,     0,     1,     3,     0,     3,     0,
+       3,     3,     3,     1,     1,     1,     0,     1,     1,     2,
+       1,     2,     1,     2,     1,     2,     1,     1,     1,     1,
+       1,     1,     2,     2,     3,     1,     2,     1,     2,     1,
+       2,     2,     0,     4,     1,     3,     2,     0,     3,     3,
+       3,     3,     3,     0,     1,     1,     1,     0,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     0,     2
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       3,     0,     0,     1,    41,    39,     0,     0,     0,    34,
-      45,    46,    47,     7,    37,     0,    10,    11,     0,     0,
-       0,    15,    16,    17,    18,     0,    38,    20,    21,     0,
-      23,    24,     0,     0,     0,    27,    28,    29,    30,     0,
-       6,     4,     5,    32,    31,    48,     0,     0,     0,    79,
-      75,    35,    50,    76,    36,    80,     8,    12,    13,     0,
-       0,     0,    25,    26,    33,     0,    64,     0,     0,    59,
-      61,    49,     0,    52,    53,    57,    42,    40,    43,    51,
-       9,    14,    19,    22,    63,    69,    62,     0,    60,     2,
-      44,    54,    55,    58,    65,    66,    82,    56,    68,    69,
-       0,     0,     0,    70,    71,     0,    67,    72,    73,    74,
-      78
+       3,     0,     0,     1,    49,    47,     0,     0,     0,    53,
+      54,    55,     0,     7,    40,     0,     9,    11,     0,     0,
+       0,    16,     0,     0,     0,    20,     0,    41,    23,    24,
+       0,     0,    28,     0,     0,     0,    31,    32,    33,     0,
+       6,    34,    44,     4,     5,    36,    35,    56,     0,     0,
+       0,     0,     0,   100,     0,    42,    96,    95,    97,    10,
+      12,    13,    14,     0,    17,    18,    19,    21,     0,    25,
+       0,    27,    29,    30,   106,   102,   101,   104,    37,   105,
+       0,   103,     0,     0,    77,    79,    93,    45,     0,    57,
+       0,    70,    75,    50,    71,    48,    51,    62,    67,    68,
+      69,    38,    64,    66,    39,    43,    99,    98,     8,    15,
+      22,    26,    81,    80,     0,    78,     2,    94,    82,    46,
+      52,    58,    60,    76,    72,    73,    63,    65,   108,    87,
+      59,    61,    74,    83,    84,    87,    86,     0,     0,     0,
+      93,    93,    85,    90,    91,    92,    89,    88
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int8 yydefgoto[] =
+static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     2,    41,    67,    43,    47,    46,    44,    45,
-      72,    51,    75,    76,    68,    69,    70,    85,    94,    95,
-      52,   104,   105,    53,    56,    89
+      -1,     1,     2,    43,    82,    88,    45,    49,    48,    46,
+      47,    90,   120,   121,    96,   101,   102,    92,    93,    83,
+      84,    85,   129,   133,   134,   118,    58,   108,    55,    77,
+      86,   103,    79,   116
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -69
-static const yytype_int8 yypact[] =
+#define YYPACT_NINF -91
+static const yytype_int16 yypact[] =
 {
-     -69,     5,   112,   -69,   -69,   -69,   -35,     0,     0,   -69,
-     -69,   -69,   -69,   -69,   -69,    13,   -69,   -69,    20,    31,
-     -18,   -69,   -69,   -69,   -69,    -6,   -69,   -69,   -69,    -5,
-     -69,   -69,    13,    13,     0,   -69,   -69,   -69,   -69,    69,
-     -69,   -69,   -69,   -69,   -69,    -2,   -38,   -38,     0,   -69,
-     -69,     0,   -69,   -69,     0,   -69,    13,   -69,   -69,    13,
-      13,    13,   -69,   -69,   -69,    -8,   -69,     3,    21,   -69,
-     -69,   -69,     0,   -69,     6,   -69,   -38,   -38,     0,   -69,
-     -69,   -69,   -69,   -69,   -69,   -69,   -69,     2,   -69,   -69,
-       0,    39,   -69,   -69,   -33,    -1,   -69,   -69,   -69,   -69,
-       0,    44,     1,   -69,   -69,     4,    -1,   -69,   -69,   -69,
-     -69
+     -91,     3,   103,   -91,   -91,   -91,   -36,     2,    10,   -91,
+     -91,   -91,     9,   -91,   -91,    32,    60,   -91,    65,    67,
+      27,   -91,    41,    73,    51,   -91,    39,   -91,   -91,   -91,
+      40,    52,   -91,    93,    95,    33,   -91,   -91,   -91,    15,
+     -91,   -91,    53,   -91,   -91,   -91,   -91,    46,    43,    43,
+      33,    11,    11,   -91,    61,   -91,   -91,   -91,    35,   -91,
+     -91,   -91,   -91,   100,   -91,   -91,   -91,   -91,   102,   -91,
+     113,   -91,   -91,   -91,   -91,   -91,   -91,   -91,   -91,   -91,
+      64,   -91,    94,     1,   -91,   -91,    62,   -91,    61,   -91,
+      33,   -91,   -91,    43,    86,    43,    33,   -91,   -91,   -91,
+     -91,    11,   -91,   -91,    11,   -91,   -91,   -91,   -91,   -91,
+     -91,   -91,   -91,   -91,    72,   -91,   -91,   -91,   -91,   -91,
+      33,   -91,   142,   -91,   145,   -91,   -91,   -91,   -91,   -91,
+     -91,   -91,   -91,    17,    34,   -91,   -91,    33,   146,    97,
+      62,    62,    34,   -91,   -91,   -91,   -91,   -91
 };
 
 /* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
+static const yytype_int16 yypgoto[] =
 {
-     -69,   -69,   -69,   -69,    47,   -69,   -69,   -69,   -69,   -69,
-     -69,    -7,   -58,     7,   -69,   -15,   -69,   -69,   -69,   -42,
-     -34,   -69,   -69,   -68,    30,   -69
+     -91,   -91,   -91,   -91,   147,   -91,   -91,   -91,   -91,   -91,
+     -91,   -91,   -91,    37,   -91,   106,   -60,   -33,   105,   -91,
+      69,   -91,   -91,   -91,    24,   -48,   -91,   -91,   -49,   -20,
+     -91,   -35,   -90,   -91
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -82
-static const yytype_int8 yytable[] =
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -108
+static const yytype_int16 yytable[] =
 {
-      64,    54,    49,    49,    73,     3,    92,    48,    74,    49,
-      91,    98,    99,   100,   101,   102,    55,    79,    93,    93,
-      79,   -81,    65,    97,    57,    59,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    58,    84,    60,    61,    14,
-      71,    78,    49,   109,    79,    50,    50,    86,   108,    42,
-     -77,    26,    96,    88,    77,   110,    79,   106,     0,    34,
-       0,   103,    62,    63,     0,    90,   107,     0,    66,    87,
-      65,     0,   103,     0,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,     0,     0,     0,    80,    14,     0,    81,
-      82,    83,     0,     0,     0,     0,     0,     0,     0,    26,
-       0,     0,     0,     0,     0,     0,     0,    34,     0,     0,
-       0,     0,     0,     0,     0,     0,    66,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,     0,     0,     0,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
-      34,    35,    36,    37,     0,     0,    38,     0,     0,     0,
-      39,    40
+      78,  -107,    80,     3,   125,   105,     4,     5,     6,     7,
+       8,     9,    10,    11,    74,    97,    80,    12,    50,    14,
+       4,     5,     6,     7,     8,     9,    10,    11,    94,    94,
+      62,    12,    27,    14,   132,    56,    74,    74,   106,   119,
+      35,   127,    67,    69,   127,    51,    27,   137,   138,   139,
+      81,   114,    53,    52,    35,   122,    75,    54,    42,    76,
+     123,   126,   123,    59,    81,    98,    99,   100,   135,    60,
+     136,    61,    42,    94,    63,    94,    65,   140,    75,    75,
+      57,    76,    76,   107,    64,   122,    68,    70,    75,    74,
+     124,    76,   146,   147,    66,    71,    72,    91,    73,   141,
+      89,    87,   143,   109,    53,   110,   117,   141,     4,     5,
+       6,     7,     8,     9,    10,    11,   111,   112,   128,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,   131,   113,    74,    44,
+     144,   145,   115,    39,    95,    40,    41,   130,   104,   142,
+      42
 };
 
-static const yytype_int8 yycheck[] =
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-91)))
+
+#define yytable_value_is_error(Yytable_value) \
+  YYID (0)
+
+static const yytype_uint8 yycheck[] =
 {
-      34,     8,     3,     3,    42,     0,    74,    42,    46,     3,
-       4,    44,    45,    14,    15,    16,     3,    51,    76,    77,
-      54,     0,     1,    91,     4,    43,     5,     6,     7,     8,
-       9,    10,    11,    12,    13,     4,    44,    43,    43,    18,
-      42,    48,     3,    42,    78,    46,    46,    44,     4,     2,
-      51,    30,    50,    68,    47,    51,    90,    99,    -1,    38,
-      -1,    95,    32,    33,    -1,    72,   100,    -1,    47,    48,
-       1,    -1,   106,    -1,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    -1,    -1,    -1,    56,    18,    -1,    59,
-      60,    61,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    30,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    38,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    47,     5,     6,     7,
-       8,     9,    10,    11,    12,    13,    -1,    -1,    -1,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,    39,    40,    41,    -1,    -1,    44,    -1,    -1,    -1,
-      48,    49
+      35,     0,     1,     0,    94,    54,     5,     6,     7,     8,
+       9,    10,    11,    12,     3,    50,     1,    16,    54,    18,
+       5,     6,     7,     8,     9,    10,    11,    12,    48,    49,
+       3,    16,    31,    18,   124,     3,     3,     3,     3,    88,
+      39,   101,     3,     3,   104,    43,    31,    13,    14,    15,
+      49,    50,    43,    43,    39,    90,    45,    48,    57,    48,
+      93,    96,    95,     3,    49,    54,    55,    56,    51,     4,
+      53,     4,    57,    93,    47,    95,     3,    43,    45,    45,
+      48,    48,    48,    48,    43,   120,    47,    47,    45,     3,
+       4,    48,   140,   141,    43,    43,     3,    54,     3,   134,
+      54,    48,   137,     3,    43,     3,    44,   142,     5,     6,
+       7,     8,     9,    10,    11,    12,     3,    53,    46,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,    40,    41,    42,     4,    53,     3,     2,
+       4,    54,    83,    50,    49,    52,    53,   120,    52,   135,
+      57
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    53,    54,     0,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    17,    18,    19,    20,    21,    22,    23,
+       0,    59,    60,     0,     5,     6,     7,     8,     9,    10,
+      11,    12,    16,    17,    18,    19,    20,    21,    22,    23,
       24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
-      34,    35,    36,    37,    38,    39,    40,    41,    44,    48,
-      49,    55,    56,    57,    60,    61,    59,    58,    42,     3,
-      46,    63,    72,    75,    63,     3,    76,     4,     4,    43,
-      43,    43,    76,    76,    72,     1,    47,    56,    66,    67,
-      68,    42,    62,    42,    46,    64,    65,    65,    63,    72,
-      76,    76,    76,    76,    44,    69,    44,    48,    67,    77,
-      63,     4,    75,    64,    70,    71,    50,    75,    44,    45,
-      14,    15,    16,    72,    73,    74,    71,    72,     4,    42,
-      51
+      34,    35,    36,    37,    38,    39,    40,    41,    42,    50,
+      52,    53,    57,    61,    62,    64,    67,    68,    66,    65,
+      54,    43,    43,    43,    48,    86,     3,    48,    84,     3,
+       4,     4,     3,    47,    43,     3,    43,     3,    47,     3,
+      47,    43,     3,     3,     3,    45,    48,    87,    89,    90,
+       1,    49,    62,    77,    78,    79,    88,    48,    63,    54,
+      69,    54,    75,    76,    87,    76,    72,    89,    54,    55,
+      56,    73,    74,    89,    73,    86,     3,    48,    85,     3,
+       3,     3,    53,    53,    50,    78,    91,    44,    83,    86,
+      70,    71,    89,    75,     4,    90,    89,    74,    46,    80,
+      71,     4,    90,    81,    82,    51,    53,    13,    14,    15,
+      43,    89,    82,    89,     4,    54,    83,    83
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -839,30 +933,40 @@
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
 
 #define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)					\
-do								\
-  if (yychar == YYEMPTY && yylen == 1)				\
-    {								\
-      yychar = (Token);						\
-      yylval = (Value);						\
-      yytoken = YYTRANSLATE (yychar);				\
-      YYPOPSTACK (1);						\
-      goto yybackup;						\
-    }								\
-  else								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      YY_LAC_DISCARD ("YYBACKUP");                              \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (YY_("syntax error: cannot back up")); \
       YYERROR;							\
     }								\
 while (YYID (0))
 
-
+/* Error token number */
 #define YYTERROR	1
 #define YYERRCODE	256
 
@@ -871,38 +975,43 @@
    If N is 0, then set CURRENT to the empty location which ends
    the previous symbol: RHS[0] (always defined).  */
 
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
 #ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)				\
-    do									\
-      if (YYID (N))                                                    \
-	{								\
-	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
-	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
-	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
-	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
-	}								\
-      else								\
-	{								\
-	  (Current).first_line   = (Current).last_line   =		\
-	    YYRHSLOC (Rhs, 0).last_line;				\
-	  (Current).first_column = (Current).last_column =		\
-	    YYRHSLOC (Rhs, 0).last_column;				\
-	}								\
+# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
+    do                                                                  \
+      if (YYID (N))                                                     \
+        {                                                               \
+          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).first_line   = (Current).last_line   =              \
+            YYRHSLOC (Rhs, 0).last_line;                                \
+          (Current).first_column = (Current).last_column =              \
+            YYRHSLOC (Rhs, 0).last_column;                              \
+        }                                                               \
     while (YYID (0))
 #endif
 
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
 
 /* YY_LOCATION_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 YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)			\
-     fprintf (File, "%d.%d-%d.%d",			\
-	      (Loc).first_line, (Loc).first_column,	\
-	      (Loc).last_line,  (Loc).last_column)
+# if defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                                   \
+  do {                                                                   \
+    fprintf (File, "%d.%d", (Loc).first_line, (Loc).first_column);       \
+    if ((Loc).first_line < (Loc).last_line)                              \
+      fprintf (File, "-%d.%d", (Loc).last_line,  (Loc).last_column - 1); \
+    else if ((Loc).first_column < (Loc).last_column - 1)                 \
+      fprintf (File, "-%d", (Loc).last_column - 1);                      \
+  } while (0)
 # else
 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 # endif
@@ -910,7 +1019,6 @@
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
-
 #ifdef YYLEX_PARAM
 # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
 #else
@@ -918,7 +1026,7 @@
 #endif
 
 /* Enable debugging if requested.  */
-#if YYDEBUG
+#if GRAM_DEBUG
 
 # ifndef YYFPRINTF
 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
@@ -961,6 +1069,8 @@
     YYLTYPE const * const yylocationp;
 #endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
   if (!yyvaluep)
     return;
   YYUSE (yylocationp);
@@ -972,85 +1082,131 @@
 # endif
   switch (yytype)
     {
-      case 3: /* "\"string\"" */
-#line 179 "parse-gram.y"
-	{ fprintf (stderr, "\"%s\"", (yyvaluep->chars)); };
-#line 979 "parse-gram.c"
+      case 3: /* "string" */
+/* Line 812 of yacc.c  */
+#line 205 "parse-gram.y"
+	{ fputs (quotearg_style (c_quoting_style, ((*yyvaluep).chars)), stderr); };
+/* Line 812 of yacc.c  */
+#line 1091 "parse-gram.c"
 	break;
-      case 4: /* "\"integer\"" */
-#line 192 "parse-gram.y"
-	{ fprintf (stderr, "%d", (yyvaluep->integer)); };
-#line 984 "parse-gram.c"
+      case 4: /* "integer" */
+/* Line 812 of yacc.c  */
+#line 217 "parse-gram.y"
+	{ fprintf (stderr, "%d", ((*yyvaluep).integer)); };
+/* Line 812 of yacc.c  */
+#line 1098 "parse-gram.c"
 	break;
-      case 8: /* "\"%destructor {...}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 989 "parse-gram.c"
+      case 43: /* "{...}" */
+/* Line 812 of yacc.c  */
+#line 207 "parse-gram.y"
+	{ fprintf (stderr, "{\n%s\n}", ((*yyvaluep).code)); };
+/* Line 812 of yacc.c  */
+#line 1105 "parse-gram.c"
 	break;
-      case 9: /* "\"%printer {...}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 994 "parse-gram.c"
+      case 44: /* "[identifier]" */
+/* Line 812 of yacc.c  */
+#line 212 "parse-gram.y"
+	{ fprintf (stderr, "[%s]", ((*yyvaluep).uniqstr)); };
+/* Line 812 of yacc.c  */
+#line 1112 "parse-gram.c"
 	break;
-      case 10: /* "\"%union {...}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 999 "parse-gram.c"
+      case 45: /* "char" */
+/* Line 812 of yacc.c  */
+#line 199 "parse-gram.y"
+	{ fputs (char_name (((*yyvaluep).character)), stderr); };
+/* Line 812 of yacc.c  */
+#line 1119 "parse-gram.c"
 	break;
-      case 26: /* "\"%initial-action {...}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 1004 "parse-gram.c"
+      case 46: /* "epilogue" */
+/* Line 812 of yacc.c  */
+#line 207 "parse-gram.y"
+	{ fprintf (stderr, "{\n%s\n}", ((*yyvaluep).chars)); };
+/* Line 812 of yacc.c  */
+#line 1126 "parse-gram.c"
 	break;
-      case 27: /* "\"%lex-param {...}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 1009 "parse-gram.c"
+      case 48: /* "identifier" */
+/* Line 812 of yacc.c  */
+#line 211 "parse-gram.y"
+	{ fputs (((*yyvaluep).uniqstr), stderr); };
+/* Line 812 of yacc.c  */
+#line 1133 "parse-gram.c"
 	break;
-      case 34: /* "\"%parse-param {...}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 1014 "parse-gram.c"
+      case 49: /* "identifier:" */
+/* Line 812 of yacc.c  */
+#line 213 "parse-gram.y"
+	{ fprintf (stderr, "%s:", ((*yyvaluep).uniqstr)); };
+/* Line 812 of yacc.c  */
+#line 1140 "parse-gram.c"
 	break;
-      case 42: /* "\"type\"" */
-#line 190 "parse-gram.y"
-	{ fprintf (stderr, "<%s>", (yyvaluep->uniqstr)); };
-#line 1019 "parse-gram.c"
+      case 52: /* "%{...%}" */
+/* Line 812 of yacc.c  */
+#line 207 "parse-gram.y"
+	{ fprintf (stderr, "{\n%s\n}", ((*yyvaluep).chars)); };
+/* Line 812 of yacc.c  */
+#line 1147 "parse-gram.c"
 	break;
-      case 46: /* "\"identifier\"" */
-#line 194 "parse-gram.y"
-	{ fprintf (stderr, "%s", (yyvaluep->symbol)->tag); };
-#line 1024 "parse-gram.c"
+      case 54: /* "type" */
+/* Line 812 of yacc.c  */
+#line 214 "parse-gram.y"
+	{ fprintf (stderr, "<%s>", ((*yyvaluep).uniqstr)); };
+/* Line 812 of yacc.c  */
+#line 1154 "parse-gram.c"
 	break;
-      case 47: /* "\"identifier:\"" */
-#line 196 "parse-gram.y"
-	{ fprintf (stderr, "%s:", (yyvaluep->symbol)->tag); };
-#line 1029 "parse-gram.c"
+      case 71: /* symbol.prec */
+/* Line 812 of yacc.c  */
+#line 220 "parse-gram.y"
+	{ fprintf (stderr, "%s", ((*yyvaluep).symbol)->tag); };
+/* Line 812 of yacc.c  */
+#line 1161 "parse-gram.c"
 	break;
-      case 49: /* "\"%{...%}\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 1034 "parse-gram.c"
+      case 84: /* variable */
+/* Line 812 of yacc.c  */
+#line 211 "parse-gram.y"
+	{ fputs (((*yyvaluep).uniqstr), stderr); };
+/* Line 812 of yacc.c  */
+#line 1168 "parse-gram.c"
 	break;
-      case 50: /* "\"epilogue\"" */
-#line 181 "parse-gram.y"
-	{ fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); };
-#line 1039 "parse-gram.c"
+      case 85: /* content.opt */
+/* Line 812 of yacc.c  */
+#line 207 "parse-gram.y"
+	{ fprintf (stderr, "{\n%s\n}", ((*yyvaluep).chars)); };
+/* Line 812 of yacc.c  */
+#line 1175 "parse-gram.c"
 	break;
-      case 72: /* "symbol" */
-#line 194 "parse-gram.y"
-	{ fprintf (stderr, "%s", (yyvaluep->symbol)->tag); };
-#line 1044 "parse-gram.c"
+      case 86: /* braceless */
+/* Line 812 of yacc.c  */
+#line 207 "parse-gram.y"
+	{ fprintf (stderr, "{\n%s\n}", ((*yyvaluep).chars)); };
+/* Line 812 of yacc.c  */
+#line 1182 "parse-gram.c"
 	break;
-      case 75: /* "string_as_id" */
-#line 194 "parse-gram.y"
-	{ fprintf (stderr, "%s", (yyvaluep->symbol)->tag); };
-#line 1049 "parse-gram.c"
+      case 87: /* id */
+/* Line 812 of yacc.c  */
+#line 220 "parse-gram.y"
+	{ fprintf (stderr, "%s", ((*yyvaluep).symbol)->tag); };
+/* Line 812 of yacc.c  */
+#line 1189 "parse-gram.c"
 	break;
-      case 76: /* "string_content" */
-#line 179 "parse-gram.y"
-	{ fprintf (stderr, "\"%s\"", (yyvaluep->chars)); };
-#line 1054 "parse-gram.c"
+      case 88: /* id_colon */
+/* Line 812 of yacc.c  */
+#line 221 "parse-gram.y"
+	{ fprintf (stderr, "%s:", ((*yyvaluep).symbol)->tag); };
+/* Line 812 of yacc.c  */
+#line 1196 "parse-gram.c"
+	break;
+      case 89: /* symbol */
+/* Line 812 of yacc.c  */
+#line 220 "parse-gram.y"
+	{ fprintf (stderr, "%s", ((*yyvaluep).symbol)->tag); };
+/* Line 812 of yacc.c  */
+#line 1203 "parse-gram.c"
+	break;
+      case 90: /* string_as_id */
+/* Line 812 of yacc.c  */
+#line 220 "parse-gram.y"
+	{ fprintf (stderr, "%s", ((*yyvaluep).symbol)->tag); };
+/* Line 812 of yacc.c  */
+#line 1210 "parse-gram.c"
 	break;
       default:
 	break;
@@ -1094,17 +1250,20 @@
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
 #else
 static void
-yy_stack_print (bottom, top)
-    yytype_int16 *bottom;
-    yytype_int16 *top;
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; bottom <= top; ++bottom)
-    YYFPRINTF (stderr, " %d", *bottom);
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
   YYFPRINTF (stderr, "\n");
 }
 
@@ -1139,11 +1298,11 @@
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      fprintf (stderr, "   $%d = ", yyi + 1);
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
 		       , &(yylsp[(yyi + 1) - (yynrhs)])		       );
-      fprintf (stderr, "\n");
+      YYFPRINTF (stderr, "\n");
     }
 }
 
@@ -1156,12 +1315,12 @@
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
 int yydebug;
-#else /* !YYDEBUG */
+#else /* !GRAM_DEBUG */
 # define YYDPRINTF(Args)
 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
 # define YY_STACK_PRINT(Bottom, Top)
 # define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
+#endif /* !GRAM_DEBUG */
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
@@ -1180,7 +1339,239 @@
 # define YYMAXDEPTH 10000
 #endif
 
-
+/* 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
+   stack, and such that *YYCAPACITY is the maximum number of elements it
+   can hold without a reallocation, make sure there is enough room to
+   store YYADD more elements.  If not, allocate a new stack using
+   YYSTACK_ALLOC, copy the existing elements, and adjust *YYBOTTOM,
+   *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.  */
+static int
+yy_lac_stack_realloc (YYSIZE_T *yycapacity, YYSIZE_T yyadd,
+#if GRAM_DEBUG
+                      char const *yydebug_prefix,
+                      char const *yydebug_suffix,
+#endif
+                      yytype_int16 **yybottom,
+                      yytype_int16 *yybottom_no_free,
+                      yytype_int16 **yytop, yytype_int16 *yytop_empty)
+{
+  YYSIZE_T yysize_old =
+    *yytop == yytop_empty ? 0 : *yytop - *yybottom + 1;
+  YYSIZE_T yysize_new = yysize_old + yyadd;
+  if (*yycapacity < yysize_new)
+    {
+      YYSIZE_T yyalloc = 2 * yysize_new;
+      yytype_int16 *yybottom_new;
+      /* Use YYMAXDEPTH for maximum stack size given that the stack
+         should never need to grow larger than the main state stack
+         needs to grow without LAC.  */
+      if (YYMAXDEPTH < yysize_new)
+        {
+          YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix,
+                      yydebug_suffix));
+          return 1;
+        }
+      if (YYMAXDEPTH < yyalloc)
+        yyalloc = YYMAXDEPTH;
+      yybottom_new =
+        (yytype_int16*) YYSTACK_ALLOC (yyalloc * sizeof *yybottom_new);
+      if (!yybottom_new)
+        {
+          YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix,
+                      yydebug_suffix));
+          return 1;
+        }
+      if (*yytop != yytop_empty)
+        {
+          YYCOPY (yybottom_new, *yybottom, yysize_old);
+          *yytop = yybottom_new + (yysize_old - 1);
+        }
+      if (*yybottom != yybottom_no_free)
+        YYSTACK_FREE (*yybottom);
+      *yybottom = yybottom_new;
+      *yycapacity = yyalloc;
+    }
+  return 0;
+}
+
+/* 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.
+
+   YY_LAC_ESTABLISH 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).  Iff there is a
+   lookahead token, it should also be invoked before reporting a syntax
+   error.  This latter case is for the sake of the debugging output.
+
+   For parse.lac=full, the implementation of YY_LAC_ESTABLISH 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.
+   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;                                         \
+      }                                                          \
+    }                                                            \
+} while (YYID (0))
+
+/* 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 GRAM_DEBUG
+# define YY_LAC_DISCARD(Event)                                           \
+do {                                                                     \
+  if (yy_lac_established)                                                \
+    {                                                                    \
+      if (yydebug)                                                       \
+        YYFPRINTF (stderr, "LAC: initial context discarded due to "      \
+                   Event "\n");                                          \
+      yy_lac_established = 0;                                            \
+    }                                                                    \
+} while (YYID (0))
+#else
+# define YY_LAC_DISCARD(Event) yy_lac_established = 0
+#endif
+
+/* 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
+   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
+   contents of either array, alter *YYES and *YYES_CAPACITY, and free
+   any old *YYES other than YYESA.  */
+static int
+yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
+        YYSIZE_T *yyes_capacity, yytype_int16 *yyssp, int yytoken)
+{
+  yytype_int16 *yyes_prev = yyssp;
+  yytype_int16 *yyesp = yyes_prev;
+  YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yytname[yytoken]));
+  if (yytoken == YYUNDEFTOK)
+    {
+      YYDPRINTF ((stderr, " Always Err\n"));
+      return 1;
+    }
+  while (1)
+    {
+      int yyrule = yypact[*yyesp];
+      if (yypact_value_is_default (yyrule)
+          || (yyrule += yytoken) < 0 || YYLAST < yyrule
+          || yycheck[yyrule] != yytoken)
+        {
+          yyrule = yydefact[*yyesp];
+          if (yyrule == 0)
+            {
+              YYDPRINTF ((stderr, " Err\n"));
+              return 1;
+            }
+        }
+      else
+        {
+          yyrule = yytable[yyrule];
+          if (yytable_value_is_error (yyrule))
+            {
+              YYDPRINTF ((stderr, " Err\n"));
+              return 1;
+            }
+          if (0 < yyrule)
+            {
+              YYDPRINTF ((stderr, " S%d\n", yyrule));
+              return 0;
+            }
+          yyrule = -yyrule;
+        }
+      {
+        YYSIZE_T yylen = yyr2[yyrule];
+        YYDPRINTF ((stderr, " R%d", yyrule - 1));
+        if (yyesp != yyes_prev)
+          {
+            YYSIZE_T yysize = yyesp - *yyes + 1;
+            if (yylen < yysize)
+              {
+                yyesp -= yylen;
+                yylen = 0;
+              }
+            else
+              {
+                yylen -= yysize;
+                yyesp = yyes_prev;
+              }
+          }
+        if (yylen)
+          yyesp = yyes_prev -= yylen;
+      }
+      {
+        int yystate;
+        {
+          int yylhs = yyr1[yyrule] - YYNTOKENS;
+          yystate = yypgoto[yylhs] + *yyesp;
+          if (yystate < 0 || YYLAST < yystate
+              || yycheck[yystate] != *yyesp)
+            yystate = yydefgoto[yylhs];
+          else
+            yystate = yytable[yystate];
+        }
+        if (yyesp == yyes_prev)
+          {
+            yyesp = *yyes;
+            *yyesp = yystate;
+          }
+        else
+          {
+            if (yy_lac_stack_realloc (yyes_capacity, 1,
+#if GRAM_DEBUG
+                                      " (", ")",
+#endif
+                                      yyes, yyesa, &yyesp, yyes_prev))
+              {
+                YYDPRINTF ((stderr, "\n"));
+                return 2;
+              }
+            *++yyesp = yystate;
+          }
+        YYDPRINTF ((stderr, " G%d", yystate));
+      }
+    }
+}
+
 
 #if YYERROR_VERBOSE
 
@@ -1283,115 +1674,147 @@
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
+/* 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.  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 or if
+   yy_lac returned 2.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyesa, yytype_int16 **yyes,
+                YYSIZE_T *yyes_capacity, yytype_int16 *yyssp, int yytoken)
 {
-  int yyn = yypact[yystate];
+  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  YYSIZE_T yysize1;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULL;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+  /* 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 check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) 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.
+       In the first two cases, it might appear that the current syntax
+       error should have been detected in the previous state when yy_lac
+       was invoked.  However, at that time, there might have been a
+       different syntax error that discarded a different initial context
+       during error recovery, leaving behind the current lookahead.
+  */
+  if (yytoken != YYEMPTY)
     {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
+      int yyn = yypact[*yyssp];
+      YYDPRINTF ((stderr, "Constructing syntax error message\n"));
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          int yyx;
 
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-	 constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+          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;
+                }
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+                if (! (yysize <= yysize1
+                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  return 2;
+                yysize = yysize1;
+              }
+        }
+# if GRAM_DEBUG
+      else if (yydebug)
+        YYFPRINTF (stderr, "No expected tokens.\n");
 # endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-		    + sizeof yyexpecting - 1
-		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-		       * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-	 YYCHECK.  */
-      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 yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-	  {
-	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-	      {
-		yycount = 1;
-		yysize = yysize0;
-		yyformat[sizeof yyunexpected - 1] = '\0';
-		break;
-	      }
-	    yyarg[yycount++] = yytname[yyx];
-	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-	    yysize_overflow |= (yysize1 < yysize);
-	    yysize = yysize1;
-	    yyfmt = yystpcpy (yyfmt, yyprefix);
-	    yyprefix = yyor;
-	  }
-
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
-
-      if (yysize_overflow)
-	return YYSIZE_MAXIMUM;
-
-      if (yyresult)
-	{
-	  /* Avoid sprintf, as that infringes on the user's name space.
-	     Don't have undefined behavior even if the translation
-	     produced a string with the wrong number of "%s"s.  */
-	  char *yyp = yyresult;
-	  int yyi = 0;
-	  while ((*yyp = *yyf) != '\0')
-	    {
-	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-		{
-		  yyp += yytnamerr (yyp, yyarg[yyi++]);
-		  yyf += 2;
-		}
-	      else
-		{
-		  yyp++;
-		  yyf++;
-		}
-	    }
-	}
-      return yysize;
     }
+
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      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_
+    }
+
+  yysize1 = yysize + yystrlen (yyformat);
+  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    return 2;
+  yysize = yysize1;
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
+    }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-
 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1425,25 +1848,6 @@
 	break;
     }
 }
-
-
-/* Prevent warnings from -Wmissing-prototypes.  */
-
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
 
 
 
@@ -1474,24 +1878,92 @@
 #endif
 #endif
 {
-  /* The look-ahead symbol.  */
+/* The lookahead symbol.  */
 int yychar;
 
-/* The semantic value of the look-ahead symbol.  */
-YYSTYPE yylval;
 
-/* Number of syntax errors so far.  */
-int yynerrs;
-/* Location data for the look-ahead symbol.  */
-YYLTYPE yylloc;
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+/* Default value used for initialization, for pacifying older GCCs
+   or non-GCC compilers.  */
+static YYSTYPE yyval_default;
+# define YY_INITIAL_VALUE(Value) = Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
 
-  int yystate;
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
+
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc
+# if defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL
+  = { 1, 1, 1, 1 }
+# endif
+;
+
+
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+       `yyls': related to locations.
+
+       Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[3];
+
+    YYSIZE_T yystacksize;
+
+    yytype_int16 yyesa[20];
+    yytype_int16 *yyes;
+    YYSIZE_T yyes_capacity;
+
+  int yy_lac_established = 0;
   int yyn;
   int yyresult;
-  /* Number of tokens to shift before error messages enabled.  */
-  int yyerrstatus;
-  /* Look-ahead token as an internal (translated) token number.  */
+  /* Lookahead token as an internal (translated) token number.  */
   int yytoken = 0;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
 #if YYERROR_VERBOSE
   /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
@@ -1499,77 +1971,40 @@
   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
 #endif
 
-  /* Three stacks and their tools:
-     `yyss': related to states,
-     `yyvs': related to semantic values,
-     `yyls': related to locations.
-
-     Refer to the stacks thru separate pointers, to allow yyoverflow
-     to reallocate them elsewhere.  */
-
-  /* The state stack.  */
-  yytype_int16 yyssa[YYINITDEPTH];
-  yytype_int16 *yyss = yyssa;
-  yytype_int16 *yyssp;
-
-  /* The semantic value stack.  */
-  YYSTYPE yyvsa[YYINITDEPTH];
-  YYSTYPE *yyvs = yyvsa;
-  YYSTYPE *yyvsp;
-
-  /* The location stack.  */
-  YYLTYPE yylsa[YYINITDEPTH];
-  YYLTYPE *yyls = yylsa;
-  YYLTYPE *yylsp;
-  /* The locations where the error started and ended.  */
-  YYLTYPE yyerror_range[2];
-
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
 
-  YYSIZE_T yystacksize = YYINITDEPTH;
-
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-  YYLTYPE yyloc;
-
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
+  yylsp = yyls = yylsa;
+  yystacksize = YYINITDEPTH;
+
+  yyes = yyesa;
+  yyes_capacity = sizeof yyesa / sizeof *yyes;
+  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.  */
+  yychar = YYEMPTY; /* Cause a token to be read.  */
 
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
-
-  yyssp = yyss;
-  yyvsp = yyvs;
-  yylsp = yyls;
-#if YYLTYPE_IS_TRIVIAL
-  /* Initialize the default location before parsing starts.  */
-  yylloc.first_line   = yylloc.last_line   = 1;
-  yylloc.first_column = yylloc.last_column = 0;
-#endif
-
-
-  /* User initialization code.  */
-#line 84 "parse-gram.y"
+/* User initialization code.  */
+/* Line 1560 of yacc.c  */
+#line 107 "parse-gram.y"
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
-  yylloc.start.file   = yylloc.end.file   = current_file;
-  yylloc.start.line   = yylloc.end.line   = 1;
-  yylloc.start.column = yylloc.end.column = 0;
+  boundary_set (&yylloc.start, current_file, 1, 1);
+  boundary_set (&yylloc.end, current_file, 1, 1);
 }
-/* Line 1078 of yacc.c.  */
-#line 1573 "parse-gram.c"
+/* Line 1560 of yacc.c  */
+#line 2008 "parse-gram.c"
   yylsp[0] = yylloc;
   goto yysetstate;
 
@@ -1607,6 +2042,7 @@
 		    &yyvs1, yysize * sizeof (*yyvsp),
 		    &yyls1, yysize * sizeof (*yylsp),
 		    &yystacksize);
+
 	yyls = yyls1;
 	yyss = yyss1;
 	yyvs = yyvs1;
@@ -1628,9 +2064,9 @@
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
 	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss);
-	YYSTACK_RELOCATE (yyvs);
-	YYSTACK_RELOCATE (yyls);
+	YYSTACK_RELOCATE (yyss_alloc, yyss);
+	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+	YYSTACK_RELOCATE (yyls_alloc, yyls);
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -1651,6 +2087,9 @@
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
   goto yybackup;
 
 /*-----------.
@@ -1659,16 +2098,16 @@
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     look-ahead token if we need one and don't already have one.  */
+     lookahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to look-ahead token.  */
+  /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
-  /* Not known => get a look-ahead token if don't already have one.  */
+  /* Not known => get a lookahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1690,33 +2129,36 @@
      detect an error, take that action.  */
   yyn += yytoken;
   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
+    {
+      YY_LAC_ESTABLISH;
+      goto yydefault;
+    }
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
+      YY_LAC_ESTABLISH;
       yyn = -yyn;
       goto yyreduce;
     }
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the look-ahead token.  */
+  /* Shift the lookahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token unless it is eof.  */
-  if (yychar != YYEOF)
-    yychar = YYEMPTY;
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+  YY_LAC_DISCARD ("shift");
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
   *++yylsp = yylloc;
   goto yynewstate;
 
@@ -1751,299 +2193,516 @@
   /* Default location.  */
   YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
   YY_REDUCE_PRINT (yyn);
-  switch (yyn)
+  {
+    int yychar_backup = yychar;
+    switch (yyn)
+      {
+          case 6:
+/* Line 1778 of yacc.c  */
+#line 246 "parse-gram.y"
     {
-        case 6:
-#line 217 "parse-gram.y"
-    { prologue_augment ((yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)])); }
+      code_props plain_code;
+      code_props_plain_init (&plain_code, (yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)]));
+      code_props_translate_code (&plain_code);
+      gram_scanner_last_string_free ();
+      muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
+                        plain_code.code, (yylsp[(1) - (1)]));
+      code_scanner_last_string_free ();
+    }
     break;
 
   case 7:
-#line 218 "parse-gram.y"
-    { debug_flag = true; }
+/* Line 1778 of yacc.c  */
+#line 255 "parse-gram.y"
+    { debug = true; }
     break;
 
   case 8:
-#line 220 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 257 "parse-gram.y"
     {
-      static char one[] = "1";
-      muscle_insert ((yyvsp[(2) - (2)].chars), one);
+      muscle_percent_define_insert ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars),
+                                    MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
     }
     break;
 
   case 9:
-#line 224 "parse-gram.y"
-    { muscle_insert ((yyvsp[(2) - (3)].chars), (yyvsp[(3) - (3)].chars)); }
-    break;
-
-  case 10:
-#line 225 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 261 "parse-gram.y"
     { defines_flag = true; }
     break;
 
+  case 10:
+/* Line 1778 of yacc.c  */
+#line 263 "parse-gram.y"
+    {
+      defines_flag = true;
+      spec_defines_file = xstrdup ((yyvsp[(2) - (2)].chars));
+    }
+    break;
+
   case 11:
-#line 226 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 267 "parse-gram.y"
     { error_verbose = true; }
     break;
 
   case 12:
-#line 227 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 268 "parse-gram.y"
     { expected_sr_conflicts = (yyvsp[(2) - (2)].integer); }
     break;
 
   case 13:
-#line 228 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 269 "parse-gram.y"
     { expected_rr_conflicts = (yyvsp[(2) - (2)].integer); }
     break;
 
   case 14:
-#line 229 "parse-gram.y"
-    { spec_file_prefix = (yyvsp[(3) - (3)].chars); }
+/* Line 1778 of yacc.c  */
+#line 270 "parse-gram.y"
+    { spec_file_prefix = (yyvsp[(2) - (2)].chars); }
     break;
 
   case 15:
-#line 231 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 271 "parse-gram.y"
+    { spec_file_prefix = (yyvsp[(3) - (3)].chars); }
+    break;
+
+  case 16:
+/* Line 1778 of yacc.c  */
+#line 273 "parse-gram.y"
     {
       nondeterministic_parser = true;
       glr_parser = true;
     }
     break;
 
-  case 16:
-#line 236 "parse-gram.y"
+  case 17:
+/* Line 1778 of yacc.c  */
+#line 278 "parse-gram.y"
     {
-      muscle_code_grow ("initial_action", (yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)]));
+      code_props action;
+      code_props_symbol_action_init (&action, (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)]));
+      code_props_translate_code (&action);
+      gram_scanner_last_string_free ();
+      muscle_code_grow ("initial_action", action.code, (yylsp[(2) - (2)]));
+      code_scanner_last_string_free ();
     }
     break;
 
-  case 17:
-#line 239 "parse-gram.y"
-    { add_param ("lex_param", (yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)])); }
-    break;
-
   case 18:
-#line 240 "parse-gram.y"
-    { locations_flag = true; }
+/* Line 1778 of yacc.c  */
+#line 286 "parse-gram.y"
+    { language_argmatch ((yyvsp[(2) - (2)].chars), grammar_prio, (yylsp[(1) - (2)])); }
     break;
 
   case 19:
-#line 241 "parse-gram.y"
-    { spec_name_prefix = (yyvsp[(3) - (3)].chars); }
+/* Line 1778 of yacc.c  */
+#line 287 "parse-gram.y"
+    { add_param ("lex_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); }
     break;
 
   case 20:
-#line 242 "parse-gram.y"
-    { no_lines_flag = true; }
+/* Line 1778 of yacc.c  */
+#line 288 "parse-gram.y"
+    { locations_flag = true; }
     break;
 
   case 21:
-#line 243 "parse-gram.y"
-    { nondeterministic_parser = true; }
+/* Line 1778 of yacc.c  */
+#line 289 "parse-gram.y"
+    { spec_name_prefix = (yyvsp[(2) - (2)].chars); }
     break;
 
   case 22:
-#line 244 "parse-gram.y"
-    { spec_outfile = (yyvsp[(3) - (3)].chars); }
+/* Line 1778 of yacc.c  */
+#line 290 "parse-gram.y"
+    { spec_name_prefix = (yyvsp[(3) - (3)].chars); }
     break;
 
   case 23:
-#line 245 "parse-gram.y"
-    { add_param ("parse_param", (yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)])); }
+/* Line 1778 of yacc.c  */
+#line 291 "parse-gram.y"
+    { no_lines_flag = true; }
     break;
 
   case 24:
-#line 246 "parse-gram.y"
-    { pure_parser = true; }
+/* Line 1778 of yacc.c  */
+#line 292 "parse-gram.y"
+    { nondeterministic_parser = true; }
     break;
 
   case 25:
-#line 247 "parse-gram.y"
-    { version_check (&(yylsp[(2) - (2)]), (yyvsp[(2) - (2)].chars)); }
+/* Line 1778 of yacc.c  */
+#line 293 "parse-gram.y"
+    { spec_outfile = (yyvsp[(2) - (2)].chars); }
     break;
 
   case 26:
-#line 248 "parse-gram.y"
-    { skeleton = (yyvsp[(2) - (2)].chars); }
+/* Line 1778 of yacc.c  */
+#line 294 "parse-gram.y"
+    { spec_outfile = (yyvsp[(3) - (3)].chars); }
     break;
 
   case 27:
-#line 249 "parse-gram.y"
-    { token_table_flag = true; }
+/* Line 1778 of yacc.c  */
+#line 295 "parse-gram.y"
+    { add_param ("parse_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); }
     break;
 
   case 28:
-#line 250 "parse-gram.y"
-    { report_flag = report_states; }
+/* Line 1778 of yacc.c  */
+#line 297 "parse-gram.y"
+    {
+      /* %pure-parser is deprecated in favor of `%define api.pure', so use
+         `%define api.pure' in a backward-compatible manner here.  First, don't
+         complain if %pure-parser is specified multiple times.  */
+      if (!muscle_find_const ("percent_define(api.pure)"))
+        muscle_percent_define_insert ("api.pure", (yylsp[(1) - (1)]), "",
+                                      MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+      /* In all cases, use api.pure now so that the backend doesn't complain if
+         the skeleton ignores api.pure, but do warn now if there's a previous
+         conflicting definition from an actual %define.  */
+      if (!muscle_percent_define_flag_if ("api.pure"))
+        muscle_percent_define_insert ("api.pure", (yylsp[(1) - (1)]), "",
+                                      MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+    }
     break;
 
   case 29:
-#line 251 "parse-gram.y"
-    { yacc_flag = true; }
+/* Line 1778 of yacc.c  */
+#line 311 "parse-gram.y"
+    { version_check (&(yylsp[(2) - (2)]), (yyvsp[(2) - (2)].chars)); }
+    break;
+
+  case 30:
+/* Line 1778 of yacc.c  */
+#line 313 "parse-gram.y"
+    {
+      char const *skeleton_user = (yyvsp[(2) - (2)].chars);
+      if (mbschr (skeleton_user, '/'))
+        {
+          size_t dir_length = strlen (current_file);
+          char *skeleton_build;
+          while (dir_length && current_file[dir_length - 1] != '/')
+            --dir_length;
+          while (dir_length && current_file[dir_length - 1] == '/')
+            --dir_length;
+          skeleton_build =
+            xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
+          if (dir_length > 0)
+            {
+              memcpy (skeleton_build, current_file, dir_length);
+              skeleton_build[dir_length++] = '/';
+            }
+          strcpy (skeleton_build + dir_length, skeleton_user);
+          skeleton_user = uniqstr_new (skeleton_build);
+          free (skeleton_build);
+        }
+      skeleton_arg (skeleton_user, grammar_prio, (yylsp[(1) - (2)]));
+    }
+    break;
+
+  case 31:
+/* Line 1778 of yacc.c  */
+#line 336 "parse-gram.y"
+    { token_table_flag = true; }
+    break;
+
+  case 32:
+/* Line 1778 of yacc.c  */
+#line 337 "parse-gram.y"
+    { report_flag |= report_states; }
     break;
 
   case 33:
-#line 259 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 338 "parse-gram.y"
+    { yacc_flag = true; }
+    break;
+
+  case 37:
+/* Line 1778 of yacc.c  */
+#line 346 "parse-gram.y"
     {
       grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]));
     }
     break;
 
-  case 34:
-#line 263 "parse-gram.y"
+  case 38:
+/* Line 1778 of yacc.c  */
+#line 350 "parse-gram.y"
     {
-      char const *body = (yyvsp[(1) - (1)].chars);
-
-      if (typed)
-	{
-	  /* Concatenate the union bodies, turning the first one's
-	     trailing '}' into '\n', and omitting the second one's '{'.  */
-	  char *code = muscle_find ("stype");
-	  code[strlen (code) - 1] = '\n';
-	  body++;
-	}
-
-      typed = true;
-      muscle_code_grow ("stype", body, (yylsp[(1) - (1)]));
+      code_props code;
+      code_props_symbol_action_init (&code, (yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]));
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
+          symbol_list_destructor_set (list, &code);
+        symbol_list_free ((yyvsp[(3) - (3)].list));
+      }
     }
     break;
 
-  case 35:
-#line 279 "parse-gram.y"
+  case 39:
+/* Line 1778 of yacc.c  */
+#line 362 "parse-gram.y"
     {
-      symbol_list *list;
-      for (list = (yyvsp[(2) - (2)].list); list; list = list->next)
-	symbol_destructor_set (list->sym, (yyvsp[(1) - (2)].chars), (yylsp[(1) - (2)]));
-      symbol_list_free ((yyvsp[(2) - (2)].list));
+      code_props code;
+      code_props_symbol_action_init (&code, (yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]));
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
+          symbol_list_printer_set (list, &code);
+        symbol_list_free ((yyvsp[(3) - (3)].list));
+      }
     }
     break;
 
-  case 36:
-#line 286 "parse-gram.y"
-    {
-      symbol_list *list;
-      for (list = (yyvsp[(2) - (2)].list); list; list = list->next)
-	symbol_printer_set (list->sym, (yyvsp[(1) - (2)].chars), (yylsp[(1) - (2)]));
-      symbol_list_free ((yyvsp[(2) - (2)].list));
-    }
-    break;
-
-  case 37:
-#line 293 "parse-gram.y"
+  case 40:
+/* Line 1778 of yacc.c  */
+#line 374 "parse-gram.y"
     {
       default_prec = true;
     }
     break;
 
-  case 38:
-#line 297 "parse-gram.y"
+  case 41:
+/* Line 1778 of yacc.c  */
+#line 378 "parse-gram.y"
     {
       default_prec = false;
     }
     break;
 
-  case 39:
-#line 303 "parse-gram.y"
-    { current_class = nterm_sym; }
-    break;
-
-  case 40:
-#line 304 "parse-gram.y"
-    {
-      current_class = unknown_sym;
-      current_type = NULL;
-    }
-    break;
-
-  case 41:
-#line 308 "parse-gram.y"
-    { current_class = token_sym; }
-    break;
-
   case 42:
-#line 309 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 382 "parse-gram.y"
     {
-      current_class = unknown_sym;
-      current_type = NULL;
+      /* Do not invoke muscle_percent_code_grow here since it invokes
+         muscle_user_name_list_grow.  */
+      muscle_code_grow ("percent_code()", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
+      code_scanner_last_string_free ();
     }
     break;
 
   case 43:
-#line 314 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 389 "parse-gram.y"
     {
-      symbol_list *list;
-      for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
-	symbol_type_set (list->sym, (yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]));
-      symbol_list_free ((yyvsp[(3) - (3)].list));
+      muscle_percent_code_grow ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)]));
+      code_scanner_last_string_free ();
     }
     break;
 
   case 44:
-#line 324 "parse-gram.y"
+/* Line 1778 of yacc.c  */
+#line 403 "parse-gram.y"
+    {}
+    break;
+
+  case 45:
+/* Line 1778 of yacc.c  */
+#line 404 "parse-gram.y"
+    { muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
+    break;
+
+  case 46:
+/* Line 1778 of yacc.c  */
+#line 409 "parse-gram.y"
+    {
+      union_seen = true;
+      muscle_code_grow ("stype", (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)]));
+      code_scanner_last_string_free ();
+    }
+    break;
+
+  case 47:
+/* Line 1778 of yacc.c  */
+#line 420 "parse-gram.y"
+    { current_class = nterm_sym; }
+    break;
+
+  case 48:
+/* Line 1778 of yacc.c  */
+#line 421 "parse-gram.y"
+    {
+      current_class = unknown_sym;
+      current_type = NULL;
+    }
+    break;
+
+  case 49:
+/* Line 1778 of yacc.c  */
+#line 425 "parse-gram.y"
+    { current_class = token_sym; }
+    break;
+
+  case 50:
+/* Line 1778 of yacc.c  */
+#line 426 "parse-gram.y"
+    {
+      current_class = unknown_sym;
+      current_type = NULL;
+    }
+    break;
+
+  case 51:
+/* Line 1778 of yacc.c  */
+#line 431 "parse-gram.y"
+    {
+      symbol_list *list;
+      tag_seen = true;
+      for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
+	symbol_type_set (list->content.sym, (yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]));
+      symbol_list_free ((yyvsp[(3) - (3)].list));
+    }
+    break;
+
+  case 52:
+/* Line 1778 of yacc.c  */
+#line 442 "parse-gram.y"
     {
       symbol_list *list;
       ++current_prec;
       for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
 	{
-	  symbol_type_set (list->sym, current_type, (yylsp[(2) - (3)]));
-	  symbol_precedence_set (list->sym, current_prec, (yyvsp[(1) - (3)].assoc), (yylsp[(1) - (3)]));
+	  symbol_type_set (list->content.sym, current_type, (yylsp[(2) - (3)]));
+	  symbol_precedence_set (list->content.sym, current_prec, (yyvsp[(1) - (3)].assoc), (yylsp[(1) - (3)]));
 	}
       symbol_list_free ((yyvsp[(3) - (3)].list));
       current_type = NULL;
     }
     break;
 
-  case 45:
-#line 338 "parse-gram.y"
+  case 53:
+/* Line 1778 of yacc.c  */
+#line 456 "parse-gram.y"
     { (yyval.assoc) = left_assoc; }
     break;
 
-  case 46:
-#line 339 "parse-gram.y"
+  case 54:
+/* Line 1778 of yacc.c  */
+#line 457 "parse-gram.y"
     { (yyval.assoc) = right_assoc; }
     break;
 
-  case 47:
-#line 340 "parse-gram.y"
+  case 55:
+/* Line 1778 of yacc.c  */
+#line 458 "parse-gram.y"
     { (yyval.assoc) = non_assoc; }
     break;
 
-  case 48:
-#line 344 "parse-gram.y"
+  case 56:
+/* Line 1778 of yacc.c  */
+#line 462 "parse-gram.y"
     { current_type = NULL; }
     break;
 
-  case 49:
-#line 345 "parse-gram.y"
-    { current_type = (yyvsp[(1) - (1)].uniqstr); }
+  case 57:
+/* Line 1778 of yacc.c  */
+#line 463 "parse-gram.y"
+    { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; }
     break;
 
-  case 50:
-#line 351 "parse-gram.y"
-    { (yyval.list) = symbol_list_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
+  case 58:
+/* Line 1778 of yacc.c  */
+#line 469 "parse-gram.y"
+    { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
     break;
 
-  case 51:
-#line 352 "parse-gram.y"
-    { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); }
+  case 59:
+/* Line 1778 of yacc.c  */
+#line 471 "parse-gram.y"
+    { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); }
     break;
 
-  case 52:
-#line 358 "parse-gram.y"
+  case 60:
+/* Line 1778 of yacc.c  */
+#line 475 "parse-gram.y"
+    { (yyval.symbol) = (yyvsp[(1) - (1)].symbol); }
+    break;
+
+  case 61:
+/* Line 1778 of yacc.c  */
+#line 476 "parse-gram.y"
+    { (yyval.symbol) = (yyvsp[(1) - (2)].symbol); symbol_user_token_number_set ((yyvsp[(1) - (2)].symbol), (yyvsp[(2) - (2)].integer), (yylsp[(2) - (2)])); }
+    break;
+
+  case 62:
+/* Line 1778 of yacc.c  */
+#line 482 "parse-gram.y"
+    { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
+    break;
+
+  case 63:
+/* Line 1778 of yacc.c  */
+#line 484 "parse-gram.y"
+    { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); }
+    break;
+
+  case 64:
+/* Line 1778 of yacc.c  */
+#line 488 "parse-gram.y"
+    { (yyval.list) = (yyvsp[(1) - (1)].list); }
+    break;
+
+  case 65:
+/* Line 1778 of yacc.c  */
+#line 489 "parse-gram.y"
+    { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); }
+    break;
+
+  case 66:
+/* Line 1778 of yacc.c  */
+#line 493 "parse-gram.y"
+    { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
+    break;
+
+  case 67:
+/* Line 1778 of yacc.c  */
+#line 494 "parse-gram.y"
+    { (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
+    break;
+
+  case 68:
+/* Line 1778 of yacc.c  */
+#line 495 "parse-gram.y"
+    { (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); }
+    break;
+
+  case 69:
+/* Line 1778 of yacc.c  */
+#line 496 "parse-gram.y"
+    { (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); }
+    break;
+
+  case 70:
+/* Line 1778 of yacc.c  */
+#line 502 "parse-gram.y"
     {
        current_type = (yyvsp[(1) - (1)].uniqstr);
+       tag_seen = true;
      }
     break;
 
-  case 53:
-#line 362 "parse-gram.y"
+  case 71:
+/* Line 1778 of yacc.c  */
+#line 507 "parse-gram.y"
     {
        symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true);
        symbol_type_set ((yyvsp[(1) - (1)].symbol), current_type, (yylsp[(1) - (1)]));
      }
     break;
 
-  case 54:
-#line 367 "parse-gram.y"
+  case 72:
+/* Line 1778 of yacc.c  */
+#line 512 "parse-gram.y"
     {
       symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true);
       symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)]));
@@ -2051,8 +2710,9 @@
     }
     break;
 
-  case 55:
-#line 373 "parse-gram.y"
+  case 73:
+/* Line 1778 of yacc.c  */
+#line 518 "parse-gram.y"
     {
       symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true);
       symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)]));
@@ -2060,8 +2720,9 @@
     }
     break;
 
-  case 56:
-#line 379 "parse-gram.y"
+  case 74:
+/* Line 1778 of yacc.c  */
+#line 524 "parse-gram.y"
     {
       symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true);
       symbol_type_set ((yyvsp[(1) - (3)].symbol), current_type, (yylsp[(1) - (3)]));
@@ -2070,94 +2731,184 @@
     }
     break;
 
-  case 63:
-#line 409 "parse-gram.y"
+  case 81:
+/* Line 1778 of yacc.c  */
+#line 554 "parse-gram.y"
     {
       yyerrok;
     }
     break;
 
-  case 64:
-#line 415 "parse-gram.y"
-    { current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); }
+  case 82:
+/* Line 1778 of yacc.c  */
+#line 560 "parse-gram.y"
+    { current_lhs ((yyvsp[(1) - (2)].symbol), (yylsp[(1) - (2)]), (yyvsp[(2) - (2)].named_ref)); }
     break;
 
-  case 66:
-#line 419 "parse-gram.y"
+  case 83:
+/* Line 1778 of yacc.c  */
+#line 561 "parse-gram.y"
+    {
+    /* Free the current lhs. */
+    current_lhs (0, (yylsp[(1) - (4)]), 0);
+  }
+    break;
+
+  case 84:
+/* Line 1778 of yacc.c  */
+#line 568 "parse-gram.y"
     { grammar_current_rule_end ((yylsp[(1) - (1)])); }
     break;
 
-  case 67:
-#line 420 "parse-gram.y"
+  case 85:
+/* Line 1778 of yacc.c  */
+#line 569 "parse-gram.y"
     { grammar_current_rule_end ((yylsp[(3) - (3)])); }
     break;
 
-  case 69:
-#line 426 "parse-gram.y"
-    { grammar_current_rule_begin (current_lhs, current_lhs_location); }
+  case 87:
+/* Line 1778 of yacc.c  */
+#line 575 "parse-gram.y"
+    { grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
+				  current_lhs_named_ref); }
     break;
 
-  case 70:
-#line 428 "parse-gram.y"
-    { grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); }
+  case 88:
+/* Line 1778 of yacc.c  */
+#line 578 "parse-gram.y"
+    { grammar_current_rule_symbol_append ((yyvsp[(2) - (3)].symbol), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].named_ref)); }
     break;
 
-  case 72:
-#line 431 "parse-gram.y"
+  case 89:
+/* Line 1778 of yacc.c  */
+#line 580 "parse-gram.y"
+    { grammar_current_rule_action_append ((yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].named_ref)); }
+    break;
+
+  case 90:
+/* Line 1778 of yacc.c  */
+#line 582 "parse-gram.y"
     { grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); }
     break;
 
-  case 73:
-#line 433 "parse-gram.y"
+  case 91:
+/* Line 1778 of yacc.c  */
+#line 584 "parse-gram.y"
     { grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); }
     break;
 
-  case 74:
-#line 435 "parse-gram.y"
+  case 92:
+/* Line 1778 of yacc.c  */
+#line 586 "parse-gram.y"
     { grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); }
     break;
 
-  case 75:
-#line 439 "parse-gram.y"
-    { (yyval.symbol) = (yyvsp[(1) - (1)].symbol); }
+  case 93:
+/* Line 1778 of yacc.c  */
+#line 590 "parse-gram.y"
+    { (yyval.named_ref) = 0; }
     break;
 
-  case 76:
-#line 440 "parse-gram.y"
-    { (yyval.symbol) = (yyvsp[(1) - (1)].symbol); }
+  case 94:
+/* Line 1778 of yacc.c  */
+#line 592 "parse-gram.y"
+    { (yyval.named_ref) = named_ref_new((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
     break;
 
-  case 77:
-#line 456 "parse-gram.y"
-    { grammar_current_rule_action_append (last_string, last_braced_code_loc); }
+  case 96:
+/* Line 1778 of yacc.c  */
+#line 604 "parse-gram.y"
+    { (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); }
     break;
 
-  case 79:
-#line 463 "parse-gram.y"
+  case 97:
+/* Line 1778 of yacc.c  */
+#line 609 "parse-gram.y"
+    { (yyval.chars) = ""; }
+    break;
+
+  case 98:
+/* Line 1778 of yacc.c  */
+#line 610 "parse-gram.y"
+    { (yyval.chars) = (yyvsp[(1) - (1)].uniqstr); }
+    break;
+
+  case 100:
+/* Line 1778 of yacc.c  */
+#line 621 "parse-gram.y"
+    {
+      code_props plain_code;
+      (yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n';
+      code_props_plain_init (&plain_code, (yyvsp[(1) - (1)].code)+1, (yylsp[(1) - (1)]));
+      code_props_translate_code (&plain_code);
+      gram_scanner_last_string_free ();
+      (yyval.chars) = plain_code.code;
+    }
+    break;
+
+  case 101:
+/* Line 1778 of yacc.c  */
+#line 641 "parse-gram.y"
+    { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
+    break;
+
+  case 102:
+/* Line 1778 of yacc.c  */
+#line 643 "parse-gram.y"
+    {
+      (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)]));
+      symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
+      symbol_user_token_number_set ((yyval.symbol), (yyvsp[(1) - (1)].character), (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 103:
+/* Line 1778 of yacc.c  */
+#line 651 "parse-gram.y"
+    { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
+    break;
+
+  case 106:
+/* Line 1778 of yacc.c  */
+#line 663 "parse-gram.y"
     {
       (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)]));
       symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
     }
     break;
 
-  case 80:
-#line 472 "parse-gram.y"
-    { (yyval.chars) = (yyvsp[(1) - (1)].chars); }
-    break;
-
-  case 82:
-#line 479 "parse-gram.y"
+  case 108:
+/* Line 1778 of yacc.c  */
+#line 672 "parse-gram.y"
     {
-      muscle_code_grow ("epilogue", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
-      scanner_last_string_free ();
+      code_props plain_code;
+      code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
+      code_props_translate_code (&plain_code);
+      gram_scanner_last_string_free ();
+      muscle_code_grow ("epilogue", plain_code.code, (yylsp[(2) - (2)]));
+      code_scanner_last_string_free ();
     }
     break;
 
 
-/* Line 1267 of yacc.c.  */
-#line 2159 "parse-gram.c"
-      default: break;
-    }
+/* Line 1778 of yacc.c  */
+#line 2896 "parse-gram.c"
+        default: break;
+      }
+    if (yychar_backup != yychar)
+      YY_LAC_DISCARD ("yychar change");
+  }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     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);
 
   YYPOPSTACK (yylen);
@@ -2186,6 +2937,10 @@
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 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);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2193,45 +2948,47 @@
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyesa, &yyes, &yyes_capacity, \
+                                        yyssp, yytoken)
       {
-	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-	  {
-	    YYSIZE_T yyalloc = 2 * yysize;
-	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
-	    if (yymsg != yymsgbuf)
-	      YYSTACK_FREE (yymsg);
-	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-	    if (yymsg)
-	      yymsg_alloc = yyalloc;
-	    else
-	      {
-		yymsg = yymsgbuf;
-		yymsg_alloc = sizeof yymsgbuf;
-	      }
-	  }
-
-	if (0 < yysize && yysize <= yymsg_alloc)
-	  {
-	    (void) yysyntax_error (yymsg, yystate, yychar);
-	    yyerror (yymsg);
-	  }
-	else
-	  {
-	    yyerror (YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        if (yychar != YYEMPTY)
+          YY_LAC_ESTABLISH;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
-  yyerror_range[0] = yylloc;
+  yyerror_range[1] = yylloc;
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse look-ahead token after an
+      /* If just tried and failed to reuse lookahead token after an
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -2248,7 +3005,7 @@
 	}
     }
 
-  /* Else will try to reuse look-ahead token after shifting the error
+  /* Else will try to reuse lookahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -2264,7 +3021,7 @@
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  yyerror_range[0] = yylsp[1-yylen];
+  yyerror_range[1] = yylsp[1-yylen];
   /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
@@ -2283,7 +3040,7 @@
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -2298,7 +3055,7 @@
       if (yyssp == yyss)
 	YYABORT;
 
-      yyerror_range[0] = *yylsp;
+      yyerror_range[1] = *yylsp;
       yydestruct ("Error: popping",
 		  yystos[yystate], yyvsp, yylsp);
       YYPOPSTACK (1);
@@ -2306,15 +3063,18 @@
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
+  /* If the stack popping above didn't lose the initial context for the
+     current lookahead token, the shift below will for sure.  */
+  YY_LAC_DISCARD ("error recovery");
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
-  yyerror_range[1] = yylloc;
+  yyerror_range[2] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
-     the look-ahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+     the lookahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
   *++yylsp = yyloc;
 
   /* Shift the error token.  */
@@ -2338,7 +3098,7 @@
   yyresult = 1;
   goto yyreturn;
 
-#ifndef yyoverflow
+#if 1
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2349,9 +3109,14 @@
 #endif
 
 yyreturn:
-  if (yychar != YYEOF && yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, &yylloc);
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, &yylloc);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -2366,6 +3131,8 @@
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
 #endif
+  if (yyes != yyesa)
+    YYSTACK_FREE (yyes);
 #if YYERROR_VERBOSE
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
@@ -2375,7 +3142,8 @@
 }
 
 
-#line 485 "parse-gram.y"
+/* Line 2041 of yacc.c  */
+#line 682 "parse-gram.y"
 
 
 
@@ -2395,7 +3163,7 @@
   loc.start = rhs[n].end;
   loc.end = rhs[n].end;
 
-  /* Ignore empty nonterminals the start of the the right-hand side.
+  /* Ignore empty nonterminals the start of the right-hand side.
      Do not bother to ignore them at the end of the right-hand side,
      since empty nonterminals have the same end as their predecessors.  */
   for (i = 1; i <= n; i++)
@@ -2432,42 +3200,35 @@
 
   /* Strip the surrounding '{' and '}', and any blanks just inside
      the braces.  */
-  while (*--p == ' ' || *p == '\t')
-    continue;
+  --p;
+  while (c_isspace ((unsigned char) *p))
+    --p;
   p[1] = '\0';
-  while (*++decl == ' ' || *decl == '\t')
-    continue;
+  ++decl;
+  while (c_isspace ((unsigned char) *decl))
+    ++decl;
 
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));
   else
     {
-      char *name;
-      size_t name_len;
-
-      for (name_len = 1;
-	   memchr (alphanum, name_start[name_len], sizeof alphanum);
-	   name_len++)
-	continue;
-
-      name = xmalloc (name_len + 1);
-      memcpy (name, name_start, name_len);
-      name[name_len] = '\0';
+      char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
       muscle_pair_list_grow (type, decl, name);
       free (name);
     }
 
-  scanner_last_string_free ();
+  gram_scanner_last_string_free ();
 }
 
+
 static void
 version_check (location const *loc, char const *version)
 {
   if (strverscmp (version, PACKAGE_VERSION) > 0)
     {
       complain_at (*loc, "require bison %s, but have %s",
-		   version, PACKAGE_VERSION);
-      exit (63);
+                   version, PACKAGE_VERSION);
+      exit (EX_MISMATCH);
     }
 }
 
@@ -2483,3 +3244,15 @@
   return yytname[YYTRANSLATE (type)];
 }
 
+static char const *
+char_name (char c)
+{
+  if (c == '\'')
+    return "'\\''";
+  else
+    {
+      char buf[4];
+      buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
+      return quotearg_style (escape_quoting_style, buf);
+    }
+}
diff --git a/src/parse-gram.h b/src/parse-gram.h
index 2d37fc1..c709098 100644
--- a/src/parse-gram.h
+++ b/src/parse-gram.h
@@ -1,24 +1,21 @@
-/* A Bison parser, made by GNU Bison 2.2a.  */
+/* A Bison parser, made by GNU Bison 2.6.5.63-3ada.  */
 
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
+/* Bison interface for Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989-1990, 2000-2012 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 2, or (at your option)
-   any later version.
-
+   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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -29,16 +26,34 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+#ifndef YY_GRAM__________SRC_PARSE_GRAM_H_INCLUDED
+# define YY_GRAM__________SRC_PARSE_GRAM_H_INCLUDED
+/* Enabling traces.  */
+#ifndef GRAM_DEBUG
+# if defined YYDEBUG
+#  if YYDEBUG
+#   define GRAM_DEBUG 1
+#  else
+#   define GRAM_DEBUG 0
+#  endif
+# else /* ! defined YYDEBUG */
+#  define GRAM_DEBUG 1
+# endif /* ! defined YYDEBUG */
+#endif  /* ! defined GRAM_DEBUG */
+#if GRAM_DEBUG
+extern int gram_debug;
+#endif
+
 /* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
+#ifndef GRAM_TOKENTYPE
+# define GRAM_TOKENTYPE
    /* Put the tokens into the symbol table, so that GDB and other debuggers
       know about them.  */
-   enum yytokentype {
+   enum gram_tokentype {
      GRAM_EOF = 0,
      STRING = 258,
      INT = 259,
@@ -47,13 +62,13 @@
      PERCENT_TYPE = 262,
      PERCENT_DESTRUCTOR = 263,
      PERCENT_PRINTER = 264,
-     PERCENT_UNION = 265,
-     PERCENT_LEFT = 266,
-     PERCENT_RIGHT = 267,
-     PERCENT_NONASSOC = 268,
-     PERCENT_PREC = 269,
-     PERCENT_DPREC = 270,
-     PERCENT_MERGE = 271,
+     PERCENT_LEFT = 265,
+     PERCENT_RIGHT = 266,
+     PERCENT_NONASSOC = 267,
+     PERCENT_PREC = 268,
+     PERCENT_DPREC = 269,
+     PERCENT_MERGE = 270,
+     PERCENT_CODE = 271,
      PERCENT_DEBUG = 272,
      PERCENT_DEFAULT_PREC = 273,
      PERCENT_DEFINE = 274,
@@ -64,31 +79,37 @@
      PERCENT_FILE_PREFIX = 279,
      PERCENT_GLR_PARSER = 280,
      PERCENT_INITIAL_ACTION = 281,
-     PERCENT_LEX_PARAM = 282,
-     PERCENT_LOCATIONS = 283,
-     PERCENT_NAME_PREFIX = 284,
-     PERCENT_NO_DEFAULT_PREC = 285,
-     PERCENT_NO_LINES = 286,
-     PERCENT_NONDETERMINISTIC_PARSER = 287,
-     PERCENT_OUTPUT = 288,
-     PERCENT_PARSE_PARAM = 289,
-     PERCENT_PURE_PARSER = 290,
-     PERCENT_REQUIRE = 291,
-     PERCENT_SKELETON = 292,
-     PERCENT_START = 293,
-     PERCENT_TOKEN_TABLE = 294,
-     PERCENT_VERBOSE = 295,
-     PERCENT_YACC = 296,
-     TYPE = 297,
-     EQUAL = 298,
-     SEMICOLON = 299,
-     PIPE = 300,
-     ID = 301,
-     ID_COLON = 302,
-     PERCENT_PERCENT = 303,
-     PROLOGUE = 304,
-     EPILOGUE = 305,
-     BRACED_CODE = 306
+     PERCENT_LANGUAGE = 282,
+     PERCENT_LEX_PARAM = 283,
+     PERCENT_LOCATIONS = 284,
+     PERCENT_NAME_PREFIX = 285,
+     PERCENT_NO_DEFAULT_PREC = 286,
+     PERCENT_NO_LINES = 287,
+     PERCENT_NONDETERMINISTIC_PARSER = 288,
+     PERCENT_OUTPUT = 289,
+     PERCENT_PARSE_PARAM = 290,
+     PERCENT_PURE_PARSER = 291,
+     PERCENT_REQUIRE = 292,
+     PERCENT_SKELETON = 293,
+     PERCENT_START = 294,
+     PERCENT_TOKEN_TABLE = 295,
+     PERCENT_VERBOSE = 296,
+     PERCENT_YACC = 297,
+     BRACED_CODE = 298,
+     BRACKETED_ID = 299,
+     CHAR = 300,
+     EPILOGUE = 301,
+     EQUAL = 302,
+     ID = 303,
+     ID_COLON = 304,
+     PERCENT_PERCENT = 305,
+     PIPE = 306,
+     PROLOGUE = 307,
+     SEMICOLON = 308,
+     TYPE = 309,
+     TYPE_TAG_ANY = 310,
+     TYPE_TAG_NONE = 311,
+     PERCENT_UNION = 312
    };
 #endif
 /* Tokens.  */
@@ -100,13 +121,13 @@
 #define PERCENT_TYPE 262
 #define PERCENT_DESTRUCTOR 263
 #define PERCENT_PRINTER 264
-#define PERCENT_UNION 265
-#define PERCENT_LEFT 266
-#define PERCENT_RIGHT 267
-#define PERCENT_NONASSOC 268
-#define PERCENT_PREC 269
-#define PERCENT_DPREC 270
-#define PERCENT_MERGE 271
+#define PERCENT_LEFT 265
+#define PERCENT_RIGHT 266
+#define PERCENT_NONASSOC 267
+#define PERCENT_PREC 268
+#define PERCENT_DPREC 269
+#define PERCENT_MERGE 270
+#define PERCENT_CODE 271
 #define PERCENT_DEBUG 272
 #define PERCENT_DEFAULT_PREC 273
 #define PERCENT_DEFINE 274
@@ -117,67 +138,91 @@
 #define PERCENT_FILE_PREFIX 279
 #define PERCENT_GLR_PARSER 280
 #define PERCENT_INITIAL_ACTION 281
-#define PERCENT_LEX_PARAM 282
-#define PERCENT_LOCATIONS 283
-#define PERCENT_NAME_PREFIX 284
-#define PERCENT_NO_DEFAULT_PREC 285
-#define PERCENT_NO_LINES 286
-#define PERCENT_NONDETERMINISTIC_PARSER 287
-#define PERCENT_OUTPUT 288
-#define PERCENT_PARSE_PARAM 289
-#define PERCENT_PURE_PARSER 290
-#define PERCENT_REQUIRE 291
-#define PERCENT_SKELETON 292
-#define PERCENT_START 293
-#define PERCENT_TOKEN_TABLE 294
-#define PERCENT_VERBOSE 295
-#define PERCENT_YACC 296
-#define TYPE 297
-#define EQUAL 298
-#define SEMICOLON 299
-#define PIPE 300
-#define ID 301
-#define ID_COLON 302
-#define PERCENT_PERCENT 303
-#define PROLOGUE 304
-#define EPILOGUE 305
-#define BRACED_CODE 306
+#define PERCENT_LANGUAGE 282
+#define PERCENT_LEX_PARAM 283
+#define PERCENT_LOCATIONS 284
+#define PERCENT_NAME_PREFIX 285
+#define PERCENT_NO_DEFAULT_PREC 286
+#define PERCENT_NO_LINES 287
+#define PERCENT_NONDETERMINISTIC_PARSER 288
+#define PERCENT_OUTPUT 289
+#define PERCENT_PARSE_PARAM 290
+#define PERCENT_PURE_PARSER 291
+#define PERCENT_REQUIRE 292
+#define PERCENT_SKELETON 293
+#define PERCENT_START 294
+#define PERCENT_TOKEN_TABLE 295
+#define PERCENT_VERBOSE 296
+#define PERCENT_YACC 297
+#define BRACED_CODE 298
+#define BRACKETED_ID 299
+#define CHAR 300
+#define EPILOGUE 301
+#define EQUAL 302
+#define ID 303
+#define ID_COLON 304
+#define PERCENT_PERCENT 305
+#define PIPE 306
+#define PROLOGUE 307
+#define SEMICOLON 308
+#define TYPE 309
+#define TYPE_TAG_ANY 310
+#define TYPE_TAG_NONE 311
+#define PERCENT_UNION 312
 
 
 
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 94 "parse-gram.y"
+#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
+typedef union GRAM_STYPE
 {
+/* Line 2042 of yacc.c  */
+#line 115 "parse-gram.y"
+
   symbol *symbol;
   symbol_list *list;
   int integer;
-  char *chars;
+  char const *chars;
+  char *code;
   assoc assoc;
   uniqstr uniqstr;
-}
-/* Line 1529 of yacc.c.  */
-#line 162 "parse-gram.h"
-	YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
+  unsigned char character;
+  named_ref *named_ref;
+
+
+/* Line 2042 of yacc.c  */
+#line 194 "parse-gram.h"
+} GRAM_STYPE;
+# define GRAM_STYPE_IS_TRIVIAL 1
+# define gram_stype GRAM_STYPE /* obsolescent; will be withdrawn */
+# define GRAM_STYPE_IS_DECLARED 1
 #endif
 
-
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
+#if ! defined GRAM_LTYPE && ! defined GRAM_LTYPE_IS_DECLARED
+typedef struct GRAM_LTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
+} GRAM_LTYPE;
+# define gram_ltype GRAM_LTYPE /* obsolescent; will be withdrawn */
+# define GRAM_LTYPE_IS_DECLARED 1
+# define GRAM_LTYPE_IS_TRIVIAL 1
 #endif
 
 
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int gram_parse (void *YYPARSE_PARAM);
+#else
+int gram_parse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int gram_parse (void);
+#else
+int gram_parse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_GRAM__________SRC_PARSE_GRAM_H_INCLUDED  */
diff --git a/src/parse-gram.y b/src/parse-gram.y
index e189e14..5f77a5b 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -1,12 +1,12 @@
 %{/* Bison Grammar Parser                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   This program is free software; you can redistribute it and/or modify
+   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 2 of the License, or
+   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,
@@ -15,24 +15,25 @@
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301  USA
-*/
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
+#include "c-ctype.h"
 #include "complain.h"
 #include "conflicts.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "muscle_tab.h"
+#include "muscle-tab.h"
+#include "named-ref.h"
 #include "quotearg.h"
 #include "reader.h"
 #include "symlist.h"
-#include "strverscmp.h"
+#include "scan-gram.h"
+#include "scan-code.h"
+#include "xmemdup0.h"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
@@ -49,55 +50,78 @@
 	gram_error (&yylloc, Msg)
 static void gram_error (location const *, char const *);
 
-static void add_param (char const *, char *, location);
+static char const *char_name (char);
+
+/** Add a lex-param or a parse-param.
+ *
+ * \param type  \a lex_param or \a parse_param
+ * \param decl  the formal argument
+ * \param loc   the location in the source.
+ */
+static void add_param (char const *type, char *decl, location loc);
+
 
 static symbol_class current_class = unknown_sym;
-static uniqstr current_type = 0;
-static symbol *current_lhs;
+static uniqstr current_type = NULL;
+static symbol *current_lhs_symbol;
 static location current_lhs_location;
+static named_ref *current_lhs_named_ref;
 static int current_prec = 0;
 
-#ifdef UINT_FAST8_MAX
-# define YYTYPE_UINT8 uint_fast8_t
-#endif
-#ifdef INT_FAST8_MAX
-# define YYTYPE_INT8 int_fast8_t
-#endif
-#ifdef UINT_FAST16_MAX
-# define YYTYPE_UINT16 uint_fast16_t
-#endif
-#ifdef INT_FAST16_MAX
-# define YYTYPE_INT16 int_fast16_t
-#endif
+/** Set the new current left-hand side symbol, possibly common
+ * to several right-hand side parts of rule.
+ */
+static
+void
+current_lhs(symbol *sym, location loc, named_ref *ref)
+{
+  current_lhs_symbol = sym;
+  current_lhs_location = loc;
+  /* In order to simplify memory management, named references for lhs
+     are always assigned by deep copy into the current symbol_list
+     node.  This is because a single named-ref in the grammar may
+     result in several uses when the user factors lhs between several
+     rules using "|".  Therefore free the parser's original copy.  */
+  free (current_lhs_named_ref);
+  current_lhs_named_ref = ref;
+}
+
+
+#define YYTYPE_INT16 int_fast16_t
+#define YYTYPE_INT8 int_fast8_t
+#define YYTYPE_UINT16 uint_fast16_t
+#define YYTYPE_UINT8 uint_fast8_t
 %}
 
 %debug
-%verbose
+%define api.prefix "gram_"
+%define api.pure
+%define parse.lac full
 %defines
-%locations
-%pure-parser
 %error-verbose
-%defines
-%name-prefix="gram_"
+%expect 0
+%locations
+%verbose
 
 %initial-action
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
-  @$.start.file   = @$.end.file   = current_file;
-  @$.start.line   = @$.end.line   = 1;
-  @$.start.column = @$.end.column = 0;
+  boundary_set (&@$.start, current_file, 1, 1);
+  boundary_set (&@$.end, current_file, 1, 1);
 }
 
-/* Only NUMBERS have a value.  */
 %union
 {
   symbol *symbol;
   symbol_list *list;
   int integer;
-  char *chars;
+  char const *chars;
+  char *code;
   assoc assoc;
   uniqstr uniqstr;
+  unsigned char character;
+  named_ref *named_ref;
 };
 
 /* Define the tokens together with their human representation.  */
@@ -109,10 +133,8 @@
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TYPE        "%type"
-%token PERCENT_DESTRUCTOR  "%destructor {...}"
-%token PERCENT_PRINTER     "%printer {...}"
-
-%token PERCENT_UNION       "%union {...}"
+%token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_PRINTER     "%printer"
 
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
@@ -128,6 +150,7 @@
 `----------------------*/
 
 %token
+  PERCENT_CODE            "%code"
   PERCENT_DEBUG           "%debug"
   PERCENT_DEFAULT_PREC    "%default-prec"
   PERCENT_DEFINE          "%define"
@@ -137,8 +160,9 @@
   PERCENT_EXPECT_RR	  "%expect-rr"
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
-  PERCENT_INITIAL_ACTION  "%initial-action {...}"
-  PERCENT_LEX_PARAM       "%lex-param {...}"
+  PERCENT_INITIAL_ACTION  "%initial-action"
+  PERCENT_LANGUAGE        "%language"
+  PERCENT_LEX_PARAM       "%lex-param"
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
   PERCENT_NO_DEFAULT_PREC "%no-default-prec"
@@ -146,7 +170,7 @@
   PERCENT_NONDETERMINISTIC_PARSER
 			  "%nondeterministic-parser"
   PERCENT_OUTPUT          "%output"
-  PERCENT_PARSE_PARAM     "%parse-param {...}"
+  PERCENT_PARSE_PARAM     "%parse-param"
   PERCENT_PURE_PARSER     "%pure-parser"
   PERCENT_REQUIRE	  "%require"
   PERCENT_SKELETON        "%skeleton"
@@ -156,50 +180,54 @@
   PERCENT_YACC            "%yacc"
 ;
 
-%token TYPE            "type"
+%token BRACED_CODE     "{...}"
+%token BRACKETED_ID    "[identifier]"
+%token CHAR            "char"
+%token EPILOGUE        "epilogue"
 %token EQUAL           "="
-%token SEMICOLON       ";"
-%token PIPE            "|"
 %token ID              "identifier"
 %token ID_COLON        "identifier:"
 %token PERCENT_PERCENT "%%"
+%token PIPE            "|"
 %token PROLOGUE        "%{...%}"
-%token EPILOGUE        "epilogue"
-%token BRACED_CODE     "{...}"
+%token SEMICOLON       ";"
+%token TYPE            "type"
+%token TYPE_TAG_ANY    "<*>"
+%token TYPE_TAG_NONE   "<>"
 
+%type <character> CHAR
+%printer { fputs (char_name ($$), stderr); } CHAR
 
-%type <chars> STRING string_content
-	      "%destructor {...}"
-	      "%initial-action {...}"
-	      "%lex-param {...}"
-	      "%parse-param {...}"
-	      "%printer {...}"
-	      "%union {...}"
-	      PROLOGUE EPILOGUE
-%printer { fprintf (stderr, "\"%s\"", $$); }
-	      STRING string_content
+/* braceless is not to be used for rule or symbol actions, as it
+   calls code_props_plain_init.  */
+%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
+%type <code> "{...}"
+%printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
+	 STRING
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
-	      "%destructor {...}"
-	      "%initial-action {...}"
-	      "%lex-param {...}"
-	      "%parse-param {...}"
-	      "%printer {...}"
-	      "%union {...}"
-	      PROLOGUE EPILOGUE
-%type <uniqstr> TYPE
+	 braceless content.opt "{...}" "%{...%}" EPILOGUE
+
+%type <uniqstr> BRACKETED_ID ID ID_COLON TYPE variable
+%printer { fputs ($$, stderr); } <uniqstr>
+%printer { fprintf (stderr, "[%s]", $$); } BRACKETED_ID
+%printer { fprintf (stderr, "%s:", $$); } ID_COLON
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
+
 %type <integer> INT
-%printer { fprintf (stderr, "%d", $$); } INT
-%type <symbol> ID symbol string_as_id
-%printer { fprintf (stderr, "%s", $$->tag); } ID symbol string_as_id
-%type <symbol> ID_COLON
-%printer { fprintf (stderr, "%s:", $$->tag); } ID_COLON
+%printer { fprintf (stderr, "%d", $$); } <integer>
+
+%type <symbol> id id_colon string_as_id symbol symbol.prec
+%printer { fprintf (stderr, "%s", $$->tag); } <symbol>
+%printer { fprintf (stderr, "%s:", $$->tag); } id_colon
+
 %type <assoc> precedence_declarator
-%type <list>  symbols.1
+%type <list>  symbols.1 symbols.prec generic_symlist generic_symlist_item
+%type <named_ref> named_ref.opt
+
 %%
 
 input:
-  declarations "%%" grammar epilogue.opt
+  prologue_declarations "%%" grammar epilogue.opt
 ;
 
 
@@ -207,48 +235,107 @@
 	| Declarations: before the first %%.  |
 	`------------------------------------*/
 
-declarations:
+prologue_declarations:
   /* Nothing */
-| declarations declaration
+| prologue_declarations prologue_declaration
 ;
 
-declaration:
+prologue_declaration:
   grammar_declaration
-| PROLOGUE                                 { prologue_augment ($1, @1); }
-| "%debug"                                 { debug_flag = true; }
-| "%define" string_content
+| "%{...%}"
     {
-      static char one[] = "1";
-      muscle_insert ($2, one);
+      code_props plain_code;
+      code_props_plain_init (&plain_code, $1, @1);
+      code_props_translate_code (&plain_code);
+      gram_scanner_last_string_free ();
+      muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
+                        plain_code.code, @1);
+      code_scanner_last_string_free ();
     }
-| "%define" string_content string_content  { muscle_insert ($2, $3); }
-| "%defines"                               { defines_flag = true; }
-| "%error-verbose"                         { error_verbose = true; }
-| "%expect" INT                            { expected_sr_conflicts = $2; }
-| "%expect-rr" INT			   { expected_rr_conflicts = $2; }
-| "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
+| "%debug"                         { debug = true; }
+| "%define" variable content.opt
+    {
+      muscle_percent_define_insert ($2, @2, $3,
+                                    MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+    }
+| "%defines"                       { defines_flag = true; }
+| "%defines" STRING
+    {
+      defines_flag = true;
+      spec_defines_file = xstrdup ($2);
+    }
+| "%error-verbose"                 { error_verbose = true; }
+| "%expect" INT                    { expected_sr_conflicts = $2; }
+| "%expect-rr" INT		   { expected_rr_conflicts = $2; }
+| "%file-prefix" STRING            { spec_file_prefix = $2; }
+| "%file-prefix" "=" STRING        { spec_file_prefix = $3; } /* deprecated */
 | "%glr-parser"
     {
       nondeterministic_parser = true;
       glr_parser = true;
     }
-| "%initial-action {...}"
+| "%initial-action" "{...}"
     {
-      muscle_code_grow ("initial_action", $1, @1);
+      code_props action;
+      code_props_symbol_action_init (&action, $2, @2);
+      code_props_translate_code (&action);
+      gram_scanner_last_string_free ();
+      muscle_code_grow ("initial_action", action.code, @2);
+      code_scanner_last_string_free ();
     }
-| "%lex-param {...}"			   { add_param ("lex_param", $1, @1); }
-| "%locations"                             { locations_flag = true; }
-| "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
-| "%no-lines"                              { no_lines_flag = true; }
-| "%nondeterministic-parser"		   { nondeterministic_parser = true; }
-| "%output" "=" string_content             { spec_outfile = $3; }
-| "%parse-param {...}"			   { add_param ("parse_param", $1, @1); }
-| "%pure-parser"                           { pure_parser = true; }
-| "%require" string_content                { version_check (&@2, $2); }
-| "%skeleton" string_content               { skeleton = $2; }
-| "%token-table"                           { token_table_flag = true; }
-| "%verbose"                               { report_flag = report_states; }
-| "%yacc"                                  { yacc_flag = true; }
+| "%language" STRING		{ language_argmatch ($2, grammar_prio, @1); }
+| "%lex-param" "{...}"		{ add_param ("lex_param", $2, @2); }
+| "%locations"                  { locations_flag = true; }
+| "%name-prefix" STRING         { spec_name_prefix = $2; }
+| "%name-prefix" "=" STRING     { spec_name_prefix = $3; } /* deprecated */
+| "%no-lines"                   { no_lines_flag = true; }
+| "%nondeterministic-parser"	{ nondeterministic_parser = true; }
+| "%output" STRING              { spec_outfile = $2; }
+| "%output" "=" STRING          { spec_outfile = $3; }  /* deprecated */
+| "%parse-param" "{...}"	{ add_param ("parse_param", $2, @2); }
+| "%pure-parser"
+    {
+      /* %pure-parser is deprecated in favor of `%define api.pure', so use
+         `%define api.pure' in a backward-compatible manner here.  First, don't
+         complain if %pure-parser is specified multiple times.  */
+      if (!muscle_find_const ("percent_define(api.pure)"))
+        muscle_percent_define_insert ("api.pure", @1, "",
+                                      MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+      /* In all cases, use api.pure now so that the backend doesn't complain if
+         the skeleton ignores api.pure, but do warn now if there's a previous
+         conflicting definition from an actual %define.  */
+      if (!muscle_percent_define_flag_if ("api.pure"))
+        muscle_percent_define_insert ("api.pure", @1, "",
+                                      MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+    }
+| "%require" STRING             { version_check (&@2, $2); }
+| "%skeleton" STRING
+    {
+      char const *skeleton_user = $2;
+      if (mbschr (skeleton_user, '/'))
+        {
+          size_t dir_length = strlen (current_file);
+          char *skeleton_build;
+          while (dir_length && current_file[dir_length - 1] != '/')
+            --dir_length;
+          while (dir_length && current_file[dir_length - 1] == '/')
+            --dir_length;
+          skeleton_build =
+            xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
+          if (dir_length > 0)
+            {
+              memcpy (skeleton_build, current_file, dir_length);
+              skeleton_build[dir_length++] = '/';
+            }
+          strcpy (skeleton_build + dir_length, skeleton_user);
+          skeleton_user = uniqstr_new (skeleton_build);
+          free (skeleton_build);
+        }
+      skeleton_arg (skeleton_user, grammar_prio, @1);
+    }
+| "%token-table"                { token_table_flag = true; }
+| "%verbose"                    { report_flag |= report_states; }
+| "%yacc"                       { yacc_flag = true; }
 | /*FIXME: Err?  What is this horror doing here? */ ";"
 ;
 
@@ -259,35 +346,29 @@
     {
       grammar_start_symbol_set ($2, @2);
     }
-| "%union {...}"
+| "%destructor" "{...}" generic_symlist
     {
-      char const *body = $1;
-
-      if (typed)
-	{
-	  /* Concatenate the union bodies, turning the first one's
-	     trailing '}' into '\n', and omitting the second one's '{'.  */
-	  char *code = muscle_find ("stype");
-	  code[strlen (code) - 1] = '\n';
-	  body++;
-	}
-
-      typed = true;
-      muscle_code_grow ("stype", body, @1);
+      code_props code;
+      code_props_symbol_action_init (&code, $2, @2);
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = $3; list; list = list->next)
+          symbol_list_destructor_set (list, &code);
+        symbol_list_free ($3);
+      }
     }
-| "%destructor {...}" symbols.1
+| "%printer" "{...}" generic_symlist
     {
-      symbol_list *list;
-      for (list = $2; list; list = list->next)
-	symbol_destructor_set (list->sym, $1, @1);
-      symbol_list_free ($2);
-    }
-| "%printer {...}" symbols.1
-    {
-      symbol_list *list;
-      for (list = $2; list; list = list->next)
-	symbol_printer_set (list->sym, $1, @1);
-      symbol_list_free ($2);
+      code_props code;
+      code_props_symbol_action_init (&code, $2, @2);
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = $3; list; list = list->next)
+          symbol_list_printer_set (list, &code);
+        symbol_list_free ($3);
+      }
     }
 | "%default-prec"
     {
@@ -297,8 +378,44 @@
     {
       default_prec = false;
     }
+| "%code" braceless
+    {
+      /* Do not invoke muscle_percent_code_grow here since it invokes
+         muscle_user_name_list_grow.  */
+      muscle_code_grow ("percent_code()", $2, @2);
+      code_scanner_last_string_free ();
+    }
+| "%code" ID braceless
+    {
+      muscle_percent_code_grow ($2, @2, $3, @3);
+      code_scanner_last_string_free ();
+    }
 ;
 
+
+/*----------*
+ | %union.  |
+ *----------*/
+
+%token PERCENT_UNION "%union";
+
+union_name:
+  /* Nothing. */ {}
+| ID             { muscle_code_grow ("union_name", $1, @1); }
+;
+
+grammar_declaration:
+  "%union" union_name braceless
+    {
+      union_seen = true;
+      muscle_code_grow ("stype", $3, @3);
+      code_scanner_last_string_free ();
+    }
+;
+
+
+
+
 symbol_declaration:
   "%nterm" { current_class = nterm_sym; } symbol_defs.1
     {
@@ -313,21 +430,22 @@
 | "%type" TYPE symbols.1
     {
       symbol_list *list;
+      tag_seen = true;
       for (list = $3; list; list = list->next)
-	symbol_type_set (list->sym, $2, @2);
+	symbol_type_set (list->content.sym, $2, @2);
       symbol_list_free ($3);
     }
 ;
 
 precedence_declaration:
-  precedence_declarator type.opt symbols.1
+  precedence_declarator type.opt symbols.prec
     {
       symbol_list *list;
       ++current_prec;
       for (list = $3; list; list = list->next)
 	{
-	  symbol_type_set (list->sym, current_type, @2);
-	  symbol_precedence_set (list->sym, current_prec, $1, @1);
+	  symbol_type_set (list->content.sym, current_type, @2);
+	  symbol_precedence_set (list->content.sym, current_prec, $1, @1);
 	}
       symbol_list_free ($3);
       current_type = NULL;
@@ -342,14 +460,40 @@
 
 type.opt:
   /* Nothing. */ { current_type = NULL; }
-| TYPE           { current_type = $1; }
+| TYPE           { current_type = $1; tag_seen = true; }
 ;
 
-/* One or more nonterminals to be %typed. */
+/* Just like symbols.1 but accept INT for the sake of POSIX.  */
+symbols.prec:
+  symbol.prec
+    { $$ = symbol_list_sym_new ($1, @1); }
+| symbols.prec symbol.prec
+    { $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
+;
 
+symbol.prec:
+    symbol { $$ = $1; }
+  | symbol INT { $$ = $1; symbol_user_token_number_set ($1, $2, @2); }
+  ;
+
+/* One or more symbols to be %typed. */
 symbols.1:
-  symbol            { $$ = symbol_list_new ($1, @1); }
-| symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
+  symbol
+    { $$ = symbol_list_sym_new ($1, @1); }
+| symbols.1 symbol
+    { $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
+;
+
+generic_symlist:
+  generic_symlist_item { $$ = $1; }
+| generic_symlist generic_symlist_item { $$ = symbol_list_prepend ($1, $2); }
+;
+
+generic_symlist_item:
+  symbol            { $$ = symbol_list_sym_new ($1, @1); }
+| TYPE              { $$ = symbol_list_type_new ($1, @1); }
+| "<*>"             { $$ = symbol_list_default_tagged_new (@1); }
+| "<>"             { $$ = symbol_list_default_tagless_new (@1); }
 ;
 
 /* One token definition.  */
@@ -357,25 +501,26 @@
   TYPE
      {
        current_type = $1;
+       tag_seen = true;
      }
-| ID
+| id
      {
        symbol_class_set ($1, current_class, @1, true);
        symbol_type_set ($1, current_type, @1);
      }
-| ID INT
+| id INT
     {
       symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
     }
-| ID string_as_id
+| id string_as_id
     {
       symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_make_alias ($1, $2, @$);
     }
-| ID INT string_as_id
+| id INT string_as_id
     {
       symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
@@ -412,7 +557,11 @@
 ;
 
 rules:
-  ID_COLON { current_lhs = $1; current_lhs_location = @1; } rhses.1
+  id_colon named_ref.opt { current_lhs ($1, @1, $2); } rhses.1
+  {
+    /* Free the current lhs. */
+    current_lhs (0, @1, 0);
+  }
 ;
 
 rhses.1:
@@ -423,10 +572,12 @@
 
 rhs:
   /* Nothing.  */
-    { grammar_current_rule_begin (current_lhs, current_lhs_location); }
-| rhs symbol
-    { grammar_current_rule_symbol_append ($2, @2); }
-| rhs action
+    { grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
+				  current_lhs_named_ref); }
+| rhs symbol named_ref.opt
+    { grammar_current_rule_symbol_append ($2, @2, $3); }
+| rhs "{...}" named_ref.opt
+    { grammar_current_rule_action_append ($2, @2, $3); }
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
@@ -435,26 +586,75 @@
     { grammar_current_rule_merge_set ($3, @3); }
 ;
 
-symbol:
-  ID              { $$ = $1; }
-| string_as_id    { $$ = $1; }
+named_ref.opt:
+  /* Nothing. */ { $$ = 0; }
+|
+  BRACKETED_ID   { $$ = named_ref_new($1, @1); }
 ;
 
-/* Handle the semantics of an action specially, with a mid-rule
-   action, so that grammar_current_rule_action_append is invoked
-   immediately after the braced code is read by the scanner.
 
-   This implementation relies on the LALR(1) parsing algorithm.
-   If grammar_current_rule_action_append were executed in a normal
-   action for this rule, then when the input grammar contains two
-   successive actions, the scanner would have to read both actions
-   before reducing this rule.  That wouldn't work, since the scanner
-   relies on all preceding input actions being processed by
-   grammar_current_rule_action_append before it scans the next
-   action.  */
-action:
-    { grammar_current_rule_action_append (last_string, last_braced_code_loc); }
-  BRACED_CODE
+/*----------------------------*
+ | variable and content.opt.  |
+ *---------------------------*/
+
+/* The STRING form of variable is deprecated and is not M4-friendly.
+   For example, M4 fails for `%define "[" "value"'.  */
+variable:
+  ID
+| STRING { $$ = uniqstr_new ($1); }
+;
+
+/* Some content or empty by default. */
+content.opt:
+  /* Nothing. */   { $$ = ""; }
+| ID { $$ = $1; }
+| STRING
+;
+
+
+/*-------------*
+ | braceless.  |
+ *-------------*/
+
+braceless:
+  "{...}"
+    {
+      code_props plain_code;
+      $1[strlen ($1) - 1] = '\n';
+      code_props_plain_init (&plain_code, $1+1, @1);
+      code_props_translate_code (&plain_code);
+      gram_scanner_last_string_free ();
+      $$ = plain_code.code;
+    }
+;
+
+
+/*---------------*
+ | Identifiers.  |
+ *---------------*/
+
+/* Identifiers are returned as uniqstr values by the scanner.
+   Depending on their use, we may need to make them genuine symbols.  */
+
+id:
+  ID
+    { $$ = symbol_from_uniqstr ($1, @1); }
+| CHAR
+    {
+      $$ = symbol_get (char_name ($1), @1);
+      symbol_class_set ($$, token_sym, @1, false);
+      symbol_user_token_number_set ($$, $1, @1);
+    }
+;
+
+id_colon:
+  ID_COLON { $$ = symbol_from_uniqstr ($1, @1); }
+;
+
+
+symbol:
+  id
+| string_as_id
 ;
 
 /* A string used as an ID: quote it.  */
@@ -466,19 +666,16 @@
     }
 ;
 
-/* A string used for its contents.  Don't quote it.  */
-string_content:
-  STRING
-    { $$ = $1; }
-;
-
-
 epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
     {
-      muscle_code_grow ("epilogue", $2, @2);
-      scanner_last_string_free ();
+      code_props plain_code;
+      code_props_plain_init (&plain_code, $2, @2);
+      code_props_translate_code (&plain_code);
+      gram_scanner_last_string_free ();
+      muscle_code_grow ("epilogue", plain_code.code, @2);
+      code_scanner_last_string_free ();
     }
 ;
 
@@ -501,7 +698,7 @@
   loc.start = rhs[n].end;
   loc.end = rhs[n].end;
 
-  /* Ignore empty nonterminals the start of the the right-hand side.
+  /* Ignore empty nonterminals the start of the right-hand side.
      Do not bother to ignore them at the end of the right-hand side,
      since empty nonterminals have the same end as their predecessors.  */
   for (i = 1; i <= n; i++)
@@ -538,42 +735,35 @@
 
   /* Strip the surrounding '{' and '}', and any blanks just inside
      the braces.  */
-  while (*--p == ' ' || *p == '\t')
-    continue;
+  --p;
+  while (c_isspace ((unsigned char) *p))
+    --p;
   p[1] = '\0';
-  while (*++decl == ' ' || *decl == '\t')
-    continue;
+  ++decl;
+  while (c_isspace ((unsigned char) *decl))
+    ++decl;
 
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));
   else
     {
-      char *name;
-      size_t name_len;
-
-      for (name_len = 1;
-	   memchr (alphanum, name_start[name_len], sizeof alphanum);
-	   name_len++)
-	continue;
-
-      name = xmalloc (name_len + 1);
-      memcpy (name, name_start, name_len);
-      name[name_len] = '\0';
+      char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
       muscle_pair_list_grow (type, decl, name);
       free (name);
     }
 
-  scanner_last_string_free ();
+  gram_scanner_last_string_free ();
 }
 
+
 static void
 version_check (location const *loc, char const *version)
 {
   if (strverscmp (version, PACKAGE_VERSION) > 0)
     {
       complain_at (*loc, "require bison %s, but have %s",
-		   version, PACKAGE_VERSION);
-      exit (63);
+                   version, PACKAGE_VERSION);
+      exit (EX_MISMATCH);
     }
 }
 
@@ -588,3 +778,16 @@
 {
   return yytname[YYTRANSLATE (type)];
 }
+
+static char const *
+char_name (char c)
+{
+  if (c == '\'')
+    return "'\\''";
+  else
+    {
+      char buf[4];
+      buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
+      return quotearg_style (escape_quoting_style, buf);
+    }
+}
diff --git a/src/print-xml.c b/src/print-xml.c
new file mode 100644
index 0000000..e37a741
--- /dev/null
+++ b/src/print-xml.c
@@ -0,0 +1,538 @@
+/* Print an xml on generated parser, for Bison,
+
+   Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "system.h"
+
+#include <stdarg.h>
+
+#include <bitset.h>
+
+#include "LR0.h"
+#include "closure.h"
+#include "conflicts.h"
+#include "files.h"
+#include "getargs.h"
+#include "gram.h"
+#include "lalr.h"
+#include "print.h"
+#include "print-xml.h"
+#include "reader.h"
+#include "reduce.h"
+#include "state.h"
+#include "symtab.h"
+#include "tables.h"
+
+static bitset no_reduce_set;
+struct escape_buf
+{
+  char *ptr;
+  size_t size;
+};
+static struct escape_buf escape_bufs[3];
+
+
+/*--------------------------------.
+| Report information on a state.  |
+`--------------------------------*/
+
+static void
+print_core (FILE *out, int level, state *s)
+{
+  size_t i;
+  item_number *sitems = s->items;
+  size_t snritems = s->nitems;
+
+  /* Output all the items of a state, not only its kernel.  */
+  closure (sitems, snritems);
+  sitems = itemset;
+  snritems = nitemset;
+
+  if (!snritems) {
+    xml_puts (out, level, "<itemset/>");
+    return;
+  }
+
+  xml_puts (out, level, "<itemset>");
+
+  for (i = 0; i < snritems; i++)
+    {
+      bool printed = false;
+      item_number *sp;
+      item_number *sp1;
+      rule_number r;
+
+      sp1 = sp = ritem + sitems[i];
+
+      while (*sp >= 0)
+	sp++;
+
+      r = item_number_as_rule_number (*sp);
+      sp = rules[r].rhs;
+
+      /* Display the lookahead tokens?  */
+      if (item_number_is_rule_number (*sp1))
+	{
+	  reductions *reds = s->reductions;
+	  int red = state_reduction_find (s, &rules[r]);
+	  /* Print item with lookaheads if there are. */
+	  if (reds->lookahead_tokens && red != -1)
+	    {
+	      xml_printf (out, level + 1,
+			  "<item rule-number=\"%d\" point=\"%d\">",
+			  rules[r].number, sp1 - sp);
+	      state_rule_lookahead_tokens_print_xml (s, &rules[r],
+						     out, level + 2);
+	      xml_puts (out, level + 1, "</item>");
+	      printed = true;
+	    }
+	}
+
+      if (!printed)
+	{
+	  xml_printf (out, level + 1,
+		      "<item rule-number=\"%d\" point=\"%d\"/>",
+		      rules[r].number,
+		      sp1 - sp);
+	}
+    }
+  xml_puts (out, level, "</itemset>");
+}
+
+
+/*-----------------------------------------------------------.
+| Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on |
+| OUT.                                                       |
+`-----------------------------------------------------------*/
+
+static void
+print_transitions (state *s, FILE *out, int level)
+{
+  transitions *trans = s->transitions;
+  int n = 0;
+  int i;
+
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i))
+      {
+	n++;
+      }
+
+  /* Nothing to report. */
+  if (!n) {
+    xml_puts (out, level, "<transitions/>");
+    return;
+  }
+
+  /* Report lookahead tokens and shifts.  */
+  xml_puts (out, level, "<transitions>");
+
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i)
+	&& TRANSITION_IS_SHIFT (trans, i))
+      {
+	symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+	char const *tag = sym->tag;
+	state *s1 = trans->states[i];
+
+	xml_printf (out, level + 1,
+		    "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>",
+		    xml_escape (tag), s1->number);
+      }
+
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i)
+	&& !TRANSITION_IS_SHIFT (trans, i))
+      {
+	symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+	char const *tag = sym->tag;
+	state *s1 = trans->states[i];
+
+	xml_printf (out, level + 1,
+		    "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>",
+		    xml_escape (tag), s1->number);
+      }
+
+  xml_puts (out, level, "</transitions>");
+}
+
+
+/*--------------------------------------------------------.
+| Report the explicit errors of S raised from %nonassoc.  |
+`--------------------------------------------------------*/
+
+static void
+print_errs (FILE *out, int level, state *s)
+{
+  errs *errp = s->errs;
+  bool count = false;
+  int i;
+
+  for (i = 0; i < errp->num; ++i)
+    if (errp->symbols[i])
+      count = true;
+
+  /* Nothing to report. */
+  if (!count) {
+    xml_puts (out, level, "<errors/>");
+    return;
+  }
+
+  /* Report lookahead tokens and errors.  */
+  xml_puts (out, level, "<errors>");
+  for (i = 0; i < errp->num; ++i)
+    if (errp->symbols[i])
+      {
+	char const *tag = errp->symbols[i]->tag;
+	xml_printf (out, level + 1,
+		    "<error symbol=\"%s\">nonassociative</error>",
+		    xml_escape (tag));
+      }
+  xml_puts (out, level, "</errors>");
+}
+
+
+/*-------------------------------------------------------------------------.
+| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default').  |
+| If not ENABLED, the rule is masked by a shift or a reduce (S/R and       |
+| R/R conflicts).                                                          |
+`-------------------------------------------------------------------------*/
+
+static void
+print_reduction (FILE *out, int level, char const *lookahead_token,
+		 rule *r, bool enabled)
+{
+  if (r->number)
+    xml_printf (out, level,
+		"<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
+		xml_escape (lookahead_token),
+		r->number,
+		enabled ? "true" : "false");
+  else
+    xml_printf (out, level,
+		"<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
+		xml_escape (lookahead_token),
+		enabled ? "true" : "false");
+}
+
+
+/*-------------------------------------------.
+| Report on OUT the reduction actions of S.  |
+`-------------------------------------------*/
+
+static void
+print_reductions (FILE *out, int level, state *s)
+{
+  transitions *trans = s->transitions;
+  reductions *reds = s->reductions;
+  rule *default_reduction = NULL;
+  int report = false;
+  int i, j;
+
+  if (reds->num == 0)
+    {
+      xml_puts (out, level, "<reductions/>");
+      return;
+    }
+
+  if (yydefact[s->number] != 0)
+    default_reduction = &rules[yydefact[s->number] - 1];
+
+  bitset_zero (no_reduce_set);
+  FOR_EACH_SHIFT (trans, i)
+    bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
+  for (i = 0; i < s->errs->num; ++i)
+    if (s->errs->symbols[i])
+      bitset_set (no_reduce_set, s->errs->symbols[i]->number);
+
+  if (default_reduction)
+    report = true;
+
+  if (reds->lookahead_tokens)
+    for (i = 0; i < ntokens; i++)
+      {
+	bool count = bitset_test (no_reduce_set, i);
+
+	for (j = 0; j < reds->num; ++j)
+	  if (bitset_test (reds->lookahead_tokens[j], i))
+	    {
+	      if (! count)
+		{
+		  if (reds->rules[j] != default_reduction)
+		    report = true;
+		  count = true;
+		}
+	      else
+		{
+		  report = true;
+		}
+	    }
+      }
+
+  /* Nothing to report. */
+  if (!report) {
+    xml_puts (out, level, "<reductions/>");
+    return;
+  }
+
+  xml_puts (out, level, "<reductions>");
+
+  /* Report lookahead tokens (or $default) and reductions.  */
+  if (reds->lookahead_tokens)
+    for (i = 0; i < ntokens; i++)
+      {
+	bool defaulted = false;
+	bool count = bitset_test (no_reduce_set, i);
+
+	for (j = 0; j < reds->num; ++j)
+	  if (bitset_test (reds->lookahead_tokens[j], i))
+	    {
+	      if (! count)
+		{
+		  if (reds->rules[j] != default_reduction)
+		    print_reduction (out, level + 1, symbols[i]->tag,
+				     reds->rules[j], true);
+		  else
+		    defaulted = true;
+		  count = true;
+		}
+	      else
+		{
+		  if (defaulted)
+		    print_reduction (out, level + 1, symbols[i]->tag,
+				     default_reduction, true);
+		  defaulted = false;
+		  print_reduction (out, level + 1, symbols[i]->tag,
+				   reds->rules[j], false);
+		}
+	    }
+      }
+
+  if (default_reduction)
+    print_reduction (out, level + 1,
+		     "$default", default_reduction, true);
+
+  xml_puts (out, level, "</reductions>");
+}
+
+
+/*--------------------------------------------------------------.
+| Report on OUT all the actions (shifts, gotos, reductions, and |
+| explicit erros from %nonassoc) of S.                          |
+`--------------------------------------------------------------*/
+
+static void
+print_actions (FILE *out, int level, state *s)
+{
+  xml_puts (out, level, "<actions>");
+  print_transitions (s, out, level + 1);
+  print_errs (out, level + 1, s);
+  print_reductions (out, level + 1, s);
+  xml_puts (out, level, "</actions>");
+}
+
+
+/*----------------------------------.
+| Report all the data on S on OUT.  |
+`----------------------------------*/
+
+static void
+print_state (FILE *out, int level, state *s)
+{
+  fputc ('\n', out);
+  xml_printf (out, level, "<state number=\"%d\">", s->number);
+  print_core (out, level + 1, s);
+  print_actions (out, level + 1, s);
+  if (s->solved_conflicts_xml)
+    {
+      xml_puts (out, level + 1, "<solved-conflicts>");
+      fputs (s->solved_conflicts_xml, out);
+      xml_puts (out, level + 1, "</solved-conflicts>");
+    }
+  else
+    xml_puts (out, level + 1, "<solved-conflicts/>");
+  xml_puts (out, level, "</state>");
+}
+
+
+/*-----------------------------------------.
+| Print information on the whole grammar.  |
+`-----------------------------------------*/
+
+static void
+print_grammar (FILE *out, int level)
+{
+  symbol_number i;
+
+  fputc ('\n', out);
+  xml_puts (out, level, "<grammar>");
+  grammar_rules_print_xml (out, level);
+
+  /* Terminals */
+  xml_puts (out, level + 1, "<terminals>");
+  for (i = 0; i < max_user_token_number + 1; i++)
+    if (token_translations[i] != undeftoken->number)
+      {
+	char const *tag = symbols[token_translations[i]]->tag;
+        int precedence = symbols[token_translations[i]]->prec;
+        assoc associativity = symbols[token_translations[i]]->assoc;
+        xml_indent (out, level + 2);
+        fprintf (out,
+                 "<terminal symbol-number=\"%d\" token-number=\"%d\""
+                 " name=\"%s\" usefulness=\"%s\"",
+                 token_translations[i], i, xml_escape (tag),
+                 reduce_token_unused_in_grammar (token_translations[i])
+                   ? "unused-in-grammar" : "useful");
+        if (precedence)
+          fprintf (out, " prec=\"%d\"", precedence);
+        if (associativity != undef_assoc)
+          fprintf (out, " assoc=\"%s\"", assoc_to_string (associativity) + 1);
+        fputs ("/>\n", out);
+      }
+  xml_puts (out, level + 1, "</terminals>");
+
+  /* Nonterminals */
+  xml_puts (out, level + 1, "<nonterminals>");
+  for (i = ntokens; i < nsyms + nuseless_nonterminals; i++)
+    {
+      char const *tag = symbols[i]->tag;
+      xml_printf (out, level + 2,
+		  "<nonterminal symbol-number=\"%d\" name=\"%s\""
+                  " usefulness=\"%s\"/>",
+		  i, xml_escape (tag),
+                  reduce_nonterminal_useless_in_grammar (i)
+                    ? "useless-in-grammar" : "useful");
+    }
+  xml_puts (out, level + 1, "</nonterminals>");
+  xml_puts (out, level, "</grammar>");
+}
+
+void
+xml_indent (FILE *out, int level)
+{
+  int i;
+  for (i = 0; i < level; i++)
+    fputs ("  ", out);
+}
+
+void
+xml_puts (FILE *out, int level, char const *s)
+{
+  xml_indent (out, level);
+  fputs (s, out);
+  fputc ('\n', out);
+}
+
+void
+xml_printf (FILE *out, int level, char const *fmt, ...)
+{
+  va_list arglist;
+
+  xml_indent (out, level);
+
+  va_start (arglist, fmt);
+  vfprintf (out, fmt, arglist);
+  va_end (arglist);
+
+  fputc ('\n', out);
+}
+
+static char const *
+xml_escape_string (struct escape_buf *buf, char const *str)
+{
+  size_t len = strlen (str);
+  size_t max_expansion = sizeof "&quot;" - 1;
+  char *p;
+
+  if (buf->size <= max_expansion * len)
+    {
+      buf->size = max_expansion * len + 1;
+      buf->ptr = x2realloc (buf->ptr, &buf->size);
+    }
+  p = buf->ptr;
+
+  for (; *str; str++)
+    switch (*str)
+      {
+      default: *p++ = *str; break;
+      case '&': p = stpcpy (p, "&amp;" ); break;
+      case '<': p = stpcpy (p, "&lt;"  ); break;
+      case '>': p = stpcpy (p, "&gt;"  ); break;
+      case '"': p = stpcpy (p, "&quot;"); break;
+      }
+
+  *p = '\0';
+  return buf->ptr;
+}
+
+char const *
+xml_escape_n (int n, char const *str)
+{
+  return xml_escape_string (escape_bufs + n, str);
+}
+
+char const *
+xml_escape (char const *str)
+{
+  return xml_escape_n (0, str);
+}
+
+void
+print_xml (void)
+{
+  state_number i;
+  int level = 0;
+
+  FILE *out = xfopen (spec_xml_file, "w");
+
+  fputs ("<?xml version=\"1.0\"?>\n\n", out);
+  xml_printf (out, level,
+              "<bison-xml-report version=\"%s\" bug-report=\"%s\""
+              " url=\"%s\">",
+              xml_escape_n (0, VERSION),
+              xml_escape_n (1, PACKAGE_BUGREPORT),
+              xml_escape_n (2, PACKAGE_URL));
+
+  fputc ('\n', out);
+  xml_printf (out, level + 1, "<filename>%s</filename>",
+	      xml_escape (grammar_file));
+
+  /* print grammar */
+  print_grammar (out, level + 1);
+
+  new_closure (nritems);
+  no_reduce_set =  bitset_create (ntokens, BITSET_FIXED);
+
+  /* print automaton */
+  fputc ('\n', out);
+  xml_puts (out, level + 1, "<automaton>");
+  for (i = 0; i < nstates; i++)
+    print_state (out, level + 2, states[i]);
+  xml_puts (out, level + 1, "</automaton>");
+
+  bitset_free (no_reduce_set);
+  free_closure ();
+
+  xml_puts (out, 0, "</bison-xml-report>");
+
+  free (escape_bufs[0].ptr);
+  free (escape_bufs[1].ptr);
+
+  xfclose (out);
+}
diff --git a/src/print-xml.h b/src/print-xml.h
new file mode 100644
index 0000000..c0ea2e7
--- /dev/null
+++ b/src/print-xml.h
@@ -0,0 +1,30 @@
+/* Output an xml of the generated parser, for Bison.
+
+   Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef PRINT_XML_H_
+# define PRINT_XML_H_
+
+void xml_indent (FILE *out, int level);
+void xml_puts (FILE *, int, char const *);
+void xml_printf (FILE *, int, char const *, ...);
+char const *xml_escape_n (int n, char const *str);
+char const *xml_escape (char const *str);
+void print_xml (void);
+
+#endif /* !PRINT_XML_H_ */
diff --git a/src/print.c b/src/print.c
index cb1600c..5fdb28b 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1,30 +1,27 @@
 /* Print information on generated parser, for bison,
 
-   Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 2000-2005, 2007, 2009-2012 Free
+   Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
 #include <bitset.h>
-#include <quotearg.h>
 
 #include "LR0.h"
 #include "closure.h"
@@ -33,14 +30,15 @@
 #include "getargs.h"
 #include "gram.h"
 #include "lalr.h"
+#include "muscle-tab.h"
 #include "print.h"
 #include "reader.h"
 #include "reduce.h"
 #include "state.h"
 #include "symtab.h"
+#include "tables.h"
 
-static bitset shift_set;
-static bitset look_ahead_set;
+static bitset no_reduce_set;
 
 #if 0
 static void
@@ -81,7 +79,7 @@
     {
       closure (sitems, snritems);
       sitems = itemset;
-      snritems = nritemset;
+      snritems = nitemset;
     }
 
   if (!snritems)
@@ -111,9 +109,10 @@
       for (/* Nothing */; *sp >= 0; ++sp)
 	fprintf (out, " %s", symbols[*sp]->tag);
 
-      /* Display the look-ahead tokens?  */
-      if (report_flag & report_look_ahead_tokens)
-	state_rule_look_ahead_tokens_print (s, &rules[r], out);
+      /* Display the lookahead tokens?  */
+      if (report_flag & report_lookahead_tokens
+          && item_number_is_rule_number (*sp1))
+	state_rule_lookahead_tokens_print (s, &rules[r], out);
 
       fputc ('\n', out);
     }
@@ -132,7 +131,7 @@
   size_t width = 0;
   int i;
 
-  /* Compute the width of the look-ahead token column.  */
+  /* Compute the width of the lookahead token column.  */
   for (i = 0; i < trans->num; i++)
     if (!TRANSITION_IS_DISABLED (trans, i)
 	&& TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
@@ -148,7 +147,7 @@
   fputc ('\n', out);
   width += 2;
 
-  /* Report look-ahead tokens and shifts.  */
+  /* Report lookahead tokens and shifts.  */
   for (i = 0; i < trans->num; i++)
     if (!TRANSITION_IS_DISABLED (trans, i)
 	&& TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
@@ -180,7 +179,7 @@
   size_t width = 0;
   int i;
 
-  /* Compute the width of the look-ahead token column.  */
+  /* Compute the width of the lookahead token column.  */
   for (i = 0; i < errp->num; ++i)
     if (errp->symbols[i])
       max_length (&width, errp->symbols[i]->tag);
@@ -192,7 +191,7 @@
   fputc ('\n', out);
   width += 2;
 
-  /* Report look-ahead tokens and errors.  */
+  /* Report lookahead tokens and errors.  */
   for (i = 0; i < errp->num; ++i)
     if (errp->symbols[i])
       {
@@ -206,85 +205,20 @@
 }
 
 
-/*-------------------------------------------------------------.
-| Return the default rule of S if it has one, NULL otherwise.  |
-`-------------------------------------------------------------*/
-
-static rule *
-state_default_rule (state *s)
-{
-  reductions *reds = s->reductions;
-  rule *default_rule = NULL;
-  int cmax = 0;
-  int i;
-
-  /* No need for a look-ahead.  */
-  if (s->consistent)
-    return reds->rules[0];
-
-  /* 1. Each reduction is possibly masked by the look-ahead tokens on which
-     we shift (S/R conflicts)...  */
-  bitset_zero (shift_set);
-  {
-    transitions *trans = s->transitions;
-    FOR_EACH_SHIFT (trans, i)
-      {
-	/* If this state has a shift for the error token, don't use a
-	     default rule.  */
-	if (TRANSITION_IS_ERROR (trans, i))
-	  return NULL;
-	bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
-      }
-  }
-
-  /* 2. Each reduction is possibly masked by the look-ahead tokens on which
-     we raise an error (due to %nonassoc).  */
-  {
-    errs *errp = s->errs;
-    for (i = 0; i < errp->num; i++)
-      if (errp->symbols[i])
-	bitset_set (shift_set, errp->symbols[i]->number);
-  }
-
-  for (i = 0; i < reds->num; ++i)
-    {
-      int count = 0;
-
-      /* How many non-masked look-ahead tokens are there for this
-	 reduction?  */
-      bitset_andn (look_ahead_set, reds->look_ahead_tokens[i], shift_set);
-      count = bitset_count (look_ahead_set);
-
-      if (count > cmax)
-	{
-	  cmax = count;
-	  default_rule = reds->rules[i];
-	}
-
-      /* 3. And finally, each reduction is possibly masked by previous
-	 reductions (in R/R conflicts, we keep the first reductions).
-	 */
-      bitset_or (shift_set, shift_set, reds->look_ahead_tokens[i]);
-    }
-
-  return default_rule;
-}
-
-
-/*--------------------------------------------------------------------------.
-| Report a reduction of RULE on LOOK_AHEAD_TOKEN (which can be `default').  |
-| If not ENABLED, the rule is masked by a shift or a reduce (S/R and        |
-| R/R conflicts).                                                           |
-`--------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------.
+| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default').  |
+| If not ENABLED, the rule is masked by a shift or a reduce (S/R and       |
+| R/R conflicts).                                                          |
+`-------------------------------------------------------------------------*/
 
 static void
 print_reduction (FILE *out, size_t width,
-		 const char *look_ahead_token,
+		 const char *lookahead_token,
 		 rule *r, bool enabled)
 {
   int j;
-  fprintf (out, "    %s", look_ahead_token);
-  for (j = width - strlen (look_ahead_token); j > 0; --j)
+  fprintf (out, "    %s", lookahead_token);
+  for (j = width - strlen (lookahead_token); j > 0; --j)
     fputc (' ', out);
   if (!enabled)
     fputc ('[', out);
@@ -307,34 +241,39 @@
 {
   transitions *trans = s->transitions;
   reductions *reds = s->reductions;
-  rule *default_rule = NULL;
+  rule *default_reduction = NULL;
   size_t width = 0;
   int i, j;
+  bool default_reduction_only = true;
 
   if (reds->num == 0)
     return;
 
-  default_rule = state_default_rule (s);
+  if (yydefact[s->number] != 0)
+    default_reduction = &rules[yydefact[s->number] - 1];
 
-  bitset_zero (shift_set);
+  bitset_zero (no_reduce_set);
   FOR_EACH_SHIFT (trans, i)
-    bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
+    bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
+  for (i = 0; i < s->errs->num; ++i)
+    if (s->errs->symbols[i])
+      bitset_set (no_reduce_set, s->errs->symbols[i]->number);
 
-  /* Compute the width of the look-ahead token column.  */
-  if (default_rule)
+  /* Compute the width of the lookahead token column.  */
+  if (default_reduction)
     width = strlen (_("$default"));
 
-  if (reds->look_ahead_tokens)
+  if (reds->lookahead_tokens)
     for (i = 0; i < ntokens; i++)
       {
-	bool count = bitset_test (shift_set, i);
+	bool count = bitset_test (no_reduce_set, i);
 
 	for (j = 0; j < reds->num; ++j)
-	  if (bitset_test (reds->look_ahead_tokens[j], i))
+	  if (bitset_test (reds->lookahead_tokens[j], i))
 	    {
 	      if (! count)
 		{
-		  if (reds->rules[j] != default_rule)
+		  if (reds->rules[j] != default_reduction)
 		    max_length (&width, symbols[i]->tag);
 		  count = true;
 		}
@@ -352,32 +291,38 @@
   fputc ('\n', out);
   width += 2;
 
-  /* Report look-ahead tokens (or $default) and reductions.  */
-  if (reds->look_ahead_tokens)
+  /* Report lookahead tokens (or $default) and reductions.  */
+  if (reds->lookahead_tokens)
     for (i = 0; i < ntokens; i++)
       {
 	bool defaulted = false;
-	bool count = bitset_test (shift_set, i);
+	bool count = bitset_test (no_reduce_set, i);
+        if (count)
+          default_reduction_only = false;
 
 	for (j = 0; j < reds->num; ++j)
-	  if (bitset_test (reds->look_ahead_tokens[j], i))
+	  if (bitset_test (reds->lookahead_tokens[j], i))
 	    {
 	      if (! count)
 		{
-		  if (reds->rules[j] != default_rule)
-		    print_reduction (out, width,
-				     symbols[i]->tag,
-				     reds->rules[j], true);
+		  if (reds->rules[j] != default_reduction)
+                    {
+                      default_reduction_only = false;
+                      print_reduction (out, width,
+                                       symbols[i]->tag,
+                                       reds->rules[j], true);
+                    }
 		  else
 		    defaulted = true;
 		  count = true;
 		}
 	      else
 		{
+                  default_reduction_only = false;
 		  if (defaulted)
 		    print_reduction (out, width,
 				     symbols[i]->tag,
-				     default_rule, true);
+				     default_reduction, true);
 		  defaulted = false;
 		  print_reduction (out, width,
 				   symbols[i]->tag,
@@ -386,9 +331,17 @@
 	    }
       }
 
-  if (default_rule)
-    print_reduction (out, width,
-		     _("$default"), default_rule, true);
+  if (default_reduction)
+    {
+      char *default_reductions =
+        muscle_percent_define_get ("lr.default-reductions");
+      print_reduction (out, width, _("$default"), default_reduction, true);
+      aver (0 == strcmp (default_reductions, "most")
+            || (0 == strcmp (default_reductions, "consistent")
+                && default_reduction_only)
+            || (reds->num == 1 && reds->rules[0]->number == 0));
+      free (default_reductions);
+    }
 }
 
 
@@ -417,7 +370,7 @@
 print_state (FILE *out, state *s)
 {
   fputs ("\n\n", out);
-  fprintf (out, _("state %d"), s->number);
+  fprintf (out, _("State %d"), s->number);
   fputc ('\n', out);
   print_core (out, s);
   print_actions (out, s);
@@ -464,7 +417,7 @@
 	buffer[0] = 0;
 	column = strlen (tag);
 	fputs (tag, out);
-	END_TEST (50);
+	END_TEST (65);
 	sprintf (buffer, " (%d)", i);
 
 	for (r = 0; r < nrules; r++)
@@ -508,14 +461,16 @@
 
       if (left_count > 0)
 	{
-	  END_TEST (50);
+	  END_TEST (65);
 	  sprintf (buffer + strlen (buffer), _(" on left:"));
 
 	  for (r = 0; r < nrules; r++)
 	    {
-	      END_TEST (65);
 	      if (rules[r].lhs->number == i)
-		sprintf (buffer + strlen (buffer), " %d", r);
+		{
+		  END_TEST (65);
+		  sprintf (buffer + strlen (buffer), " %d", r);
+		}
 	    }
 	}
 
@@ -523,7 +478,7 @@
 	{
 	  if (left_count > 0)
 	    sprintf (buffer + strlen (buffer), ",");
-	  END_TEST (50);
+	  END_TEST (65);
 	  sprintf (buffer + strlen (buffer), _(" on right:"));
 	  for (r = 0; r < nrules; r++)
 	    {
@@ -552,7 +507,8 @@
 
   reduce_output (out);
   grammar_rules_partial_print (out,
-			       _("Rules never reduced"), rule_never_reduced_p);
+			       _("Rules useless in parser due to conflicts"),
+                                 rule_useless_in_parser_p);
   conflicts_output (out);
 
   print_grammar (out);
@@ -562,12 +518,10 @@
   if (report_flag & report_itemsets)
     new_closure (nritems);
   /* Storage for print_reductions.  */
-  shift_set =  bitset_create (ntokens, BITSET_FIXED);
-  look_ahead_set = bitset_create (ntokens, BITSET_FIXED);
+  no_reduce_set =  bitset_create (ntokens, BITSET_FIXED);
   for (i = 0; i < nstates; i++)
     print_state (out, states[i]);
-  bitset_free (shift_set);
-  bitset_free (look_ahead_set);
+  bitset_free (no_reduce_set);
   if (report_flag & report_itemsets)
     free_closure ();
 
diff --git a/src/print.h b/src/print.h
index 1daa577..f528aaf 100644
--- a/src/print.h
+++ b/src/print.h
@@ -1,22 +1,21 @@
 /* Print information on generated parser, for bison,
-   Copyright 2000 Free Software Foundation, Inc.
+
+   Copyright (C) 2000, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef PRINT_H_
 # define PRINT_H_
diff --git a/src/print_graph.c b/src/print_graph.c
index 9580f3f..f4742b1 100644
--- a/src/print_graph.c
+++ b/src/print_graph.c
@@ -1,29 +1,25 @@
-/* Output a VCG description on generated parser, for Bison,
+/* Output a graph of the generated parser, for Bison.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
-#include <quotearg.h>
-
 #include "LR0.h"
 #include "closure.h"
 #include "complain.h"
@@ -31,26 +27,44 @@
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
+#include "graphviz.h"
 #include "lalr.h"
 #include "print_graph.h"
 #include "reader.h"
 #include "state.h"
 #include "symtab.h"
-#include "vcg.h"
-
-static graph static_graph;
-static FILE *fgraph = NULL;
 
 
 /*----------------------------.
 | Construct the node labels.  |
 `----------------------------*/
 
+/* Print the lhs of a rule in such a manner that there is no vertical
+   repetition, like in *.output files. */
+
+static void
+print_lhs (struct obstack *oout, rule *previous_rule, rule *r)
+{
+  if (previous_rule && STREQ (previous_rule->lhs->tag, r->lhs->tag))
+    {
+      int i;
+      for (i = 0; i < strlen (r->lhs->tag); ++i)
+        obstack_1grow (oout, ' ');
+      obstack_1grow (oout, '|');
+    }
+  else
+    {
+      obstack_sgrow (oout, escape (r->lhs->tag));
+      obstack_1grow (oout, ':');
+    }
+}
+
 static void
 print_core (struct obstack *oout, state *s)
 {
-  size_t i;
   item_number *sitems = s->items;
+  rule *previous_rule = NULL;
+  size_t i;
   size_t snritems = s->nitems;
 
   /* Output all the items of a state, not only its kernel.  */
@@ -58,10 +72,11 @@
     {
       closure (sitems, snritems);
       sitems = itemset;
-      snritems = nritemset;
+      snritems = nitemset;
     }
 
-  obstack_fgrow1 (oout, "state %2d\n", s->number);
+  obstack_printf (oout, _("State %d"), s->number);
+  obstack_sgrow (oout, "\\n\\l");
   for (i = 0; i < snritems; i++)
     {
       item_number *sp;
@@ -71,45 +86,47 @@
       sp1 = sp = ritem + sitems[i];
 
       while (*sp >= 0)
-	sp++;
+        sp++;
 
       r = item_number_as_rule_number (*sp);
 
-      if (i)
-	obstack_1grow (oout, '\n');
-      obstack_fgrow1 (oout, " %s -> ",
-		      rules[r].lhs->tag);
+      obstack_printf (oout, "%3d ", r);
+      print_lhs (oout, previous_rule, &rules[r]);
+      previous_rule = &rules[r];
 
       for (sp = rules[r].rhs; sp < sp1; sp++)
-	obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag);
+        obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
 
-      obstack_1grow (oout, '.');
+      obstack_sgrow (oout, " .");
 
       for (/* Nothing */; *sp >= 0; ++sp)
-	obstack_fgrow1 (oout, " %s", symbols[*sp]->tag);
+        obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
 
-      /* Experimental feature: display the look-ahead tokens. */
-      if (report_flag & report_look_ahead_tokens)
-	{
-	  /* Find the reduction we are handling.  */
-	  reductions *reds = s->reductions;
-	  int redno = state_reduction_find (s, &rules[r]);
+      /* Experimental feature: display the lookahead tokens. */
+      if (report_flag & report_lookahead_tokens
+          && item_number_is_rule_number (*sp1))
+        {
+          /* Find the reduction we are handling.  */
+          reductions *reds = s->reductions;
+          int redno = state_reduction_find (s, &rules[r]);
 
-	  /* Print them if there are.  */
-	  if (reds->look_ahead_tokens && redno != -1)
-	    {
-	      bitset_iterator biter;
-	      int k;
-	      char const *sep = "";
-	      obstack_sgrow (oout, "[");
-	      BITSET_FOR_EACH (biter, reds->look_ahead_tokens[redno], k, 0)
-		{
-		  obstack_fgrow2 (oout, "%s%s", sep, symbols[k]->tag);
-		  sep = ", ";
-		}
-	      obstack_sgrow (oout, "]");
-	    }
-	}
+          /* Print them if there are.  */
+          if (reds->lookahead_tokens && redno != -1)
+            {
+              bitset_iterator biter;
+              int k;
+              char const *sep = "";
+              obstack_sgrow (oout, "  [");
+              BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
+                {
+                  obstack_sgrow (oout, sep);
+                  obstack_sgrow (oout, escape (symbols[k]->tag));
+                  sep = ", ";
+                }
+              obstack_1grow (oout, ']');
+            }
+        }
+      obstack_sgrow (oout, "\\l");
     }
 }
 
@@ -120,17 +137,12 @@
 `---------------------------------------------------------------*/
 
 static void
-print_actions (state *s, const char *node_name)
+print_actions (state const *s, FILE *fgraph)
 {
+  transitions const *trans = s->transitions;
   int i;
 
-  transitions *trans = s->transitions;
-  reductions *reds = s->reductions;
-
-  static char buff[10];
-  edge e;
-
-  if (!trans->num && !reds)
+  if (!trans->num && !s->reductions)
     return;
 
   for (i = 0; i < trans->num; i++)
@@ -139,24 +151,21 @@
 	state *s1 = trans->states[i];
 	symbol_number sym = s1->accessing_symbol;
 
-	new_edge (&e);
+	/* Shifts are solid, gotos are dashed, and error is dotted.  */
+	char const *style =
+	  (TRANSITION_IS_ERROR (trans, i) ? "dotted"
+	   : TRANSITION_IS_SHIFT (trans, i) ? "solid"
+	   : "dashed");
 
-	if (s->number > s1->number)
-	  e.type = back_edge;
-	open_edge (&e, fgraph);
-	/* The edge source is the current node.  */
-	e.sourcename = node_name;
-	sprintf (buff, "%d", s1->number);
-	e.targetname = buff;
-	/* Shifts are blue, gotos are green, and error is red. */
-	if (TRANSITION_IS_ERROR (trans, i))
-	  e.color = red;
-	else
-	  e.color = TRANSITION_IS_SHIFT (trans, i) ? blue : green;
-	e.label = symbols[sym]->tag;
-	output_edge (&e, fgraph);
-	close_edge (fgraph);
+	if (TRANSITION_IS_ERROR (trans, i)
+	    && strcmp (symbols[sym]->tag, "error") != 0)
+	  abort ();
+	output_edge (s->number, s1->number,
+		     TRANSITION_IS_ERROR (trans, i) ? NULL : symbols[sym]->tag,
+		     style, fgraph);
       }
+  /* Display reductions. */
+  output_red (s, s->reductions, fgraph);
 }
 
 
@@ -166,29 +175,19 @@
 `-------------------------------------------------------------*/
 
 static void
-print_state (state *s)
+print_state (state *s, FILE *fgraph)
 {
-  static char name[10];
   struct obstack node_obstack;
-  node n;
 
-  /* The labels of the nodes are their the items.  */
+  /* A node's label contains its items.  */
   obstack_init (&node_obstack);
-  new_node (&n);
-  sprintf (name, "%d", s->number);
-  n.title = name;
   print_core (&node_obstack, s);
   obstack_1grow (&node_obstack, '\0');
-  n.label = obstack_finish (&node_obstack);
-
-  open_node (fgraph);
-  output_node (&n, fgraph);
-  close_node (fgraph);
+  output_node (s->number, obstack_finish (&node_obstack), fgraph);
+  obstack_free (&node_obstack, 0);
 
   /* Output the edges.  */
-  print_actions (s, name);
-
-  obstack_free (&node_obstack, 0);
+  print_actions (s, fgraph);
 }
 
 
@@ -196,32 +195,15 @@
 print_graph (void)
 {
   state_number i;
-
-  /* Output file.  */
-  fgraph = xfopen (spec_graph_file, "w");
-
-  new_graph (&static_graph);
-
-  static_graph.display_edge_labels = yes;
-
-  static_graph.port_sharing = no;
-  static_graph.finetuning = yes;
-  static_graph.priority_phase = yes;
-  static_graph.splines = yes;
-
-  static_graph.crossing_weight = median;
-
-  /* Output graph options. */
-  open_graph (fgraph);
-  output_graph (&static_graph, fgraph);
+  FILE *fgraph = xfopen (spec_graph_file, "w");
+  start_graph (fgraph);
 
   /* Output nodes and edges. */
   new_closure (nritems);
   for (i = 0; i < nstates; i++)
-    print_state (states[i]);
+    print_state (states[i], fgraph);
   free_closure ();
 
-  /* Close graph. */
-  close_graph (&static_graph, fgraph);
+  finish_graph (fgraph);
   xfclose (fgraph);
 }
diff --git a/src/print_graph.h b/src/print_graph.h
index befc531..02aa8b3 100644
--- a/src/print_graph.h
+++ b/src/print_graph.h
@@ -1,22 +1,21 @@
-/* Output a VCG description on generated parser, for bison,
-   Copyright 2000 Free Software Foundation, Inc.
+/* Output a graph of the generated parser, for Bison.
+
+   Copyright (C) 2000, 2006, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef PRINT_GRAPH_H_
 # define PRINT_GRAPH_H_
diff --git a/src/reader.c b/src/reader.c
index d07ce5c..735e700 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -1,40 +1,41 @@
 /* Input parser for Bison
 
-   Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003,
-   2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000-2003, 2005-2007,
+   2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
-#include <quotearg.h>
+#include <quote.h>
 
 #include "complain.h"
 #include "conflicts.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "muscle_tab.h"
+#include "muscle-tab.h"
 #include "reader.h"
 #include "symlist.h"
 #include "symtab.h"
+#include "scan-gram.h"
+#include "scan-code.h"
 
+static void prepare_percent_define_front_end_variables (void);
 static void check_and_convert_grammar (void);
 
 static symbol_list *grammar = NULL;
@@ -42,7 +43,10 @@
 merger_list *merge_functions;
 
 /* Was %union seen?  */
-bool typed = false;
+bool union_seen = false;
+
+/* Was a tag seen?  */
+bool tag_seen = false;
 
 /* Should rules have a default precedence?  */
 bool default_prec = true;
@@ -64,35 +68,15 @@
     }
 }
 
-
-/*----------------------------------------------------------------.
-| There are two prologues: one before %union, one after.  Augment |
-| the current one.                                                |
-`----------------------------------------------------------------*/
-
-void
-prologue_augment (const char *prologue, location loc)
-{
-  struct obstack *oout =
-    !typed ? &pre_prologue_obstack : &post_prologue_obstack;
-
-  obstack_fgrow1 (oout, "]b4_syncline(%d, [[", loc.start.line);
-  MUSCLE_OBSTACK_SGROW (oout,
-			quotearg_style (c_quoting_style, loc.start.file));
-  obstack_sgrow (oout, "]])[\n");
-  obstack_sgrow (oout, prologue);
-}
-
 
 
-/*-------------------------------------------------------------------.
-| Return the merger index for a merging function named NAME, whose   |
-| arguments have type TYPE.  Records the function, if new, in        |
-| MERGER_LIST.							     |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------------.
+| Return the merger index for a merging function named NAME.  Records the |
+| function, if new, in MERGER_LIST.                                       |
+`------------------------------------------------------------------------*/
 
 static int
-get_merge_function (uniqstr name, uniqstr type, location loc)
+get_merge_function (uniqstr name)
 {
   merger_list *syms;
   merger_list head;
@@ -101,9 +85,6 @@
   if (! glr_parser)
     return 0;
 
-  if (type == NULL)
-    type = uniqstr_new ("");
-
   head.next = merge_functions;
   for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
     if (UNIQSTR_EQ (name, syms->next->name))
@@ -112,16 +93,55 @@
     {
       syms->next = xmalloc (sizeof syms->next[0]);
       syms->next->name = uniqstr_new (name);
-      syms->next->type = uniqstr_new (type);
+      /* After all symbol type declarations have been parsed, packgram invokes
+	 record_merge_function_type to set the type.  */
+      syms->next->type = NULL;
       syms->next->next = NULL;
       merge_functions = head.next;
     }
-  else if (!UNIQSTR_EQ (type, syms->next->type))
-    warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),
-	     name, type, syms->next->type);
   return n;
 }
 
+/*-------------------------------------------------------------------------.
+| For the existing merging function with index MERGER, record the result   |
+| type as TYPE as required by the lhs of the rule whose %merge declaration |
+| is at DECLARATION_LOC.                                                   |
+`-------------------------------------------------------------------------*/
+
+static void
+record_merge_function_type (int merger, uniqstr type, location declaration_loc)
+{
+  int merger_find;
+  merger_list *merge_function;
+
+  if (merger <= 0)
+    return;
+
+  if (type == NULL)
+    type = uniqstr_new ("");
+
+  merger_find = 1;
+  for (merge_function = merge_functions;
+       merge_function != NULL && merger_find != merger;
+       merge_function = merge_function->next)
+    merger_find += 1;
+  aver (merge_function != NULL && merger_find == merger);
+  if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type))
+    {
+      unsigned indent = 0;
+      complain_at_indent (declaration_loc, &indent,
+                          _("result type clash on merge function %s: "
+                            "<%s> != <%s>"),
+                          quote (merge_function->name), type,
+                          merge_function->type);
+      indent += SUB_INDENT;
+      complain_at_indent (merge_function->type_declaration_location, &indent,
+                          _("previous declaration"));
+   }
+  merge_function->type = uniqstr_new (type);
+  merge_function->type_declaration_location = declaration_loc;
+}
+
 /*--------------------------------------.
 | Free all merge-function definitions.	|
 `--------------------------------------*/
@@ -154,10 +174,10 @@
 static symbol_list *grammar_end = NULL;
 
 /* Append SYM to the grammar.  */
-static void
+static symbol_list *
 grammar_symbol_append (symbol *sym, location loc)
 {
-  symbol_list *p = symbol_list_new (sym, loc);
+  symbol_list *p = symbol_list_sym_new (sym, loc);
 
   if (grammar_end)
     grammar_end->next = p;
@@ -170,12 +190,31 @@
      part of it.  */
   if (sym)
     ++nritems;
+
+  return p;
 }
 
+static void
+assign_named_ref (symbol_list *p, named_ref *name)
+{
+  symbol *sym = p->content.sym;
+
+  if (name->id == sym->tag)
+    {
+      warn_at (name->loc,
+	       _("duplicated symbol name for %s ignored"),
+	       quote (sym->tag));
+      named_ref_free (name);
+    }
+  else
+    p->named_ref = name;
+}
+
+
 /* The rule currently being defined, and the previous rule.
    CURRENT_RULE points to the first LHS of the current rule, while
    PREVIOUS_RULE_END points to the *end* of the previous rule (NULL).  */
-symbol_list *current_rule = NULL;
+static symbol_list *current_rule = NULL;
 static symbol_list *previous_rule_end = NULL;
 
 
@@ -184,19 +223,19 @@
 `----------------------------------------------*/
 
 void
-grammar_current_rule_begin (symbol *lhs, location loc)
+grammar_current_rule_begin (symbol *lhs, location loc,
+			    named_ref *lhs_name)
 {
-  if (!start_flag)
-    {
-      startsymbol = lhs;
-      startsymbol_location = loc;
-      start_flag = true;
-    }
+  symbol_list* p;
 
   /* Start a new rule and record its lhs.  */
   ++nrules;
   previous_rule_end = grammar_end;
-  grammar_symbol_append (lhs, loc);
+
+  p = grammar_symbol_append (lhs, loc);
+  if (lhs_name)
+    assign_named_ref (p, named_ref_copy (lhs_name));
+
   current_rule = grammar_end;
 
   /* Mark the rule's lhs as a nonterminal if not already so.  */
@@ -212,16 +251,28 @@
 
 
 /*----------------------------------------------------------------------.
-| A symbol should be used if it has a destructor, or if it is a         |
-| mid-rule symbol (i.e., the generated LHS replacing a mid-rule         |
-| action) that was assigned to, as in "exp: { $$ = 1; } { $$ = $1; }".  |
+| A symbol should be used if either:                                    |
+|   1. It has a destructor.                                             |
+|   2. The symbol is a mid-rule symbol (i.e., the generated LHS         |
+|      replacing a mid-rule action) that was assigned to or used, as in |
+|      "exp: { $$ = 1; } { $$ = $1; }".                                 |
 `----------------------------------------------------------------------*/
 
 static bool
-symbol_should_be_used (symbol_list const *s)
+symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
 {
-  return (s->sym->destructor
-	  || (s->midrule && s->midrule->used));
+  if (symbol_destructor_get (s->content.sym)->code)
+    return true;
+  if ((s->midrule && s->midrule->action_props.is_value_used)
+      || (s->midrule_parent_rule
+          && symbol_list_n_get (s->midrule_parent_rule,
+                                s->midrule_parent_rhs_index)
+               ->action_props.is_value_used))
+    {
+      *midrule_warning = true;
+      return true;
+    }
+  return false;
 }
 
 /*----------------------------------------------------------------.
@@ -239,13 +290,13 @@
 
      Don't worry about the default action if $$ is untyped, since $$'s
      value can't be used.  */
-  if (!r->action && r->sym->type_name)
+  if (!r->action_props.code && r->content.sym->type_name)
     {
-      symbol *first_rhs = r->next->sym;
+      symbol *first_rhs = r->next->content.sym;
       /* If $$ is being set in default way, report if any type mismatch.  */
       if (first_rhs)
 	{
-	  char const *lhs_type = r->sym->type_name;
+	  char const *lhs_type = r->content.sym->type_name;
 	  const char *rhs_type =
 	    first_rhs->type_name ? first_rhs->type_name : "";
 	  if (!UNIQSTR_EQ (lhs_type, rhs_type))
@@ -263,18 +314,32 @@
   {
     symbol_list const *l = r;
     int n = 0;
-    for (; l && l->sym; l = l->next, ++n)
-      if (! (l->used
-	     || !symbol_should_be_used (l)
-	     /* The default action, $$ = $1, `uses' both.  */
-	     || (!r->action && (n == 0 || n == 1))))
-	{
-	  if (n)
-	    warn_at (r->location, _("unused value: $%d"), n);
-	  else
-	    warn_at (r->location, _("unset value: $$"));
-	}
+    for (; l && l->content.sym; l = l->next, ++n)
+      {
+        bool midrule_warning = false;
+        if (!l->action_props.is_value_used
+            && symbol_should_be_used (l, &midrule_warning)
+            /* The default action, $$ = $1, `uses' both.  */
+            && (r->action_props.code || (n != 0 && n != 1)))
+          {
+            void (*warn_at_ptr)(location, char const*, ...) =
+              midrule_warning ? midrule_value_at : warn_at;
+            if (n)
+              warn_at_ptr (l->location, _("unused value: $%d"), n);
+            else
+              warn_at_ptr (l->location, _("unset value: $$"));
+          }
+      }
   }
+
+  /* See comments in grammar_current_rule_prec_set for how POSIX
+     mandates this complaint.  It's only for identifiers, so skip
+     it for char literals and strings, which are always tokens.  */
+  if (r->ruleprec
+      && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
+      && !r->ruleprec->declared && !r->ruleprec->prec)
+    warn_at (r->location, _("token for %%prec is not defined: %s"),
+             r->ruleprec->tag);
 }
 
 
@@ -288,7 +353,6 @@
   /* Put an empty link in the list to mark the end of this rule  */
   grammar_symbol_append (NULL, grammar_end->location);
   current_rule->location = loc;
-  grammar_rule_check (current_rule);
 }
 
 
@@ -308,9 +372,12 @@
 
   /* Make a DUMMY nonterminal, whose location is that of the midrule
      action.  Create the MIDRULE.  */
-  location dummy_location = current_rule->action_location;
+  location dummy_location = current_rule->action_props.location;
   symbol *dummy = dummy_symbol_get (dummy_location);
-  symbol_list *midrule = symbol_list_new (dummy, dummy_location);
+  symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
+
+  /* Remember named_ref of previous action. */
+  named_ref *action_name = current_rule->action_props.named_ref;
 
   /* Make a new rule, whose body is empty, before the current one, so
      that the action just read can belong to it.  */
@@ -318,13 +385,11 @@
   ++nritems;
   /* Attach its location and actions to that of the DUMMY.  */
   midrule->location = dummy_location;
-  midrule->action = current_rule->action;
-  midrule->action_location = dummy_location;
-  current_rule->action = NULL;
-  /* If $$ was used in the action, the LHS of the enclosing rule was
-     incorrectly flagged as used.  */
-  midrule->used = current_rule->used;
-  current_rule->used = false;
+  code_props_rule_action_init (&midrule->action_props,
+                               current_rule->action_props.code,
+                               current_rule->action_props.location,
+                               midrule, 0);
+  code_props_none_init (&current_rule->action_props);
 
   if (previous_rule_end)
     previous_rule_end->next = midrule;
@@ -332,16 +397,18 @@
     grammar = midrule;
 
   /* End the dummy's rule.  */
-  midrule->next = symbol_list_new (NULL, dummy_location);
-  grammar_rule_check (midrule);
+  midrule->next = symbol_list_sym_new (NULL, dummy_location);
   midrule->next->next = current_rule;
 
   previous_rule_end = midrule->next;
 
   /* Insert the dummy nonterminal replacing the midrule action into
      the current rule.  Bind it to its dedicated rule.  */
-  grammar_current_rule_symbol_append (dummy, dummy_location);
+  grammar_current_rule_symbol_append (dummy, dummy_location,
+                                      action_name);
   grammar_end->midrule = midrule;
+  midrule->midrule_parent_rule = current_rule;
+  midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
 }
 
 /* Set the precedence symbol of the current rule to PRECSYM. */
@@ -349,6 +416,17 @@
 void
 grammar_current_rule_prec_set (symbol *precsym, location loc)
 {
+  /* POSIX says that any identifier is a nonterminal if it does not
+     appear on the LHS of a grammar rule and is not defined by %token
+     or by one of the directives that assigns precedence to a token.  We
+     ignore this here because the only kind of identifier that POSIX
+     allows to follow a %prec is a token and because assuming it's a
+     token now can produce more logical error messages.  Nevertheless,
+     grammar_rule_check does obey what we believe is the real intent of
+     POSIX here: that an error be reported for any identifier that
+     appears after %prec but that is not defined separately as a
+     token.  */
+  symbol_class_set (precsym, token_sym, loc, false);
   if (current_rule->ruleprec)
     complain_at (loc, _("only one %s allowed per rule"), "%prec");
   current_rule->ruleprec = precsym;
@@ -378,30 +456,37 @@
     warn_at (loc, _("%s affects only GLR parsers"), "%merge");
   if (current_rule->merger != 0)
     complain_at (loc, _("only one %s allowed per rule"), "%merge");
-  current_rule->merger =
-    get_merge_function (name, current_rule->sym->type_name, loc);
+  current_rule->merger = get_merge_function (name);
+  current_rule->merger_declaration_location = loc;
 }
 
 /* Attach SYM to the current rule.  If needed, move the previous
    action as a mid-rule action.  */
 
 void
-grammar_current_rule_symbol_append (symbol *sym, location loc)
+grammar_current_rule_symbol_append (symbol *sym, location loc,
+				    named_ref *name)
 {
-  if (current_rule->action)
+  symbol_list *p;
+  if (current_rule->action_props.code)
     grammar_midrule_action ();
-  grammar_symbol_append (sym, loc);
+  p = grammar_symbol_append (sym, loc);
+  if (name)
+    assign_named_ref(p, name);
 }
 
 /* Attach an ACTION to the current rule.  */
 
 void
-grammar_current_rule_action_append (const char *action, location loc)
+grammar_current_rule_action_append (const char *action, location loc,
+				    named_ref *name)
 {
-  /* There's no need to invoke grammar_midrule_action here, since the
-     scanner already did it if necessary.  */
-  current_rule->action = action;
-  current_rule->action_location = loc;
+  if (current_rule->action_props.code)
+    grammar_midrule_action ();
+  /* After all symbol declarations have been parsed, packgram invokes
+     code_props_translate_code.  */
+  code_props_rule_action_init (&current_rule->action_props, action, loc,
+                               current_rule, name);
 }
 
 
@@ -426,10 +511,13 @@
 
   while (p)
     {
+      int rule_length = 0;
       symbol *ruleprec = p->ruleprec;
+      record_merge_function_type (p->merger, p->content.sym->type_name,
+				  p->merger_declaration_location);
       rules[ruleno].user_number = ruleno;
       rules[ruleno].number = ruleno;
-      rules[ruleno].lhs = p->sym;
+      rules[ruleno].lhs = p->content.sym;
       rules[ruleno].rhs = ritem + itemno;
       rules[ruleno].prec = NULL;
       rules[ruleno].dprec = p->dprec;
@@ -437,21 +525,42 @@
       rules[ruleno].precsym = NULL;
       rules[ruleno].location = p->location;
       rules[ruleno].useful = true;
-      rules[ruleno].action = p->action;
-      rules[ruleno].action_location = p->action_location;
+      rules[ruleno].action = p->action_props.code;
+      rules[ruleno].action_location = p->action_props.location;
 
-      p = p->next;
-      while (p && p->sym)
+      /* If the midrule's $$ is set or its $n is used, remove the `$' from the
+	 symbol name so that it's a user-defined symbol so that the default
+	 %destructor and %printer apply.  */
+      if (p->midrule_parent_rule
+          && (p->action_props.is_value_used
+	      || symbol_list_n_get (p->midrule_parent_rule,
+				    p->midrule_parent_rhs_index)
+                   ->action_props.is_value_used))
+	p->content.sym->tag += 1;
+
+      /* Don't check the generated rule 0.  It has no action, so some rhs
+	 symbols may appear unused, but the parsing algorithm ensures that
+	 %destructor's are invoked appropriately.  */
+      if (p != grammar)
+	grammar_rule_check (p);
+
+      for (p = p->next; p && p->content.sym; p = p->next)
 	{
+	  ++rule_length;
+
+	  /* Don't allow rule_length == INT_MAX, since that might
+	     cause confusion with strtol if INT_MAX == LONG_MAX.  */
+	  if (rule_length == INT_MAX)
+	      fatal_at (rules[ruleno].location, _("rule is too long"));
+
 	  /* item_number = symbol_number.
 	     But the former needs to contain more: negative rule numbers. */
-	  ritem[itemno++] = symbol_number_as_item_number (p->sym->number);
+	  ritem[itemno++] =
+            symbol_number_as_item_number (p->content.sym->number);
 	  /* A rule gets by default the precedence and associativity
-	     of the last token in it.  */
-	  if (p->sym->class == token_sym && default_prec)
-	    rules[ruleno].prec = p->sym;
-	  if (p)
-	    p = p->next;
+	     of its last token.  */
+	  if (p->content.sym->class == token_sym && default_prec)
+	    rules[ruleno].prec = p->content.sym;
 	}
 
       /* If this rule has a %prec,
@@ -461,14 +570,17 @@
 	  rules[ruleno].precsym = ruleprec;
 	  rules[ruleno].prec = ruleprec;
 	}
+      /* An item ends by the rule number (negated).  */
       ritem[itemno++] = rule_number_as_item_number (ruleno);
+      aver (itemno < ITEM_NUMBER_MAX);
       ++ruleno;
+      aver (ruleno < RULE_NUMBER_MAX);
 
       if (p)
 	p = p->next;
     }
 
-  assert (itemno == nritems);
+  aver (itemno == nritems);
 
   if (trace_flag & trace_sets)
     ritem_print (stderr);
@@ -503,16 +615,13 @@
   undeftoken->class = token_sym;
   undeftoken->number = ntokens++;
 
-  /* Initialize the obstacks. */
-  obstack_init (&pre_prologue_obstack);
-  obstack_init (&post_prologue_obstack);
-
   gram_in = xfopen (grammar_file, "r");
 
   gram__flex_debug = trace_flag & trace_scan;
   gram_debug = trace_flag & trace_parse;
-  scanner_initialize ();
+  gram_scanner_initialize ();
   gram_parse ();
+  prepare_percent_define_front_end_variables ();
 
   if (! complaint_issued)
     check_and_convert_grammar ();
@@ -520,6 +629,35 @@
   xfclose (gram_in);
 }
 
+static void
+prepare_percent_define_front_end_variables (void)
+{
+  /* Set %define front-end variable defaults.  */
+  muscle_percent_define_default ("lr.keep-unreachable-states", "false");
+  {
+    char *lr_type;
+    /* IELR would be a better default, but LALR is historically the
+       default.  */
+    muscle_percent_define_default ("lr.type", "lalr");
+    lr_type = muscle_percent_define_get ("lr.type");
+    if (0 != strcmp (lr_type, "canonical-lr"))
+      muscle_percent_define_default ("lr.default-reductions", "most");
+    else
+      muscle_percent_define_default ("lr.default-reductions", "accepting");
+    free (lr_type);
+  }
+
+  /* Check %define front-end variables.  */
+  {
+    static char const * const values[] = {
+      "lr.type", "lalr", "ielr", "canonical-lr", NULL,
+      "lr.default-reductions", "most", "consistent", "accepting", NULL,
+      NULL
+    };
+    muscle_percent_define_check_values (values);
+  }
+}
+
 
 /*-------------------------------------------------------------.
 | Check the grammar that has just been read, and convert it to |
@@ -533,9 +671,6 @@
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
 
-  /* Report any undefined symbols and consider them nonterminals.  */
-  symbols_check_defined ();
-
   /* If the user did not define her ENDTOKEN, do it now. */
   if (!endtoken)
     {
@@ -546,31 +681,69 @@
       endtoken->user_token_number = 0;
     }
 
+  /* Report any undefined symbols and consider them nonterminals.  */
+  symbols_check_defined ();
+
+  /* Find the start symbol if no %start.  */
+  if (!start_flag)
+    {
+      symbol_list *node;
+      for (node = grammar;
+           node != NULL && symbol_is_dummy (node->content.sym);
+           node = node->next)
+        {
+          for (node = node->next;
+               node != NULL && node->content.sym != NULL;
+               node = node->next)
+            ;
+        }
+      aver (node != NULL);
+      grammar_start_symbol_set (node->content.sym,
+                                node->content.sym->location);
+    }
+
   /* Insert the initial rule, whose line is that of the first rule
      (not that of the start symbol):
 
      accept: %start EOF.  */
   {
-    symbol_list *p = symbol_list_new (accept, empty_location);
+    symbol_list *p = symbol_list_sym_new (accept, empty_location);
     p->location = grammar->location;
-    p->next = symbol_list_new (startsymbol, empty_location);
-    p->next->next = symbol_list_new (endtoken, empty_location);
-    p->next->next->next = symbol_list_new (NULL, empty_location);
+    p->next = symbol_list_sym_new (startsymbol, empty_location);
+    p->next->next = symbol_list_sym_new (endtoken, empty_location);
+    p->next->next->next = symbol_list_sym_new (NULL, empty_location);
     p->next->next->next->next = grammar;
     nrules += 1;
     nritems += 3;
     grammar = p;
   }
 
-  assert (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
+  aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
 
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */
   symbols_pack ();
 
+  /* Scan rule actions after invoking symbol_check_alias_consistency (in
+     symbols_pack above) so that token types are set correctly before the rule
+     action type checking.
+
+     Before invoking grammar_rule_check (in packgram below) on any rule, make
+     sure all actions have already been scanned in order to set `used' flags.
+     Otherwise, checking that a midrule's $$ should be set will not always work
+     properly because the check must forward-reference the midrule's parent
+     rule.  For the same reason, all the `used' flags must be set before
+     checking whether to remove `$' from any midrule symbol name (also in
+     packgram).  */
+  {
+    symbol_list *sym;
+    for (sym = grammar; sym; sym = sym->next)
+      code_props_translate_code (&sym->action_props);
+  }
+
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();
 
   /* The grammar as a symbol_list is no longer needed. */
-  LIST_FREE (symbol_list, grammar);
+  symbol_list_free (grammar);
 }
diff --git a/src/reader.h b/src/reader.h
index f110f70..e154deb 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -1,30 +1,29 @@
 /* Input parser for Bison
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 Free Software
+   Copyright (C) 2000-2003, 2005-2007, 2009-2012 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef READER_H_
 # define READER_H_
 
 # include "location.h"
 # include "symlist.h"
+# include "named-ref.h"
 
 # include "parse-gram.h"
 
@@ -33,28 +32,9 @@
   struct merger_list* next;
   uniqstr name;
   uniqstr type;
+  location type_declaration_location;
 } merger_list;
 
-/* From the scanner.  */
-extern FILE *gram_in;
-extern int gram__flex_debug;
-extern boundary scanner_cursor;
-extern char *last_string;
-extern location last_braced_code_loc;
-extern int max_left_semantic_context;
-void scanner_initialize (void);
-void scanner_free (void);
-void scanner_last_string_free (void);
-
-/* These are declared by the scanner, but not used.  We put them here
-   to pacify "make syntax-check".  */
-extern FILE *gram_out;
-extern int gram_lineno;
-
-# define YY_DECL int gram_lex (YYSTYPE *val, location *loc)
-YY_DECL;
-
-
 /* From the parser.  */
 extern int gram_debug;
 int gram_parse (void);
@@ -63,23 +43,27 @@
 
 /* From reader.c. */
 void grammar_start_symbol_set (symbol *sym, location loc);
-void prologue_augment (const char *prologue, location loc);
-void grammar_current_rule_begin (symbol *lhs, location loc);
+void grammar_current_rule_begin (symbol *lhs, location loc,
+				 named_ref *lhs_named_ref);
 void grammar_current_rule_end (location loc);
 void grammar_midrule_action (void);
 void grammar_current_rule_prec_set (symbol *precsym, location loc);
 void grammar_current_rule_dprec_set (int dprec, location loc);
 void grammar_current_rule_merge_set (uniqstr name, location loc);
-void grammar_current_rule_symbol_append (symbol *sym, location loc);
-void grammar_current_rule_action_append (const char *action, location loc);
-extern symbol_list *current_rule;
+void grammar_current_rule_symbol_append (symbol *sym, location loc,
+					 named_ref *nref);
+void grammar_current_rule_action_append (const char *action, location loc,
+					 named_ref *nref);
 void reader (void);
 void free_merger_functions (void);
 
 extern merger_list *merge_functions;
 
 /* Was %union seen?  */
-extern bool typed;
+extern bool union_seen;
+
+/* Was a tag seen?  */
+extern bool tag_seen;
 
 /* Should rules have a default precedence?  */
 extern bool default_prec;
diff --git a/src/reduce.c b/src/reduce.c
index 1bb40f0..5338393 100644
--- a/src/reduce.c
+++ b/src/reduce.c
@@ -1,24 +1,22 @@
 /* Grammar reduction for Bison.
 
-   Copyright (C) 1988, 1989, 2000, 2001, 2002, 2003, 2005, 2006 Free
-   Software Foundation, Inc.
+   Copyright (C) 1988-1989, 2000-2003, 2005-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 /* Reduce the grammar: Find and eliminate unreachable terminals,
@@ -31,12 +29,12 @@
 #include "system.h"
 
 #include <bitset.h>
-#include <quotearg.h>
 
 #include "complain.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
+#include "print-xml.h"
 #include "reader.h"
 #include "reduce.h"
 #include "symtab.h"
@@ -240,7 +238,7 @@
     rule_number r;
     for (r = 0; r < nrules; r++)
       rules[r].useful = bitset_test (P, r);
-    grammar_rules_never_reduced_report (_("useless rule"));
+    grammar_rules_useless_report (_("rule useless in grammar"));
   }
 
   /* Map the nonterminals to their new index: useful first, useless
@@ -301,7 +299,7 @@
     if (!bitset_test (V, i))
       {
 	nontermmap[i - ntokens] = n++;
-	warn_at (symbols[i]->location, _("useless nonterminal: %s"),
+	warn_at (symbols[i]->location, _("nonterminal useless in grammar: %s"),
 		 symbols[i]->tag);
       }
 
@@ -349,7 +347,7 @@
   if (nuseless_nonterminals > 0)
     {
       int i;
-      fprintf (out, "%s\n\n", _("Useless nonterminals"));
+      fprintf (out, "%s\n\n", _("Nonterminals useless in grammar"));
       for (i = 0; i < nuseless_nonterminals; ++i)
 	fprintf (out, "   %s\n", symbols[nsyms + i]->tag);
       fputs ("\n\n", out);
@@ -359,10 +357,10 @@
     bool b = false;
     int i;
     for (i = 0; i < ntokens; i++)
-      if (!bitset_test (V, i) && !bitset_test (V1, i))
+      if (reduce_token_unused_in_grammar (i))
 	{
 	  if (!b)
-	    fprintf (out, "%s\n\n", _("Terminals which are not used"));
+	    fprintf (out, "%s\n\n", _("Terminals unused in grammar"));
 	  b = true;
 	  fprintf (out, "   %s\n", symbols[i]->tag);
 	}
@@ -371,14 +369,11 @@
   }
 
   if (nuseless_productions > 0)
-    grammar_rules_partial_print (out, _("Useless rules"),
-				 rule_useless_p);
+    grammar_rules_partial_print (out, _("Rules useless in grammar"),
+				 rule_useless_in_grammar_p);
 }
 
 
-
-
-
 /*-------------------------------.
 | Report the results to STDERR.  |
 `-------------------------------*/
@@ -386,29 +381,16 @@
 static void
 reduce_print (void)
 {
-  if (yacc_flag && nuseless_productions)
-    fprintf (stderr, ngettext ("%d rule never reduced\n",
-			       "%d rules never reduced\n",
-			       nuseless_productions),
-	     nuseless_productions);
-
-  fprintf (stderr, "%s: %s: ", grammar_file, _("warning"));
-
   if (nuseless_nonterminals > 0)
-    fprintf (stderr, ngettext ("%d useless nonterminal",
-			       "%d useless nonterminals",
-			       nuseless_nonterminals),
-	     nuseless_nonterminals);
-
-  if (nuseless_nonterminals > 0 && nuseless_productions > 0)
-    fprintf (stderr, _(" and "));
-
+    warn (ngettext ("%d nonterminal useless in grammar",
+                    "%d nonterminals useless in grammar",
+                    nuseless_nonterminals),
+          nuseless_nonterminals);
   if (nuseless_productions > 0)
-    fprintf (stderr, ngettext ("%d useless rule",
-			       "%d useless rules",
-			       nuseless_productions),
-	     nuseless_productions);
-  fprintf (stderr, "\n");
+    warn (ngettext ("%d rule useless in grammar",
+                    "%d rules useless in grammar",
+                    nuseless_productions),
+          nuseless_productions);
 }
 
 void
@@ -455,6 +437,19 @@
     }
 }
 
+bool
+reduce_token_unused_in_grammar (symbol_number i)
+{
+  aver (i < ntokens);
+  return !bitset_test (V, i) && !bitset_test (V1, i);
+}
+
+bool
+reduce_nonterminal_useless_in_grammar (symbol_number i)
+{
+  aver (ntokens <= i && i < nsyms + nuseless_nonterminals);
+  return nsyms <= i;
+}
 
 /*-----------------------------------------------------------.
 | Free the global sets used to compute the reduced grammar.  |
diff --git a/src/reduce.h b/src/reduce.h
index dfdab65..c28824f 100644
--- a/src/reduce.h
+++ b/src/reduce.h
@@ -1,29 +1,30 @@
 /* Grammar reduction for Bison.
 
-   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2007, 2009-2012 Free Software Foundation,
+   Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef REDUCE_H_
 # define REDUCE_H_
 
 void reduce_grammar (void);
 void reduce_output (FILE *out);
+bool reduce_token_unused_in_grammar (symbol_number i);
+bool reduce_nonterminal_useless_in_grammar (symbol_number i);
 void reduce_free (void);
 
 extern symbol_number nuseless_nonterminals;
diff --git a/src/relation.c b/src/relation.c
index 1d2b42d..49424c0 100644
--- a/src/relation.c
+++ b/src/relation.c
@@ -1,22 +1,22 @@
 /* Binary relations.
-   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+   Copyright (C) 2002, 2004-2005, 2009-2012 Free Software Foundation,
+   Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
diff --git a/src/relation.h b/src/relation.h
index 479e42e..88c69b7 100644
--- a/src/relation.h
+++ b/src/relation.h
@@ -1,22 +1,21 @@
 /* Binary relations.
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+   Copyright (C) 2002, 2004, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #ifndef RELATION_H_
diff --git a/src/scan-code-c.c b/src/scan-code-c.c
new file mode 100644
index 0000000..4a018f8
--- /dev/null
+++ b/src/scan-code-c.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#include "system.h"
+#include "scan-code.c"
diff --git a/src/scan-code.c b/src/scan-code.c
new file mode 100644
index 0000000..8201dc9
--- /dev/null
+++ b/src/scan-code.c
@@ -0,0 +1,3148 @@
+#line 2 "scan-code.c"
+
+#line 4 "scan-code.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+#define yy_create_buffer code__create_buffer
+#define yy_delete_buffer code__delete_buffer
+#define yy_flex_debug code__flex_debug
+#define yy_init_buffer code__init_buffer
+#define yy_flush_buffer code__flush_buffer
+#define yy_load_buffer_state code__load_buffer_state
+#define yy_switch_to_buffer code__switch_to_buffer
+#define yyin code_in
+#define yyleng code_leng
+#define yylex code_lex
+#define yylineno code_lineno
+#define yyout code_out
+#define yyrestart code_restart
+#define yytext code_text
+#define yywrap code_wrap
+#define yyalloc code_alloc
+#define yyrealloc code_realloc
+#define yyfree code_free
+
+/* %endif */
+/* %endif */
+/* %ok-for-header */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 37
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* %if-c++-only */
+/* %endif */
+
+/* %if-c-only */
+    
+/* %endif */
+
+/* %if-c-only */
+
+/* %endif */
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+/* %if-c-only */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+/* %endif */
+
+/* %if-tables-serialization */
+/* %endif */
+/* end standard C headers. */
+
+/* %if-c-or-c++ */
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif	/* defined (__STDC__) */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* %not-for-header */
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE code_restart(code_in  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+/* %if-not-reentrant */
+extern yy_size_t code_leng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+extern FILE *code_in, *code_out;
+/* %endif */
+/* %endif */
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up code_text. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up code_text again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+/* %if-c-only */
+	FILE *yy_input_file;
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	yy_size_t yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via code_restart()), so that the user can continue scanning by
+	 * just pointing code_in at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* %if-c-only Standard (non-C++) definition */
+
+/* %if-not-reentrant */
+/* %not-for-header */
+
+/* yy_hold_char holds the character lost when code_text is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t code_leng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow code_wrap()'s to do buffer switches
+ * instead of setting up a fresh code_in.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+/* %ok-for-header */
+
+/* %endif */
+
+void code_restart (FILE *input_file  );
+void code__switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE code__create_buffer (FILE *file,int size  );
+void code__delete_buffer (YY_BUFFER_STATE b  );
+void code__flush_buffer (YY_BUFFER_STATE b  );
+void code_push_buffer_state (YY_BUFFER_STATE new_buffer  );
+void code_pop_buffer_state (void );
+
+static void code_ensure_buffer_stack (void );
+static void code__load_buffer_state (void );
+static void code__init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER code__flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE code__scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE code__scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE code__scan_bytes (yyconst char *bytes,yy_size_t len  );
+
+/* %endif */
+
+void *code_alloc (yy_size_t  );
+void *code_realloc (void *,yy_size_t  );
+void code_free (void *  );
+
+#define yy_new_buffer code__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        code_ensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            code__create_buffer(code_in,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        code_ensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            code__create_buffer(code_in,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* %% [1.0] code_text/code_in/code_out/yy_state_type/code_lineno etc. def's & init go here */
+/* Begin user sect3 */
+
+#define code_wrap() 1
+#define YY_SKIP_YYWRAP
+
+#define FLEX_DEBUG
+
+typedef unsigned char YY_CHAR;
+
+FILE *code_in = (FILE *) 0, *code_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int code_lineno;
+
+int code_lineno = 1;
+
+extern char *code_text;
+#define yytext_ptr code_text
+
+/* %if-c-only Standard (non-C++) definition */
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* %endif */
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up code_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle code_text and code_leng for yymore() goes here \ */\
+	code_leng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to code_text[] goes here, if %array \ */\
+	(yy_c_buf_p) = yy_cp;
+
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[101] =
+    {   0,
+        0,    0,    0,    0,    3,    3,    4,    4,    4,    4,
+       19,   19,    0,    0,   30,   28,   27,   28,    2,   28,
+        6,   28,    5,   24,   21,   20,   20,    8,   18,   11,
+        7,   24,   15,   11,   23,   23,   12,   24,   16,   17,
+        8,   11,    7,   28,   11,   12,    1,    0,    0,    3,
+        4,    4,    4,    4,   13,    0,   13,   13,    0,    0,
+        9,   10,    0,   14,    0,   14,   14,    0,   23,   23,
+        0,   19,   25,    0,   26,    0,    0,    0,    0,    0,
+        0,    0,   13,    0,    0,    0,    0,   14,    0,   23,
+        0,    0,    0,    0,    0,   23,    0,   23,   22,    0
+
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        4,    2,    5,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    6,    7,    8,    1,    1,    9,    1,
+        1,   10,    1,    1,   11,   12,   13,   14,   14,   14,
+       14,   14,   14,   14,   14,   14,   14,    1,   15,   16,
+        1,   17,    1,   18,   19,   20,   20,   20,   20,   21,
+       20,   20,   22,   20,   20,   23,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   24,   20,
+       25,   26,   27,    1,   20,    1,   20,   20,   20,   20,
+
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   28,    1,   29,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[31] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    3,    1,    1,
+        4,    5,    1,    6,    1,    1,    2,    1,    7,    7,
+        7,    7,    7,    7,    3,    1,    8,    1,    1,    2
+    } ;
+
+static yyconst flex_int16_t yy_base[113] =
+    {   0,
+        0,    1,   21,   41,   66,    0,    4,    8,   12,   14,
+       93,    0,  118,    0,  242,  243,  243,    7,  243,    0,
+      243,   39,  243,  243,  243,  243,  243,  243,  243,  138,
+      243,   34,  243,   42,    0,  217,  243,   33,  243,  243,
+      243,    8,  243,   44,  232,  243,  243,   59,   69,  213,
+      243,   73,  212,   76,  243,  223,    0,  222,    0,    0,
+      243,  243,   79,  243,  205,    0,  202,    0,    0,  188,
+       83,  175,  243,    0,  243,   86,   19,  126,  130,  135,
+      138,  122,    0,  151,  140,  162,  143,    0,  128,  132,
+      168,  130,  128,  108,   37,   36,   47,   29,    0,  243,
+
+      172,  180,  186,  188,  192,  199,  203,  207,  210,  217,
+      222,  227
+    } ;
+
+static yyconst flex_int16_t yy_def[113] =
+    {   0,
+      101,  101,  101,  101,  101,    5,    5,    5,    5,    5,
+      100,   11,  101,   13,  100,  100,  100,  100,  100,  100,
+      100,  102,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  103,  104,  104,  100,  100,  100,  100,
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  100,  100,  100,  105,  100,  106,  107,
+      100,  100,  100,  100,  100,  108,  100,  109,  104,  104,
+      100,  100,  100,  110,  100,  100,  100,  100,  100,  100,
+      100,  102,  105,  106,  111,  100,  100,  108,  112,  104,
+      100,  110,   30,  111,  112,  104,  100,  104,  104,    0,
+
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100
+    } ;
+
+static yyconst flex_int16_t yy_nxt[274] =
+    {   0,
+      100,   49,   50,   49,  100,  100,   16,   17,   17,   21,
+       16,  100,  100,   21,   16,   73,   16,   17,   17,   47,
+       23,  100,   23,   74,   17,   17,   17,   17,   17,   22,
+       18,   47,   48,   22,   71,   72,   71,   22,   17,   22,
+       52,   53,   52,   61,   48,   17,   62,   17,   17,   64,
+       18,   99,   65,   61,   73,   67,   62,   98,   17,   63,
+       76,   77,   76,   64,   54,   17,   68,   17,   19,   63,
+       49,   50,   49,   17,   79,   53,   79,   81,   82,   81,
+       86,   87,   86,   17,   71,   72,   71,   76,   77,   76,
+       17,   20,   17,   24,   25,   26,   24,   27,   28,   29,
+
+       30,   31,   24,   24,   24,   32,   24,   33,   24,   24,
+       34,   35,   35,   35,   35,   35,   36,   37,   38,   37,
+       39,   40,   24,   41,  100,   42,   43,   49,   50,   49,
+       44,   79,   53,   79,   55,   45,   79,   53,   79,   81,
+       82,   81,   46,  100,   46,   55,   97,   54,   56,   57,
+       96,   58,   61,   59,   64,   62,   57,   57,   57,   57,
+       57,   57,   60,   86,   87,   86,   55,   93,   63,   71,
+       72,   71,   16,   16,   16,   16,   16,   16,   16,   16,
+       51,   51,   51,   51,   51,   51,   51,   51,   66,   66,
+       66,   66,   66,   69,   69,   83,   83,   83,   83,   84,
+
+       91,   84,   84,   84,   84,   84,   84,   85,   90,   85,
+       88,   88,   88,   88,   89,   67,   89,   92,   67,   92,
+       92,   92,   92,   92,   92,   94,   94,   94,   94,   94,
+       95,   95,   95,   95,   95,   58,   58,   80,   78,   75,
+       70,  100,   15,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100
+    } ;
+
+static yyconst flex_int16_t yy_chk[274] =
+    {   0,
+        0,   20,   20,   20,    0,    0,    7,    1,    2,    7,
+        8,    0,    0,    8,    9,   42,   10,    1,    2,   18,
+        9,    0,   10,   42,    1,    2,    1,    2,    3,    7,
+        3,   77,   18,    8,   38,   38,   38,    9,    3,   10,
+       22,   22,   22,   32,   77,    3,   32,    3,    4,   34,
+        4,   98,   34,   44,   97,   34,   44,   96,    4,   32,
+       48,   48,   48,   95,   22,    4,   34,    4,    5,   44,
+       49,   49,   49,    5,   52,   52,   52,   54,   54,   54,
+       63,   63,   63,    5,   71,   71,   71,   76,   76,   76,
+        5,    5,    5,   11,   11,   11,   11,   11,   11,   11,
+
+       11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
+       11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
+       11,   11,   11,   13,   82,   13,   13,   78,   78,   78,
+       13,   79,   79,   79,   94,   13,   80,   80,   80,   81,
+       81,   81,   13,   93,   13,   30,   92,   82,   30,   30,
+       90,   30,   87,   30,   89,   87,   30,   30,   30,   30,
+       30,   30,   30,   86,   86,   86,   85,   84,   87,   91,
+       91,   91,  101,  101,  101,  101,  101,  101,  101,  101,
+      102,  102,  102,  102,  102,  102,  102,  102,  103,  103,
+      103,  103,  103,  104,  104,  105,  105,  105,  105,  106,
+
+       72,  106,  106,  106,  106,  106,  106,  107,   70,  107,
+      108,  108,  108,  108,  109,   67,  109,  110,   65,  110,
+      110,  110,  110,  110,  110,  111,  111,  111,  111,  111,
+      112,  112,  112,  112,  112,   58,   56,   53,   50,   45,
+       36,   15,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int code__flex_debug;
+int code__flex_debug = 1;
+
+static yyconst flex_int16_t yy_rule_linenum[29] =
+    {   0,
+      132,  142,  143,  153,  158,  163,  169,  174,  179,  183,
+      187,  192,  200,  207,  215,  216,  217,  244,  246,  247,
+      248,  252,  260,  262,  267,  275,  285,  288
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *code_text;
+#line 1 "scan-code.l"
+/* Bison Action Scanner                             -*- C -*-
+
+   Copyright (C) 2006-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+#define YY_NO_INPUT 1
+#line 24 "scan-code.l"
+/* Work around a bug in flex 2.5.31.  See Debian bug 333231
+   <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
+#undef code_wrap
+#define code_wrap() 1
+
+#define FLEX_PREFIX(Id) code_ ## Id
+#include "flex-scanner.h"
+
+#include "complain.h"
+#include "reader.h"
+#include "getargs.h"
+#include "scan-code.h"
+#include "symlist.h"
+
+#include <c-ctype.h>
+#include <get-errno.h>
+#include <quote.h>
+
+/* The current calling start condition: SC_RULE_ACTION or
+   SC_SYMBOL_ACTION. */
+# define YY_DECL static char *code_lex (code_props *self, int sc_context)
+YY_DECL;
+
+#define YY_USER_ACTION  location_compute (loc, &loc->end, code_text, code_leng);
+
+static char *fetch_type_name (char *cp, char const **type_name,
+                              location dollar_loc);
+
+static void handle_action_dollar (symbol_list *rule, char *cp,
+				  location dollar_loc);
+static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
+
+/* A string to be pushed to obstack after dollar/at has been handled. */
+static char *ref_tail_fields;
+
+static location the_location;
+static location *loc = &the_location;
+
+/* A string representing the most recent translation.  */
+static char *last_string;
+
+/* True if an untyped $$ or $n was seen.  */
+static bool untyped_var_seen;
+
+/* C and C++ comments in code. */
+
+/* Strings and characters in code. */
+
+/* Whether in a rule or symbol action.  Specifies the translation
+of $ and @.  */
+
+/* POSIX says that a tag must be both an id and a C union member, but
+   historically almost any character is allowed in a tag.  We disallow
+   NUL and newline, as this simplifies our implementation.  */
+/* Zero or more instances of backslash-newline.  Following GCC, allow
+   white space between the backslash and the newline.  */
+/* C style identifier. Must start with letter. Will be used for
+   named symbol references. Shall be kept synchronized with
+   scan-gram.l "letter" and "id". */
+#line 735 "scan-code.c"
+
+#define INITIAL 0
+#define SC_COMMENT 1
+#define SC_LINE_COMMENT 2
+#define SC_STRING 3
+#define SC_CHARACTER 4
+#define SC_RULE_ACTION 5
+#define SC_SYMBOL_ACTION 6
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+/* %if-c-only */
+#include <unistd.h>
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+
+static int yy_init_globals (void );
+
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int code_lex_destroy (void );
+
+int code_get_debug (void );
+
+void code_set_debug (int debug_flag  );
+
+YY_EXTRA_TYPE code_get_extra (void );
+
+void code_set_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *code_get_in (void );
+
+void code_set_in  (FILE * in_str  );
+
+FILE *code_get_out (void );
+
+void code_set_out  (FILE * out_str  );
+
+yy_size_t code_get_leng (void );
+
+char *code_get_text (void );
+
+int code_get_lineno (void );
+
+void code_set_lineno (int line_number  );
+
+/* %if-bison-bridge */
+/* %endif */
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int code_wrap (void );
+#else
+extern int code_wrap (void );
+#endif
+#endif
+
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %endif */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+/* %ok-for-header */
+
+/* %endif */
+#endif
+
+/* %if-c-only */
+
+/* %endif */
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* %if-c-only Standard (non-C++) definition */
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( code_text, code_leng, 1, code_out )) {} } while (0)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( code_in )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( code_in ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, code_in))==0 && ferror(code_in)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(code_in); \
+			} \
+		}\
+\
+/* %if-c++-only C++ definition \ */\
+/* %endif */
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+/* %if-c-only */
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
+/* end tables serialization structures and prototypes */
+
+/* %ok-for-header */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+/* %if-c-only Standard (non-C++) definition */
+
+extern int code_lex (void);
+
+#define YY_DECL int code_lex (void)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after code_text and code_leng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+/* %% [6.0] YY_RULE_SETUP definition goes here */
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/* %not-for-header */
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+/* %% [7.0] user's declarations go here */
+#line 94 "scan-code.l"
+
+
+
+  /* Nesting level of the current code in braces.  */
+  int braces_level = 0;
+
+  /* Whether a semicolon is probably needed.
+
+     The heuristic is that a semicolon is not needed after '{', '}',
+     ';', or a C preprocessor directive, and that whitespaces and
+     comments do not affect this flag.  Note that '{' does not need a
+     semicolon because of '{}'.  A semicolon may be needed before a
+     cpp directive, but don't bother.
+
+     While it is maintained in several start-conditions (factoring
+     opportunities), it is meaningful only for SC_RULE_ACTION. */
+  bool need_semicolon = false;
+
+  /* Whether in a C preprocessor directive.  Don't use a start condition
+     for this because, at the end of strings and comments, we still need
+     to know whether we're in a directive.  */
+  bool in_cpp = false;
+
+  /* This scanner is special: it is invoked only once, henceforth
+     is expected to return only once.  This initialization is
+     therefore done once per action to translate. */
+  aver (sc_context == SC_SYMBOL_ACTION
+	|| sc_context == SC_RULE_ACTION
+	|| sc_context == INITIAL);
+  BEGIN sc_context;
+
+
+  /*------------------------------------------------------------.
+  | Scanning a C comment.  The initial '/ *' is already eaten.  |
+  `------------------------------------------------------------*/
+
+#line 1018 "scan-code.c"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! code_in )
+/* %if-c-only */
+			code_in = stdin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+		if ( ! code_out )
+/* %if-c-only */
+			code_out = stdout;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			code_ensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				code__create_buffer(code_in,YY_BUF_SIZE );
+		}
+
+		code__load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+/* %% [8.0] yymore()-related code goes here */
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of code_text. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+/* %% [9.0] code to set up and find next match goes here */
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 101 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_current_state != 100 );
+		yy_cp = (yy_last_accepting_cpos);
+		yy_current_state = (yy_last_accepting_state);
+
+yy_find_action:
+/* %% [10.0] code to find the action number goes here */
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+/* %% [11.0] code for code_lineno update goes here */
+
+do_action:	/* This label is used only to access EOF actions. */
+
+/* %% [12.0] debug code goes here */
+		if ( code__flex_debug )
+			{
+			if ( yy_act == 0 )
+				fprintf( stderr, "--scanner backing up\n" );
+			else if ( yy_act < 29 )
+				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+				         (long)yy_rule_linenum[yy_act], code_text );
+			else if ( yy_act == 29 )
+				fprintf( stderr, "--accepting default rule (\"%s\")\n",
+				         code_text );
+			else if ( yy_act == 30 )
+				fprintf( stderr, "--(end of buffer or a NUL)\n" );
+			else
+				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
+			}
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+/* %% [13.0] actions go here */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+/* rule 1 can match eol */
+YY_RULE_SETUP
+#line 132 "scan-code.l"
+STRING_GROW; BEGIN sc_context;
+	YY_BREAK
+
+/*--------------------------------------------------------------.
+  | Scanning a line comment.  The initial '//' is already eaten.  |
+  `--------------------------------------------------------------*/
+
+
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 142 "scan-code.l"
+STRING_GROW; BEGIN sc_context;
+	YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 143 "scan-code.l"
+STRING_GROW;
+	YY_BREAK
+
+/*--------------------------------------------.
+  | Scanning user-code characters and strings.  |
+  `--------------------------------------------*/
+
+
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+#line 153 "scan-code.l"
+STRING_GROW;
+	YY_BREAK
+
+
+
+case 5:
+YY_RULE_SETUP
+#line 158 "scan-code.l"
+STRING_GROW; BEGIN sc_context;
+	YY_BREAK
+
+
+
+case 6:
+YY_RULE_SETUP
+#line 163 "scan-code.l"
+STRING_GROW; BEGIN sc_context;
+	YY_BREAK
+
+
+
+case 7:
+YY_RULE_SETUP
+#line 169 "scan-code.l"
+{
+    STRING_GROW;
+    BEGIN SC_CHARACTER;
+    need_semicolon = true;
+  }
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 174 "scan-code.l"
+{
+    STRING_GROW;
+    BEGIN SC_STRING;
+    need_semicolon = true;
+  }
+	YY_BREAK
+case 9:
+/* rule 9 can match eol */
+YY_RULE_SETUP
+#line 179 "scan-code.l"
+{
+    STRING_GROW;
+    BEGIN SC_COMMENT;
+  }
+	YY_BREAK
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 183 "scan-code.l"
+{
+    STRING_GROW;
+    BEGIN SC_LINE_COMMENT;
+  }
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 187 "scan-code.l"
+{
+    warn_at (*loc, _("stray '%s'"), code_text);
+    obstack_escape (&obstack_for_string, code_text);
+    need_semicolon = true;
+  }
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 192 "scan-code.l"
+{
+    obstack_escape (&obstack_for_string, code_text);
+    need_semicolon = true;
+  }
+	YY_BREAK
+
+
+
+case 13:
+YY_RULE_SETUP
+#line 200 "scan-code.l"
+{
+    ref_tail_fields = NULL;
+    handle_action_dollar (self->rule, code_text, *loc);
+    if (ref_tail_fields)
+      obstack_sgrow (&obstack_for_string, ref_tail_fields);
+    need_semicolon = true;
+  }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 207 "scan-code.l"
+{
+    ref_tail_fields = NULL;
+    handle_action_at (self->rule, code_text, *loc);
+    if (ref_tail_fields)
+      obstack_sgrow (&obstack_for_string, ref_tail_fields);
+    need_semicolon = true;
+  }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 215 "scan-code.l"
+STRING_GROW;                 need_semicolon = false;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 216 "scan-code.l"
+STRING_GROW; ++braces_level; need_semicolon = false;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 217 "scan-code.l"
+{
+    bool outer_brace = --braces_level == 0;
+
+    /* As an undocumented Bison extension, append ';' before the last
+       brace in braced code, so that the user code can omit trailing
+       ';'.  But do not append ';' if emulating Yacc, since Yacc does
+       not append one.  This is deprecated since release 2.4.1.  */
+    if (outer_brace && !yacc_flag && language_prio == default_prio
+        && skeleton_prio == default_prio && need_semicolon && ! in_cpp)
+      {
+        unsigned int indent = 0;
+        warn_at_indent (*loc, &indent,
+                       _("a ';' might be needed at the end of action code"));
+        indent += SUB_INDENT;
+        warn_at_indent (*loc, &indent,
+                       _("future versions of Bison will not add the ';'"));
+        obstack_1grow (&obstack_for_string, ';');
+      }
+
+    STRING_GROW;
+    need_semicolon = false;
+  }
+	YY_BREAK
+/* Preprocessing directives should only be recognized at the beginning
+     of lines, allowing whitespace including comments, but in C/C++,
+     '#' can only be the start of preprocessor directives or within
+     '#define' directives anyway, so don't bother with begin of line.  */
+case 18:
+YY_RULE_SETUP
+#line 244 "scan-code.l"
+STRING_GROW; in_cpp = true;
+	YY_BREAK
+case 19:
+/* rule 19 can match eol */
+YY_RULE_SETUP
+#line 246 "scan-code.l"
+STRING_GROW;
+	YY_BREAK
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 247 "scan-code.l"
+STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 248 "scan-code.l"
+STRING_GROW;
+	YY_BREAK
+/* YYFAIL is undocumented and was formally deprecated in Bison
+     2.4.2.  */
+case 22:
+YY_RULE_SETUP
+#line 252 "scan-code.l"
+{
+    STRING_GROW; need_semicolon = true;
+    warn_at (*loc, _("use of YYFAIL, which is deprecated and will be"
+                     " removed"));
+  }
+	YY_BREAK
+/* The sole purpose of this is to make sure identifiers that merely
+     contain YYFAIL don't produce the above warning.  */
+case 23:
+YY_RULE_SETUP
+#line 260 "scan-code.l"
+STRING_GROW; need_semicolon = true;
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 262 "scan-code.l"
+STRING_GROW; need_semicolon = true;
+	YY_BREAK
+
+
+
+case 25:
+YY_RULE_SETUP
+#line 267 "scan-code.l"
+{
+    const char *type_name = NULL;
+    fetch_type_name (code_text + 1, &type_name, *loc)[-1] = 0;
+    obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar(");
+    obstack_quote (&obstack_for_string, type_name);
+    obstack_sgrow (&obstack_for_string, ")[");
+    self->is_value_used = true;
+  }
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 275 "scan-code.l"
+{
+    obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
+    locations_flag = true;
+  }
+	YY_BREAK
+
+
+
+/* Escape M4 quoting characters in C code.  */
+case 27:
+YY_RULE_SETUP
+#line 285 "scan-code.l"
+obstack_escape (&obstack_for_string, code_text);
+	YY_BREAK
+/* By default, grow the string obstack with the input.  */
+case 28:
+/* rule 28 can match eol */
+YY_RULE_SETUP
+#line 288 "scan-code.l"
+STRING_GROW;
+	YY_BREAK
+/* End of processing. */
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(SC_COMMENT):
+case YY_STATE_EOF(SC_LINE_COMMENT):
+case YY_STATE_EOF(SC_STRING):
+case YY_STATE_EOF(SC_CHARACTER):
+case YY_STATE_EOF(SC_RULE_ACTION):
+case YY_STATE_EOF(SC_SYMBOL_ACTION):
+#line 291 "scan-code.l"
+STRING_FINISH; return last_string;
+	YY_BREAK
+
+case 29:
+YY_RULE_SETUP
+#line 294 "scan-code.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+	YY_BREAK
+#line 1402 "scan-code.c"
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed code_in at a new source and called
+			 * code_lex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = code_in;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+				yy_cp = (yy_last_accepting_cpos);
+				yy_current_state = (yy_last_accepting_state);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( code_wrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * code_text, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of code_lex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %endif */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+/* %if-c-only */
+static int yy_get_next_buffer (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			yy_size_t num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				yy_size_t new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					code_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			code_restart(code_in  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) code_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+/* %if-c-only */
+/* %not-for-header */
+
+    static yy_state_type yy_get_previous_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+/* %% [15.0] code to get the start state into yy_current_state goes here */
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+/* %% [16.0] code to find the next state goes here */
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 30);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 101 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+/* %if-c-only */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+	register int yy_is_jam;
+    /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 30;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 101 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 100);
+
+		return yy_is_jam ? 0 : yy_current_state;
+}
+
+/* %if-c-only */
+
+/* %endif */
+
+/* %if-c-only */
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					code_restart(code_in );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( code_wrap( ) )
+						return EOF;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve code_text */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+/* %% [19.0] update BOL and code_lineno */
+
+	return c;
+}
+/* %if-c-only */
+#endif	/* ifndef YY_NO_INPUT */
+/* %endif */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+/* %if-c-only */
+    void code_restart  (FILE * input_file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        code_ensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            code__create_buffer(code_in,YY_BUF_SIZE );
+	}
+
+	code__init_buffer(YY_CURRENT_BUFFER,input_file );
+	code__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+/* %if-c-only */
+    void code__switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		code_pop_buffer_state();
+	 *		code_push_buffer_state(new_buffer);
+     */
+	code_ensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	code__load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (code_wrap()) processing, but the only time this flag
+	 * is looked at is after code_wrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/* %if-c-only */
+static void code__load_buffer_state  (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	code_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+/* %if-c-only */
+    YY_BUFFER_STATE code__create_buffer  (FILE * file, int  size )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) code_alloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in code__create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) code_alloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in code__create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	code__init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with code__create_buffer()
+ * 
+ */
+/* %if-c-only */
+    void code__delete_buffer (YY_BUFFER_STATE  b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		code_free((void *) b->yy_ch_buf  );
+
+	code_free((void *) b  );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a code_restart() or at EOF.
+ */
+/* %if-c-only */
+    static void code__init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+{
+	int oerrno = errno;
+    
+	code__flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then code__init_buffer was _probably_
+     * called from code_restart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+/* %if-c-only */
+
+        b->yy_is_interactive = 0;
+    
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+/* %if-c-only */
+    void code__flush_buffer (YY_BUFFER_STATE  b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		code__load_buffer_state( );
+}
+
+/* %if-c-or-c++ */
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+/* %if-c-only */
+void code_push_buffer_state (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    	if (new_buffer == NULL)
+		return;
+
+	code_ensure_buffer_stack();
+
+	/* This block is copied from code__switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from code__switch_to_buffer. */
+	code__load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+/* %if-c-only */
+void code_pop_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	code__delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		code__load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+/* %if-c-only */
+static void code_ensure_buffer_stack (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+	yy_size_t num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)code_alloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in code_ensure_buffer_stack()" );
+								  
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)code_realloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in code_ensure_buffer_stack()" );
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE code__scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) code_alloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in code__scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	code__switch_to_buffer(b  );
+
+	return b;
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan a string. The next call to code_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       code__scan_bytes() instead.
+ */
+YY_BUFFER_STATE code__scan_string (yyconst char * yystr )
+{
+    
+	return code__scan_bytes(yystr,strlen(yystr) );
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan the given bytes. The next call to code_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE code__scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) code_alloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in code__scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = code__scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in code__scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+/* %endif */
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+/* %if-c-only */
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up code_text. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		code_text[code_leng] = (yy_hold_char); \
+		(yy_c_buf_p) = code_text + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		code_leng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+
+/** Get the current line number.
+ * 
+ */
+int code_get_lineno  (void)
+{
+        
+    return code_lineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *code_get_in  (void)
+{
+        return code_in;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *code_get_out  (void)
+{
+        return code_out;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+yy_size_t code_get_leng  (void)
+{
+        return code_leng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *code_get_text  (void)
+{
+        return code_text;
+}
+
+/* %if-reentrant */
+/* %endif */
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void code_set_lineno (int  line_number )
+{
+    
+    code_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see code__switch_to_buffer
+ */
+void code_set_in (FILE *  in_str )
+{
+        code_in = in_str ;
+}
+
+void code_set_out (FILE *  out_str )
+{
+        code_out = out_str ;
+}
+
+int code_get_debug  (void)
+{
+        return code__flex_debug;
+}
+
+void code_set_debug (int  bdebug )
+{
+        code__flex_debug = bdebug ;
+}
+
+/* %endif */
+
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
+
+/* %if-c-only */
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from code_lex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    code_in = stdin;
+    code_out = stdout;
+#else
+    code_in = (FILE *) 0;
+    code_out = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * code_lex_init()
+     */
+    return 0;
+}
+/* %endif */
+
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* code_lex_destroy is for both reentrant and non-reentrant scanners. */
+int code_lex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		code__delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		code_pop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	code_free((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * code_lex() is called, initialization will occur. */
+    yy_init_globals( );
+
+/* %if-reentrant */
+/* %endif */
+    return 0;
+}
+/* %endif */
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *code_alloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *code_realloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void code_free (void * ptr )
+{
+	free( (char *) ptr );	/* see code_realloc() for (char *) cast */
+}
+
+/* %if-tables-serialization definitions */
+/* %define-yytables   The name for this specific scanner's tables. */
+#define YYTABLES_NAME "yytables"
+/* %endif */
+
+/* %ok-for-header */
+
+#line 294 "scan-code.l"
+
+
+
+static inline bool
+is_dot_or_dash (char ch)
+{
+  return ch == '.' || ch == '-';
+}
+
+static inline bool
+contains_dot_or_dash (const char* p)
+{
+  for (; *p; ++p)
+    if (is_dot_or_dash (*p))
+      return true;
+  return false;
+}
+
+/* Defines a variant of a symbolic name resolution. */
+typedef struct
+{
+  /* Index in symbol list. */
+  unsigned symbol_index;
+
+  /* Matched symbol id and loc. */
+  uniqstr id;
+  location loc;
+
+  /* Hiding named reference. */
+  named_ref* hidden_by;
+
+  /* Error flags. May contain zero (no errors) or
+     a combination of VARIANT_* values. */
+  unsigned err;
+} variant;
+
+/* Set when the variant refers to a symbol hidden
+   by an explicit symbol reference. */
+#define VARIANT_HIDDEN (1 << 0)
+
+/* Set when the variant refers to a symbol containing
+   dots or dashes. Will require explicit bracketing. */
+#define VARIANT_BAD_BRACKETING (1 << 1)
+
+/* Set when the variant refers to a symbol which is
+   not visible from current midrule. */
+#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2)
+
+static variant *variant_table = NULL;
+static unsigned variant_table_size = 0;
+static unsigned variant_count = 0;
+
+static variant *
+variant_table_grow (void)
+{
+  ++variant_count;
+  if (variant_count > variant_table_size)
+    {
+      while (variant_count > variant_table_size)
+	variant_table_size = 2 * variant_table_size + 3;
+      variant_table = xnrealloc (variant_table, variant_table_size,
+				 sizeof *variant_table);
+    }
+  return &variant_table[variant_count - 1];
+}
+
+static void
+variant_table_free (void)
+{
+  free (variant_table);
+  variant_table = NULL;
+  variant_table_size = variant_count = 0;
+}
+
+static char *
+find_prefix_end (const char *prefix, char *begin, char *end)
+{
+  char *ptr = begin;
+
+  for (; *prefix && ptr != end; ++prefix, ++ptr)
+    if (*prefix != *ptr)
+      return 0;
+
+  if (*prefix)
+    return 0;
+
+  return ptr;
+}
+
+static variant *
+variant_add (uniqstr id, location id_loc, unsigned symbol_index,
+	     char *cp, char *cp_end, bool explicit_bracketing)
+{
+  char *prefix_end;
+
+  prefix_end = find_prefix_end (id, cp, cp_end);
+  if (prefix_end &&
+      (prefix_end == cp_end ||
+       (!explicit_bracketing && is_dot_or_dash (*prefix_end))))
+    {
+      variant *r = variant_table_grow ();
+      r->symbol_index = symbol_index;
+      r->id = id;
+      r->loc = id_loc;
+      r->hidden_by = NULL;
+      r->err = 0;
+      return r;
+    }
+  else
+    return NULL;
+}
+
+static const char *
+get_at_spec (unsigned symbol_index)
+{
+  static char at_buf[20];
+  if (symbol_index == 0)
+    strcpy (at_buf, "$$");
+  else
+    snprintf (at_buf, sizeof at_buf, "$%u", symbol_index);
+  return at_buf;
+}
+
+static void
+show_sub_messages (const char* cp, bool explicit_bracketing,
+                   int midrule_rhs_index, char dollar_or_at,
+                   bool is_warning, unsigned indent)
+{
+  unsigned i;
+
+  for (i = 0; i < variant_count; ++i)
+    {
+      const variant *var = &variant_table[i];
+      const char *at_spec = get_at_spec (var->symbol_index);
+
+      if (var->err == 0)
+        {
+          if (is_warning)
+            warn_at_indent (var->loc, &indent, _("refers to: %c%s at %s"),
+                            dollar_or_at, var->id, at_spec);
+          else
+            complain_at_indent (var->loc, &indent, _("refers to: %c%s at %s"),
+                                dollar_or_at, var->id, at_spec);
+        }
+      else
+	{
+	  static struct obstack msg_buf;
+	  const char *tail = explicit_bracketing ? "" :
+	    cp + strlen (var->id);
+	  const char *id = var->hidden_by ? var->hidden_by->id :
+	    var->id;
+	  location id_loc = var->hidden_by ? var->hidden_by->loc :
+	    var->loc;
+
+	  /* Create the explanation message. */
+	  obstack_init (&msg_buf);
+
+	  obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at);
+	  if (contains_dot_or_dash (id))
+	    obstack_printf (&msg_buf, "[%s]", id);
+	  else
+	    obstack_sgrow (&msg_buf, id);
+	  obstack_sgrow (&msg_buf, tail);
+
+	  if (var->err & VARIANT_HIDDEN)
+	    {
+	      obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at);
+	      if (contains_dot_or_dash (var->id))
+		obstack_printf (&msg_buf, "[%s]", var->id);
+	      else
+		obstack_sgrow (&msg_buf, var->id);
+	      obstack_sgrow (&msg_buf, tail);
+	    }
+
+	  obstack_printf (&msg_buf, _(" at %s"), at_spec);
+
+	  if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE)
+            {
+              const char *format =
+                _(", cannot be accessed from mid-rule action at $%d");
+              obstack_printf (&msg_buf, format, midrule_rhs_index);
+            }
+
+	  obstack_1grow (&msg_buf, '\0');
+          if (is_warning)
+            warn_at_indent (id_loc, &indent, "%s",
+                            (char *) obstack_finish (&msg_buf));
+          else
+            complain_at_indent (id_loc, &indent, "%s",
+                                (char *) obstack_finish (&msg_buf));
+	  obstack_free (&msg_buf, 0);
+	}
+    }
+}
+
+/* Returned from "parse_ref" when the reference
+   is inappropriate. */
+#define INVALID_REF (INT_MIN)
+
+/* Returned from "parse_ref" when the reference
+   points to LHS ($$) of the current rule or midrule. */
+#define LHS_REF (INT_MIN + 1)
+
+/* Parse named or positional reference. In case of positional
+   references, can return negative values for $-n "deep" stack
+   accesses. */
+static long int
+parse_ref (char *cp, symbol_list *rule, int rule_length,
+	   int midrule_rhs_index, char *text, location text_loc,
+	   char dollar_or_at)
+{
+  symbol_list *l;
+  char *cp_end;
+  bool explicit_bracketing;
+  unsigned i;
+  unsigned valid_variants = 0;
+  unsigned valid_variant_index = 0;
+
+  if ('$' == *cp)
+    return LHS_REF;
+
+  if (c_isdigit (*cp) || (*cp == '-' && c_isdigit (* (cp + 1))))
+    {
+      long int num = strtol (cp, &cp, 10);
+      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
+	return num;
+      else
+	{
+	  complain_at (text_loc, _("integer out of range: %s"),
+                       quote (text));
+	  return INVALID_REF;
+	}
+    }
+
+  if ('[' == *cp)
+    {
+      /* Ignore the brackets. */
+      char *p;
+      for (p = ++cp; *p != ']'; ++p)
+	continue;
+      cp_end = p;
+
+      explicit_bracketing = true;
+    }
+  else
+    {
+      /* Take all characters of the name. */
+      char* p;
+      for (p = cp; *p; ++p)
+	if (is_dot_or_dash (*p))
+	  {
+	    ref_tail_fields = p;
+	    break;
+	  }
+      for (p = cp; *p; ++p)
+	continue;
+      cp_end = p;
+
+      explicit_bracketing = false;
+    }
+
+  /* Add all relevant variants. */
+  {
+    unsigned symbol_index;
+    variant_count = 0;
+    for (symbol_index = 0, l = rule; !symbol_list_null (l);
+         ++symbol_index, l = l->next)
+      {
+	variant *var;
+	if (l->content_type != SYMLIST_SYMBOL)
+	  continue;
+
+	var = variant_add (l->content.sym->tag, l->sym_loc,
+                           symbol_index, cp, cp_end, explicit_bracketing);
+	if (var && l->named_ref)
+	  var->hidden_by = l->named_ref;
+
+	if (l->named_ref)
+	  variant_add (l->named_ref->id, l->named_ref->loc,
+                       symbol_index, cp, cp_end, explicit_bracketing);
+      }
+  }
+
+  /* Check errors. */
+  for (i = 0; i < variant_count; ++i)
+    {
+      variant *var = &variant_table[i];
+      unsigned symbol_index = var->symbol_index;
+
+      /* Check visibility from mid-rule actions. */
+      if (midrule_rhs_index != 0
+	  && (symbol_index == 0 || midrule_rhs_index < symbol_index))
+        var->err |= VARIANT_NOT_VISIBLE_FROM_MIDRULE;
+
+      /* Check correct bracketing. */
+      if (!explicit_bracketing && contains_dot_or_dash (var->id))
+        var->err |= VARIANT_BAD_BRACKETING;
+
+      /* Check using of hidden symbols. */
+      if (var->hidden_by)
+        var->err |= VARIANT_HIDDEN;
+
+      if (!var->err)
+        {
+          valid_variant_index = i;
+          ++valid_variants;
+        }
+    }
+
+  switch (valid_variants)
+    {
+    case 0:
+      {
+        unsigned len = (explicit_bracketing || !ref_tail_fields) ?
+          cp_end - cp : ref_tail_fields - cp;
+        unsigned indent = 0;
+
+        complain_at_indent (text_loc, &indent, _("invalid reference: %s"),
+                            quote (text));
+        indent += SUB_INDENT;
+        if (len == 0)
+          {
+            location sym_loc = text_loc;
+            sym_loc.start.column += 1;
+            sym_loc.end = sym_loc.start;
+            const char *format =
+              _("syntax error after '%c', expecting integer, letter,"
+                " '_', '[', or '$'");
+            complain_at_indent (sym_loc, &indent, format, dollar_or_at);
+          }
+        else if (midrule_rhs_index)
+          {
+            const char *format =
+              _("symbol not found in production before $%d: %.*s");
+            complain_at_indent (rule->location, &indent, format,
+                                midrule_rhs_index, len, cp);
+          }
+        else
+          {
+            const char *format =
+              _("symbol not found in production: %.*s");
+            complain_at_indent (rule->location, &indent, format,
+                                len, cp);
+          }
+
+        if (variant_count > 0)
+          show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
+                             dollar_or_at, false, indent);
+        return INVALID_REF;
+      }
+    case 1:
+      {
+        unsigned indent = 0;
+        if (variant_count > 1)
+          {
+            warn_at_indent (text_loc, &indent, _("misleading reference: %s"),
+                            quote (text));
+            show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
+                               dollar_or_at, true, indent + SUB_INDENT);
+          }
+        {
+          unsigned symbol_index =
+            variant_table[valid_variant_index].symbol_index;
+          return (symbol_index == midrule_rhs_index) ? LHS_REF : symbol_index;
+        }
+      }
+    case 2:
+    default:
+      {
+        unsigned indent = 0;
+        complain_at_indent (text_loc, &indent, _("ambiguous reference: %s"),
+                            quote (text));
+        show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
+                           dollar_or_at, false, indent + SUB_INDENT);
+        return INVALID_REF;
+      }
+    }
+
+  /* Not reachable. */
+  return INVALID_REF;
+}
+
+/* Keeps track of the maximum number of semantic values to the left of
+   a handle (those referenced by $0, $-1, etc.) are required by the
+   semantic actions of this grammar. */
+int max_left_semantic_context = 0;
+
+
+/* If CP points to a typename (i.e., <.*?>), set TYPE_NAME to its
+   beginning (i.e., after the opening "<", and return the pointer
+   immediately after it.  */
+
+static
+char *
+fetch_type_name (char *cp, char const **type_name,
+                 location dollar_loc)
+{
+  if (*cp == '<')
+    {
+      *type_name = ++cp;
+      while (*cp != '>')
+	++cp;
+
+      /* The '>' symbol will be later replaced by '\0'. Original
+	 'text' is needed for error messages. */
+      ++cp;
+      if (untyped_var_seen)
+	complain_at (dollar_loc, _("explicit type given in untyped grammar"));
+      tag_seen = true;
+    }
+  return cp;
+}
+
+/*------------------------------------------------------------------.
+| TEXT is pointing to a wannabee semantic value (i.e., a '$').      |
+|                                                                   |
+| Possible inputs: $[<TYPENAME>]($|integer)                         |
+|                                                                   |
+| Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
+`------------------------------------------------------------------*/
+
+static void
+handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
+{
+  char const *type_name = NULL;
+  char *cp = text + 1;
+  symbol_list *effective_rule;
+  int effective_rule_length;
+  int n;
+
+  if (rule->midrule_parent_rule)
+    {
+      effective_rule = rule->midrule_parent_rule;
+      effective_rule_length = rule->midrule_parent_rhs_index - 1;
+    }
+  else
+    {
+      effective_rule = rule;
+      effective_rule_length = symbol_list_length (rule->next);
+    }
+
+  /* Get the type name if explicit. */
+  cp = fetch_type_name (cp, &type_name, dollar_loc);
+
+  n = parse_ref (cp, effective_rule, effective_rule_length,
+		 rule->midrule_parent_rhs_index, text, dollar_loc, '$');
+
+  /* End type_name. */
+  if (type_name)
+    cp[-1] = '\0';
+
+  switch (n)
+    {
+    case INVALID_REF:
+      break;
+
+    case LHS_REF:
+      if (!type_name)
+	type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
+
+      if (!type_name)
+        {
+          if (union_seen | tag_seen)
+            {
+              if (rule->midrule_parent_rule)
+                complain_at (dollar_loc,
+                             _("$$ for the midrule at $%d of %s"
+                               " has no declared type"),
+                             rule->midrule_parent_rhs_index,
+                             quote (effective_rule->content.sym->tag));
+              else
+                complain_at (dollar_loc, _("$$ of %s has no declared type"),
+                             quote (rule->content.sym->tag));
+            }
+          else
+            untyped_var_seen = true;
+        }
+
+      obstack_sgrow (&obstack_for_string, "]b4_lhs_value(");
+      obstack_quote (&obstack_for_string, type_name);
+      obstack_sgrow (&obstack_for_string, ")[");
+      rule->action_props.is_value_used = true;
+      break;
+
+    default:
+      if (max_left_semantic_context < 1 - n)
+	max_left_semantic_context = 1 - n;
+      if (!type_name && 0 < n)
+	type_name =
+	  symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
+      if (!type_name)
+        {
+          if (union_seen | tag_seen)
+            complain_at (dollar_loc, _("$%s of %s has no declared type"),
+                         cp, quote (effective_rule->content.sym->tag));
+          else
+            untyped_var_seen = true;
+        }
+
+      obstack_printf (&obstack_for_string,
+		      "]b4_rhs_value(%d, %d, ", effective_rule_length, n);
+      obstack_quote (&obstack_for_string, type_name);
+      obstack_sgrow (&obstack_for_string, ")[");
+      if (n > 0)
+	symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
+	  true;
+      break;
+    }
+}
+
+
+/*------------------------------------------------------.
+| TEXT is a location token (i.e., a '@...').  Output to |
+| OBSTACK_FOR_STRING a reference to this location.      |
+`------------------------------------------------------*/
+
+static void
+handle_action_at (symbol_list *rule, char *text, location at_loc)
+{
+  char *cp = text + 1;
+  symbol_list *effective_rule;
+  int effective_rule_length;
+  int n;
+
+  if (rule->midrule_parent_rule)
+    {
+      effective_rule = rule->midrule_parent_rule;
+      effective_rule_length = rule->midrule_parent_rhs_index - 1;
+    }
+  else
+    {
+      effective_rule = rule;
+      effective_rule_length = symbol_list_length (rule->next);
+    }
+
+  locations_flag = true;
+
+  n = parse_ref (cp, effective_rule, effective_rule_length,
+                 rule->midrule_parent_rhs_index, text, at_loc, '@');
+  switch (n)
+    {
+    case INVALID_REF:
+      break;
+
+    case LHS_REF:
+      obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
+      break;
+
+    default:
+      obstack_printf (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
+		      effective_rule_length, n);
+      break;
+    }
+}
+
+
+/*-------------------------.
+| Initialize the scanner.  |
+`-------------------------*/
+
+/* Translate the dollars and ats in \a self, in the context \a sc_context
+   (SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL).  */
+
+static char const *
+translate_action (code_props *self, int sc_context)
+{
+  char *res;
+  static bool initialized = false;
+  if (!initialized)
+    {
+      obstack_init (&obstack_for_string);
+      code__flex_debug = 0;
+      initialized = true;
+    }
+
+  loc->start = loc->end = self->location.start;
+  code__switch_to_buffer (code__scan_string (self->code));
+  res = code_lex (self, sc_context);
+  code__delete_buffer (YY_CURRENT_BUFFER);
+
+  return res;
+}
+
+/*------------------------------------------------------------------------.
+| Implementation of the public interface as documented in "scan-code.h".  |
+`------------------------------------------------------------------------*/
+
+void
+code_props_none_init (code_props *self)
+{
+  *self = code_props_none;
+}
+
+code_props const code_props_none = CODE_PROPS_NONE_INIT;
+
+void
+code_props_plain_init (code_props *self, char const *code,
+		       location code_loc)
+{
+  self->kind = CODE_PROPS_PLAIN;
+  self->code = code;
+  self->location = code_loc;
+  self->is_value_used = false;
+  self->rule = NULL;
+  self->named_ref = NULL;
+}
+
+void
+code_props_symbol_action_init (code_props *self, char const *code,
+                               location code_loc)
+{
+  self->kind = CODE_PROPS_SYMBOL_ACTION;
+  self->code = code;
+  self->location = code_loc;
+  self->is_value_used = false;
+  self->rule = NULL;
+  self->named_ref = NULL;
+}
+
+void
+code_props_rule_action_init (code_props *self, char const *code,
+                             location code_loc, symbol_list *rule,
+			     named_ref *name)
+{
+  self->kind = CODE_PROPS_RULE_ACTION;
+  self->code = code;
+  self->location = code_loc;
+  self->is_value_used = false;
+  self->rule = rule;
+  self->named_ref = name;
+}
+
+void
+code_props_translate_code (code_props *self)
+{
+  switch (self->kind)
+    {
+      case CODE_PROPS_NONE:
+        break;
+      case CODE_PROPS_PLAIN:
+        self->code = translate_action (self, INITIAL);
+        break;
+      case CODE_PROPS_SYMBOL_ACTION:
+        self->code = translate_action (self, SC_SYMBOL_ACTION);
+        break;
+      case CODE_PROPS_RULE_ACTION:
+        self->code = translate_action (self, SC_RULE_ACTION);
+        break;
+    }
+}
+
+void
+code_scanner_last_string_free (void)
+{
+  STRING_FREE;
+}
+
+void
+code_scanner_free (void)
+{
+  obstack_free (&obstack_for_string, 0);
+  variant_table_free ();
+
+  /* Reclaim Flex's buffers.  */
+  code_lex_destroy ();
+}
+
diff --git a/src/scan-code.h b/src/scan-code.h
new file mode 100644
index 0000000..c8d554d
--- /dev/null
+++ b/src/scan-code.h
@@ -0,0 +1,176 @@
+/* Bison code properties structure and scanner.
+
+   Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef SCAN_CODE_H_
+# define SCAN_CODE_H_
+
+# include "location.h"
+# include "named-ref.h"
+
+struct symbol_list;
+
+/**
+ * Keeps track of the maximum number of semantic values to the left of a handle
+ * (those referenced by $0, $-1, etc.) that are required by the semantic
+ * actions of this grammar.
+ */
+extern int max_left_semantic_context;
+
+/**
+ * A code passage captured from the grammar file and possibly translated,
+ * and/or properties associated with such a code passage.  Don't break
+ * encapsulation by modifying the fields directly.  Use the provided interface
+ * functions.
+ */
+typedef struct code_props {
+  /** Set by the init functions.  */
+  enum {
+    CODE_PROPS_NONE, CODE_PROPS_PLAIN,
+    CODE_PROPS_SYMBOL_ACTION, CODE_PROPS_RULE_ACTION
+  } kind;
+
+  /**
+   * \c NULL iff \c code_props::kind is \c CODE_PROPS_NONE.
+   * Memory is allocated in an obstack freed elsewhere.
+   */
+  char const *code;
+  /** Undefined iff \c code_props::code is \c NULL.  */
+  location location;
+
+  /**
+   * \c false iff either:
+   *   - \c code_props_translate_code has never previously been invoked for
+   *     the \c code_props that would contain the code passage associated
+   *     with \c self.  (That \c code_props is not the same as this one if this
+   *     one is for a RHS \c symbol_list node.  Instead, it's the \c code_props
+   *     for the LHS symbol of the same rule.)
+   *   - \c code_props_translate_code has been invoked for that \c code_props,
+   *     but the symbol value associated with this \c code_props was not
+   *     referenced in the code passage.
+   */
+  bool is_value_used;
+
+  /** \c NULL iff \c code_props::kind is not \c CODE_PROPS_RULE_ACTION.  */
+  struct symbol_list *rule;
+
+  /* Named reference. */
+  named_ref *named_ref;
+} code_props;
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ * \post
+ *   - \c self has been overwritten to contain no code.
+ */
+void code_props_none_init (code_props *self);
+
+/** Equivalent to \c code_props_none_init.  */
+#define CODE_PROPS_NONE_INIT \
+  {CODE_PROPS_NONE, NULL, EMPTY_LOCATION_INIT, false, NULL, NULL}
+
+/** Initialized by \c CODE_PROPS_NONE_INIT with no further modification.  */
+extern code_props const code_props_none;
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - <tt>code != NULL</tt>.
+ *   - \c code is an untranslated code passage containing no Bison escapes.
+ *   - \c code was extracted from the grammar file at \c code_loc.
+ * \post
+ *   - \c self has been overwritten to represent the specified plain code
+ *     passage.
+ *   - \c self will become invalid if the caller frees \c code before invoking
+ *     \c code_props_translate_code on \c self.
+ */
+void code_props_plain_init (code_props *self, char const *code,
+                            location code_loc);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - <tt>code != NULL</tt>.
+ *   - \c code is an untranslated code passage.  The only Bison escapes it
+ *     might contain are $$ and \@$, referring to a single symbol.
+ *   - \c code was extracted from the grammar file at \c code_loc.
+ * \post
+ *   - \c self has been overwritten to represent the specified symbol action.
+ *   - \c self will become invalid if the caller frees \c code before invoking
+ *     \c code_props_translate_code on \c self.
+ */
+void code_props_symbol_action_init (code_props *self, char const *code,
+                                    location code_loc);
+
+/**
+ * \pre
+ *   - <tt>self != NULL</tt>.
+ *   - <tt>code != NULL</tt>.
+ *   - <tt>rule != NULL</tt>.
+ *   - \c code is the untranslated action of the rule for which \c rule is the
+ *     LHS node.  Thus, \c code possibly contains Bison escapes such as $$, $1,
+ *     $2, etc referring to the values of the rule.
+ *   - \c code was extracted from the grammar file at \c code_loc.
+ * \post
+ *   - \c self has been overwritten to represent the specified rule action.
+ *   - \c self does not claim responsibility for the memory of \c rule.
+ *   - \c self will become invalid if:
+ *     - The caller frees \c code before invoking \c code_props_translate_code
+ *       on \c self.
+ *     - The caller frees \c rule.
+ */
+void code_props_rule_action_init (code_props *self, char const *code,
+                                  location code_loc, struct symbol_list *rule,
+                                  named_ref *name);
+
+/**
+ * \pre
+ *   - If there's a code passage contained in \c self and it contains Bison
+ *     escapes, all grammar declarations have already been parsed as they may
+ *     affect warnings and complaints issued here.
+ * \post
+ *   - All M4-special symbols and Bison escapes have been translated in
+ *     \c self->code.
+ *   - <tt>self->code != self->code\@pre</tt> unless
+ *     <tt>self->code\@pre = NULL</tt>.
+ */
+void code_props_translate_code (code_props *self);
+
+/**
+ * \pre
+ *   - None.
+ * \post
+ *   - The dynamic memory allocated by the previous invocation of
+ *     \c code_props_translate_code (if any) was freed.  The \c code_props
+ *     instance for which \c code_props_translate_code was invoked is now
+ *     invalid.
+ */
+void code_scanner_last_string_free (void);
+
+/**
+ * \pre
+ *   - None.
+ * \post
+ *   - All dynamic memory allocated during invocations of
+ *     \c code_props_translate_code (if any) has been freed.  All \c code_props
+ *     instances may now be invalid.
+ */
+void code_scanner_free (void);
+
+#endif /* !SCAN_CODE_H_ */
diff --git a/src/scan-code.l b/src/scan-code.l
new file mode 100644
index 0000000..560d343
--- /dev/null
+++ b/src/scan-code.l
@@ -0,0 +1,958 @@
+/* Bison Action Scanner                             -*- C -*-
+
+   Copyright (C) 2006-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+%option debug nodefault noinput nounput noyywrap never-interactive
+%option prefix="code_" outfile="lex.yy.c"
+
+%{
+/* Work around a bug in flex 2.5.31.  See Debian bug 333231
+   <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
+#undef code_wrap
+#define code_wrap() 1
+
+#define FLEX_PREFIX(Id) code_ ## Id
+#include "flex-scanner.h"
+
+#include "complain.h"
+#include "reader.h"
+#include "getargs.h"
+#include "scan-code.h"
+#include "symlist.h"
+
+#include <c-ctype.h>
+#include <get-errno.h>
+#include <quote.h>
+
+/* The current calling start condition: SC_RULE_ACTION or
+   SC_SYMBOL_ACTION. */
+# define YY_DECL static char *code_lex (code_props *self, int sc_context)
+YY_DECL;
+
+#define YY_USER_ACTION  location_compute (loc, &loc->end, yytext, yyleng);
+
+static char *fetch_type_name (char *cp, char const **type_name,
+                              location dollar_loc);
+
+static void handle_action_dollar (symbol_list *rule, char *cp,
+				  location dollar_loc);
+static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
+
+/* A string to be pushed to obstack after dollar/at has been handled. */
+static char *ref_tail_fields;
+
+static location the_location;
+static location *loc = &the_location;
+
+/* A string representing the most recent translation.  */
+static char *last_string;
+
+/* True if an untyped $$ or $n was seen.  */
+static bool untyped_var_seen;
+
+%}
+ /* C and C++ comments in code. */
+%x SC_COMMENT SC_LINE_COMMENT
+ /* Strings and characters in code. */
+%x SC_STRING SC_CHARACTER
+ /* Whether in a rule or symbol action.  Specifies the translation
+    of $ and @.  */
+%x SC_RULE_ACTION SC_SYMBOL_ACTION
+
+
+/* POSIX says that a tag must be both an id and a C union member, but
+   historically almost any character is allowed in a tag.  We disallow
+   NUL and newline, as this simplifies our implementation.  */
+tag	 [^\0\n>]+
+
+/* Zero or more instances of backslash-newline.  Following GCC, allow
+   white space between the backslash and the newline.  */
+splice	 (\\[ \f\t\v]*\n)*
+
+/* C style identifier. Must start with letter. Will be used for
+   named symbol references. Shall be kept synchronized with
+   scan-gram.l "letter" and "id". */
+letter	  [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
+id	  {letter}({letter}|[-0-9])*
+ref      -?[0-9]+|{id}|"["{id}"]"|"$"
+
+%%
+
+%{
+  /* Nesting level of the current code in braces.  */
+  int braces_level = 0;
+
+  /* Whether a semicolon is probably needed.
+
+     The heuristic is that a semicolon is not needed after '{', '}',
+     ';', or a C preprocessor directive, and that whitespaces and
+     comments do not affect this flag.  Note that '{' does not need a
+     semicolon because of '{}'.  A semicolon may be needed before a
+     cpp directive, but don't bother.
+
+     While it is maintained in several start-conditions (factoring
+     opportunities), it is meaningful only for SC_RULE_ACTION. */
+  bool need_semicolon = false;
+
+  /* Whether in a C preprocessor directive.  Don't use a start condition
+     for this because, at the end of strings and comments, we still need
+     to know whether we're in a directive.  */
+  bool in_cpp = false;
+
+  /* This scanner is special: it is invoked only once, henceforth
+     is expected to return only once.  This initialization is
+     therefore done once per action to translate. */
+  aver (sc_context == SC_SYMBOL_ACTION
+	|| sc_context == SC_RULE_ACTION
+	|| sc_context == INITIAL);
+  BEGIN sc_context;
+%}
+
+  /*------------------------------------------------------------.
+  | Scanning a C comment.  The initial '/ *' is already eaten.  |
+  `------------------------------------------------------------*/
+
+<SC_COMMENT>
+{
+  "*"{splice}"/"  STRING_GROW; BEGIN sc_context;
+}
+
+
+  /*--------------------------------------------------------------.
+  | Scanning a line comment.  The initial '//' is already eaten.  |
+  `--------------------------------------------------------------*/
+
+<SC_LINE_COMMENT>
+{
+  "\n"		 STRING_GROW; BEGIN sc_context;
+  {splice}	 STRING_GROW;
+}
+
+
+  /*--------------------------------------------.
+  | Scanning user-code characters and strings.  |
+  `--------------------------------------------*/
+
+<SC_CHARACTER,SC_STRING>
+{
+  {splice}|\\{splice}.	STRING_GROW;
+}
+
+<SC_CHARACTER>
+{
+  "'"		STRING_GROW; BEGIN sc_context;
+}
+
+<SC_STRING>
+{
+  "\""		STRING_GROW; BEGIN sc_context;
+}
+
+
+<SC_RULE_ACTION,SC_SYMBOL_ACTION>
+{
+  "'" {
+    STRING_GROW;
+    BEGIN SC_CHARACTER;
+    need_semicolon = true;
+  }
+  "\"" {
+    STRING_GROW;
+    BEGIN SC_STRING;
+    need_semicolon = true;
+  }
+  "/"{splice}"*" {
+    STRING_GROW;
+    BEGIN SC_COMMENT;
+  }
+  "/"{splice}"/" {
+    STRING_GROW;
+    BEGIN SC_LINE_COMMENT;
+  }
+  [$@]  {
+    warn_at (*loc, _("stray '%s'"), yytext);
+    obstack_escape (&obstack_for_string, yytext);
+    need_semicolon = true;
+  }
+  [\[\]]  {
+    obstack_escape (&obstack_for_string, yytext);
+    need_semicolon = true;
+  }
+}
+
+<SC_RULE_ACTION>
+{
+  "$"("<"{tag}">")?{ref}  {
+    ref_tail_fields = NULL;
+    handle_action_dollar (self->rule, yytext, *loc);
+    if (ref_tail_fields)
+      obstack_sgrow (&obstack_for_string, ref_tail_fields);
+    need_semicolon = true;
+  }
+  "@"{ref} {
+    ref_tail_fields = NULL;
+    handle_action_at (self->rule, yytext, *loc);
+    if (ref_tail_fields)
+      obstack_sgrow (&obstack_for_string, ref_tail_fields);
+    need_semicolon = true;
+  }
+
+  ";"  STRING_GROW;                 need_semicolon = false;
+  "{"  STRING_GROW; ++braces_level; need_semicolon = false;
+  "}"  {
+    bool outer_brace = --braces_level == 0;
+
+    /* As an undocumented Bison extension, append ';' before the last
+       brace in braced code, so that the user code can omit trailing
+       ';'.  But do not append ';' if emulating Yacc, since Yacc does
+       not append one.  This is deprecated since release 2.4.1.  */
+    if (outer_brace && !yacc_flag && language_prio == default_prio
+        && skeleton_prio == default_prio && need_semicolon && ! in_cpp)
+      {
+        unsigned int indent = 0;
+        warn_at_indent (*loc, &indent,
+                       _("a ';' might be needed at the end of action code"));
+        indent += SUB_INDENT;
+        warn_at_indent (*loc, &indent,
+                       _("future versions of Bison will not add the ';'"));
+        obstack_1grow (&obstack_for_string, ';');
+      }
+
+    STRING_GROW;
+    need_semicolon = false;
+  }
+
+  /* Preprocessing directives should only be recognized at the beginning
+     of lines, allowing whitespace including comments, but in C/C++,
+     '#' can only be the start of preprocessor directives or within
+     '#define' directives anyway, so don't bother with begin of line.  */
+  "#"       STRING_GROW; in_cpp = true;
+
+  {splice}  STRING_GROW;
+  [\n\r]    STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false;
+  [ \t\f]   STRING_GROW;
+
+  /* YYFAIL is undocumented and was formally deprecated in Bison
+     2.4.2.  */
+  YYFAIL {
+    STRING_GROW; need_semicolon = true;
+    warn_at (*loc, _("use of YYFAIL, which is deprecated and will be"
+                     " removed"));
+  }
+
+  /* The sole purpose of this is to make sure identifiers that merely
+     contain YYFAIL don't produce the above warning.  */
+  [A-Za-z_][0-9A-Za-z_]* STRING_GROW; need_semicolon = true;
+
+  . STRING_GROW; need_semicolon = true;
+}
+
+<SC_SYMBOL_ACTION>
+{
+  "$"("<"{tag}">")?"$" {
+    const char *type_name = NULL;
+    fetch_type_name (yytext + 1, &type_name, *loc)[-1] = 0;
+    obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar(");
+    obstack_quote (&obstack_for_string, type_name);
+    obstack_sgrow (&obstack_for_string, ")[");
+    self->is_value_used = true;
+  }
+  "@$" {
+    obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
+    locations_flag = true;
+  }
+}
+
+
+<*>
+{
+  /* Escape M4 quoting characters in C code.  */
+  [$@\[\]]    obstack_escape (&obstack_for_string, yytext);
+
+  /* By default, grow the string obstack with the input.  */
+  .|\n        STRING_GROW;
+
+  /* End of processing. */
+  <<EOF>>     STRING_FINISH; return last_string;
+}
+
+%%
+
+static inline bool
+is_dot_or_dash (char ch)
+{
+  return ch == '.' || ch == '-';
+}
+
+static inline bool
+contains_dot_or_dash (const char* p)
+{
+  for (; *p; ++p)
+    if (is_dot_or_dash (*p))
+      return true;
+  return false;
+}
+
+/* Defines a variant of a symbolic name resolution. */
+typedef struct
+{
+  /* Index in symbol list. */
+  unsigned symbol_index;
+
+  /* Matched symbol id and loc. */
+  uniqstr id;
+  location loc;
+
+  /* Hiding named reference. */
+  named_ref* hidden_by;
+
+  /* Error flags. May contain zero (no errors) or
+     a combination of VARIANT_* values. */
+  unsigned err;
+} variant;
+
+/* Set when the variant refers to a symbol hidden
+   by an explicit symbol reference. */
+#define VARIANT_HIDDEN (1 << 0)
+
+/* Set when the variant refers to a symbol containing
+   dots or dashes. Will require explicit bracketing. */
+#define VARIANT_BAD_BRACKETING (1 << 1)
+
+/* Set when the variant refers to a symbol which is
+   not visible from current midrule. */
+#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2)
+
+static variant *variant_table = NULL;
+static unsigned variant_table_size = 0;
+static unsigned variant_count = 0;
+
+static variant *
+variant_table_grow (void)
+{
+  ++variant_count;
+  if (variant_count > variant_table_size)
+    {
+      while (variant_count > variant_table_size)
+	variant_table_size = 2 * variant_table_size + 3;
+      variant_table = xnrealloc (variant_table, variant_table_size,
+				 sizeof *variant_table);
+    }
+  return &variant_table[variant_count - 1];
+}
+
+static void
+variant_table_free (void)
+{
+  free (variant_table);
+  variant_table = NULL;
+  variant_table_size = variant_count = 0;
+}
+
+static char *
+find_prefix_end (const char *prefix, char *begin, char *end)
+{
+  char *ptr = begin;
+
+  for (; *prefix && ptr != end; ++prefix, ++ptr)
+    if (*prefix != *ptr)
+      return 0;
+
+  if (*prefix)
+    return 0;
+
+  return ptr;
+}
+
+static variant *
+variant_add (uniqstr id, location id_loc, unsigned symbol_index,
+	     char *cp, char *cp_end, bool explicit_bracketing)
+{
+  char *prefix_end;
+
+  prefix_end = find_prefix_end (id, cp, cp_end);
+  if (prefix_end &&
+      (prefix_end == cp_end ||
+       (!explicit_bracketing && is_dot_or_dash (*prefix_end))))
+    {
+      variant *r = variant_table_grow ();
+      r->symbol_index = symbol_index;
+      r->id = id;
+      r->loc = id_loc;
+      r->hidden_by = NULL;
+      r->err = 0;
+      return r;
+    }
+  else
+    return NULL;
+}
+
+static const char *
+get_at_spec (unsigned symbol_index)
+{
+  static char at_buf[20];
+  if (symbol_index == 0)
+    strcpy (at_buf, "$$");
+  else
+    snprintf (at_buf, sizeof at_buf, "$%u", symbol_index);
+  return at_buf;
+}
+
+static void
+show_sub_messages (const char* cp, bool explicit_bracketing,
+                   int midrule_rhs_index, char dollar_or_at,
+                   bool is_warning, unsigned indent)
+{
+  unsigned i;
+
+  for (i = 0; i < variant_count; ++i)
+    {
+      const variant *var = &variant_table[i];
+      const char *at_spec = get_at_spec (var->symbol_index);
+
+      if (var->err == 0)
+        {
+          if (is_warning)
+            warn_at_indent (var->loc, &indent, _("refers to: %c%s at %s"),
+                            dollar_or_at, var->id, at_spec);
+          else
+            complain_at_indent (var->loc, &indent, _("refers to: %c%s at %s"),
+                                dollar_or_at, var->id, at_spec);
+        }
+      else
+	{
+	  static struct obstack msg_buf;
+	  const char *tail = explicit_bracketing ? "" :
+	    cp + strlen (var->id);
+	  const char *id = var->hidden_by ? var->hidden_by->id :
+	    var->id;
+	  location id_loc = var->hidden_by ? var->hidden_by->loc :
+	    var->loc;
+
+	  /* Create the explanation message. */
+	  obstack_init (&msg_buf);
+
+	  obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at);
+	  if (contains_dot_or_dash (id))
+	    obstack_printf (&msg_buf, "[%s]", id);
+	  else
+	    obstack_sgrow (&msg_buf, id);
+	  obstack_sgrow (&msg_buf, tail);
+
+	  if (var->err & VARIANT_HIDDEN)
+	    {
+	      obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at);
+	      if (contains_dot_or_dash (var->id))
+		obstack_printf (&msg_buf, "[%s]", var->id);
+	      else
+		obstack_sgrow (&msg_buf, var->id);
+	      obstack_sgrow (&msg_buf, tail);
+	    }
+
+	  obstack_printf (&msg_buf, _(" at %s"), at_spec);
+
+	  if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE)
+            {
+              const char *format =
+                _(", cannot be accessed from mid-rule action at $%d");
+              obstack_printf (&msg_buf, format, midrule_rhs_index);
+            }
+
+	  obstack_1grow (&msg_buf, '\0');
+          if (is_warning)
+            warn_at_indent (id_loc, &indent, "%s",
+                            (char *) obstack_finish (&msg_buf));
+          else
+            complain_at_indent (id_loc, &indent, "%s",
+                                (char *) obstack_finish (&msg_buf));
+	  obstack_free (&msg_buf, 0);
+	}
+    }
+}
+
+/* Returned from "parse_ref" when the reference
+   is inappropriate. */
+#define INVALID_REF (INT_MIN)
+
+/* Returned from "parse_ref" when the reference
+   points to LHS ($$) of the current rule or midrule. */
+#define LHS_REF (INT_MIN + 1)
+
+/* Parse named or positional reference. In case of positional
+   references, can return negative values for $-n "deep" stack
+   accesses. */
+static long int
+parse_ref (char *cp, symbol_list *rule, int rule_length,
+	   int midrule_rhs_index, char *text, location text_loc,
+	   char dollar_or_at)
+{
+  symbol_list *l;
+  char *cp_end;
+  bool explicit_bracketing;
+  unsigned i;
+  unsigned valid_variants = 0;
+  unsigned valid_variant_index = 0;
+
+  if ('$' == *cp)
+    return LHS_REF;
+
+  if (c_isdigit (*cp) || (*cp == '-' && c_isdigit (* (cp + 1))))
+    {
+      long int num = strtol (cp, &cp, 10);
+      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
+	return num;
+      else
+	{
+	  complain_at (text_loc, _("integer out of range: %s"),
+                       quote (text));
+	  return INVALID_REF;
+	}
+    }
+
+  if ('[' == *cp)
+    {
+      /* Ignore the brackets. */
+      char *p;
+      for (p = ++cp; *p != ']'; ++p)
+	continue;
+      cp_end = p;
+
+      explicit_bracketing = true;
+    }
+  else
+    {
+      /* Take all characters of the name. */
+      char* p;
+      for (p = cp; *p; ++p)
+	if (is_dot_or_dash (*p))
+	  {
+	    ref_tail_fields = p;
+	    break;
+	  }
+      for (p = cp; *p; ++p)
+	continue;
+      cp_end = p;
+
+      explicit_bracketing = false;
+    }
+
+  /* Add all relevant variants. */
+  {
+    unsigned symbol_index;
+    variant_count = 0;
+    for (symbol_index = 0, l = rule; !symbol_list_null (l);
+         ++symbol_index, l = l->next)
+      {
+	variant *var;
+	if (l->content_type != SYMLIST_SYMBOL)
+	  continue;
+
+	var = variant_add (l->content.sym->tag, l->sym_loc,
+                           symbol_index, cp, cp_end, explicit_bracketing);
+	if (var && l->named_ref)
+	  var->hidden_by = l->named_ref;
+
+	if (l->named_ref)
+	  variant_add (l->named_ref->id, l->named_ref->loc,
+                       symbol_index, cp, cp_end, explicit_bracketing);
+      }
+  }
+
+  /* Check errors. */
+  for (i = 0; i < variant_count; ++i)
+    {
+      variant *var = &variant_table[i];
+      unsigned symbol_index = var->symbol_index;
+
+      /* Check visibility from mid-rule actions. */
+      if (midrule_rhs_index != 0
+	  && (symbol_index == 0 || midrule_rhs_index < symbol_index))
+        var->err |= VARIANT_NOT_VISIBLE_FROM_MIDRULE;
+
+      /* Check correct bracketing. */
+      if (!explicit_bracketing && contains_dot_or_dash (var->id))
+        var->err |= VARIANT_BAD_BRACKETING;
+
+      /* Check using of hidden symbols. */
+      if (var->hidden_by)
+        var->err |= VARIANT_HIDDEN;
+
+      if (!var->err)
+        {
+          valid_variant_index = i;
+          ++valid_variants;
+        }
+    }
+
+  switch (valid_variants)
+    {
+    case 0:
+      {
+        unsigned len = (explicit_bracketing || !ref_tail_fields) ?
+          cp_end - cp : ref_tail_fields - cp;
+        unsigned indent = 0;
+
+        complain_at_indent (text_loc, &indent, _("invalid reference: %s"),
+                            quote (text));
+        indent += SUB_INDENT;
+        if (len == 0)
+          {
+            location sym_loc = text_loc;
+            sym_loc.start.column += 1;
+            sym_loc.end = sym_loc.start;
+            const char *format =
+              _("syntax error after '%c', expecting integer, letter,"
+                " '_', '[', or '$'");
+            complain_at_indent (sym_loc, &indent, format, dollar_or_at);
+          }
+        else if (midrule_rhs_index)
+          {
+            const char *format =
+              _("symbol not found in production before $%d: %.*s");
+            complain_at_indent (rule->location, &indent, format,
+                                midrule_rhs_index, len, cp);
+          }
+        else
+          {
+            const char *format =
+              _("symbol not found in production: %.*s");
+            complain_at_indent (rule->location, &indent, format,
+                                len, cp);
+          }
+
+        if (variant_count > 0)
+          show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
+                             dollar_or_at, false, indent);
+        return INVALID_REF;
+      }
+    case 1:
+      {
+        unsigned indent = 0;
+        if (variant_count > 1)
+          {
+            warn_at_indent (text_loc, &indent, _("misleading reference: %s"),
+                            quote (text));
+            show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
+                               dollar_or_at, true, indent + SUB_INDENT);
+          }
+        {
+          unsigned symbol_index =
+            variant_table[valid_variant_index].symbol_index;
+          return (symbol_index == midrule_rhs_index) ? LHS_REF : symbol_index;
+        }
+      }
+    case 2:
+    default:
+      {
+        unsigned indent = 0;
+        complain_at_indent (text_loc, &indent, _("ambiguous reference: %s"),
+                            quote (text));
+        show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
+                           dollar_or_at, false, indent + SUB_INDENT);
+        return INVALID_REF;
+      }
+    }
+
+  /* Not reachable. */
+  return INVALID_REF;
+}
+
+/* Keeps track of the maximum number of semantic values to the left of
+   a handle (those referenced by $0, $-1, etc.) are required by the
+   semantic actions of this grammar. */
+int max_left_semantic_context = 0;
+
+
+/* If CP points to a typename (i.e., <.*?>), set TYPE_NAME to its
+   beginning (i.e., after the opening "<", and return the pointer
+   immediately after it.  */
+
+static
+char *
+fetch_type_name (char *cp, char const **type_name,
+                 location dollar_loc)
+{
+  if (*cp == '<')
+    {
+      *type_name = ++cp;
+      while (*cp != '>')
+	++cp;
+
+      /* The '>' symbol will be later replaced by '\0'. Original
+	 'text' is needed for error messages. */
+      ++cp;
+      if (untyped_var_seen)
+	complain_at (dollar_loc, _("explicit type given in untyped grammar"));
+      tag_seen = true;
+    }
+  return cp;
+}
+
+/*------------------------------------------------------------------.
+| TEXT is pointing to a wannabee semantic value (i.e., a '$').      |
+|                                                                   |
+| Possible inputs: $[<TYPENAME>]($|integer)                         |
+|                                                                   |
+| Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
+`------------------------------------------------------------------*/
+
+static void
+handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
+{
+  char const *type_name = NULL;
+  char *cp = text + 1;
+  symbol_list *effective_rule;
+  int effective_rule_length;
+  int n;
+
+  if (rule->midrule_parent_rule)
+    {
+      effective_rule = rule->midrule_parent_rule;
+      effective_rule_length = rule->midrule_parent_rhs_index - 1;
+    }
+  else
+    {
+      effective_rule = rule;
+      effective_rule_length = symbol_list_length (rule->next);
+    }
+
+  /* Get the type name if explicit. */
+  cp = fetch_type_name (cp, &type_name, dollar_loc);
+
+  n = parse_ref (cp, effective_rule, effective_rule_length,
+		 rule->midrule_parent_rhs_index, text, dollar_loc, '$');
+
+  /* End type_name. */
+  if (type_name)
+    cp[-1] = '\0';
+
+  switch (n)
+    {
+    case INVALID_REF:
+      break;
+
+    case LHS_REF:
+      if (!type_name)
+	type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
+
+      if (!type_name)
+        {
+          if (union_seen | tag_seen)
+            {
+              if (rule->midrule_parent_rule)
+                complain_at (dollar_loc,
+                             _("$$ for the midrule at $%d of %s"
+                               " has no declared type"),
+                             rule->midrule_parent_rhs_index,
+                             quote (effective_rule->content.sym->tag));
+              else
+                complain_at (dollar_loc, _("$$ of %s has no declared type"),
+                             quote (rule->content.sym->tag));
+            }
+          else
+            untyped_var_seen = true;
+        }
+
+      obstack_sgrow (&obstack_for_string, "]b4_lhs_value(");
+      obstack_quote (&obstack_for_string, type_name);
+      obstack_sgrow (&obstack_for_string, ")[");
+      rule->action_props.is_value_used = true;
+      break;
+
+    default:
+      if (max_left_semantic_context < 1 - n)
+	max_left_semantic_context = 1 - n;
+      if (!type_name && 0 < n)
+	type_name =
+	  symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
+      if (!type_name)
+        {
+          if (union_seen | tag_seen)
+            complain_at (dollar_loc, _("$%s of %s has no declared type"),
+                         cp, quote (effective_rule->content.sym->tag));
+          else
+            untyped_var_seen = true;
+        }
+
+      obstack_printf (&obstack_for_string,
+		      "]b4_rhs_value(%d, %d, ", effective_rule_length, n);
+      obstack_quote (&obstack_for_string, type_name);
+      obstack_sgrow (&obstack_for_string, ")[");
+      if (n > 0)
+	symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
+	  true;
+      break;
+    }
+}
+
+
+/*------------------------------------------------------.
+| TEXT is a location token (i.e., a '@...').  Output to |
+| OBSTACK_FOR_STRING a reference to this location.      |
+`------------------------------------------------------*/
+
+static void
+handle_action_at (symbol_list *rule, char *text, location at_loc)
+{
+  char *cp = text + 1;
+  symbol_list *effective_rule;
+  int effective_rule_length;
+  int n;
+
+  if (rule->midrule_parent_rule)
+    {
+      effective_rule = rule->midrule_parent_rule;
+      effective_rule_length = rule->midrule_parent_rhs_index - 1;
+    }
+  else
+    {
+      effective_rule = rule;
+      effective_rule_length = symbol_list_length (rule->next);
+    }
+
+  locations_flag = true;
+
+  n = parse_ref (cp, effective_rule, effective_rule_length,
+                 rule->midrule_parent_rhs_index, text, at_loc, '@');
+  switch (n)
+    {
+    case INVALID_REF:
+      break;
+
+    case LHS_REF:
+      obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
+      break;
+
+    default:
+      obstack_printf (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
+		      effective_rule_length, n);
+      break;
+    }
+}
+
+
+/*-------------------------.
+| Initialize the scanner.  |
+`-------------------------*/
+
+/* Translate the dollars and ats in \a self, in the context \a sc_context
+   (SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL).  */
+
+static char const *
+translate_action (code_props *self, int sc_context)
+{
+  char *res;
+  static bool initialized = false;
+  if (!initialized)
+    {
+      obstack_init (&obstack_for_string);
+      yy_flex_debug = 0;
+      initialized = true;
+    }
+
+  loc->start = loc->end = self->location.start;
+  yy_switch_to_buffer (yy_scan_string (self->code));
+  res = code_lex (self, sc_context);
+  yy_delete_buffer (YY_CURRENT_BUFFER);
+
+  return res;
+}
+
+/*------------------------------------------------------------------------.
+| Implementation of the public interface as documented in "scan-code.h".  |
+`------------------------------------------------------------------------*/
+
+void
+code_props_none_init (code_props *self)
+{
+  *self = code_props_none;
+}
+
+code_props const code_props_none = CODE_PROPS_NONE_INIT;
+
+void
+code_props_plain_init (code_props *self, char const *code,
+		       location code_loc)
+{
+  self->kind = CODE_PROPS_PLAIN;
+  self->code = code;
+  self->location = code_loc;
+  self->is_value_used = false;
+  self->rule = NULL;
+  self->named_ref = NULL;
+}
+
+void
+code_props_symbol_action_init (code_props *self, char const *code,
+                               location code_loc)
+{
+  self->kind = CODE_PROPS_SYMBOL_ACTION;
+  self->code = code;
+  self->location = code_loc;
+  self->is_value_used = false;
+  self->rule = NULL;
+  self->named_ref = NULL;
+}
+
+void
+code_props_rule_action_init (code_props *self, char const *code,
+                             location code_loc, symbol_list *rule,
+			     named_ref *name)
+{
+  self->kind = CODE_PROPS_RULE_ACTION;
+  self->code = code;
+  self->location = code_loc;
+  self->is_value_used = false;
+  self->rule = rule;
+  self->named_ref = name;
+}
+
+void
+code_props_translate_code (code_props *self)
+{
+  switch (self->kind)
+    {
+      case CODE_PROPS_NONE:
+        break;
+      case CODE_PROPS_PLAIN:
+        self->code = translate_action (self, INITIAL);
+        break;
+      case CODE_PROPS_SYMBOL_ACTION:
+        self->code = translate_action (self, SC_SYMBOL_ACTION);
+        break;
+      case CODE_PROPS_RULE_ACTION:
+        self->code = translate_action (self, SC_RULE_ACTION);
+        break;
+    }
+}
+
+void
+code_scanner_last_string_free (void)
+{
+  STRING_FREE;
+}
+
+void
+code_scanner_free (void)
+{
+  obstack_free (&obstack_for_string, 0);
+  variant_table_free ();
+
+  /* Reclaim Flex's buffers.  */
+  yylex_destroy ();
+}
diff --git a/src/scan-gram-c.c b/src/scan-gram-c.c
index 8f12e2c..6bacac6 100644
--- a/src/scan-gram-c.c
+++ b/src/scan-gram-c.c
@@ -1,2 +1,3 @@
 #include <config.h>
+#include "system.h"
 #include "scan-gram.c"
diff --git a/src/scan-gram.c b/src/scan-gram.c
index 04cf539..41d99a5 100644
--- a/src/scan-gram.c
+++ b/src/scan-gram.c
@@ -6,10 +6,37 @@
 
 /* A lexical scanner generated by flex */
 
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+#define yy_create_buffer gram__create_buffer
+#define yy_delete_buffer gram__delete_buffer
+#define yy_flex_debug gram__flex_debug
+#define yy_init_buffer gram__init_buffer
+#define yy_flush_buffer gram__flush_buffer
+#define yy_load_buffer_state gram__load_buffer_state
+#define yy_switch_to_buffer gram__switch_to_buffer
+#define yyin gram_in
+#define yyleng gram_leng
+#define yylex gram_lex
+#define yylineno gram_lineno
+#define yyout gram_out
+#define yyrestart gram_restart
+#define yytext gram_text
+#define yywrap gram_wrap
+#define yyalloc gram_alloc
+#define yyrealloc gram_realloc
+#define yyfree gram_free
+
+/* %endif */
+/* %endif */
+/* %ok-for-header */
+
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
+#define YY_FLEX_SUBMINOR_VERSION 37
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -47,7 +74,15 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
 #include <inttypes.h>
 typedef int8_t flex_int8_t;
 typedef uint8_t flex_uint8_t;
@@ -62,7 +97,6 @@
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -93,6 +127,8 @@
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#endif /* ! C99 */
+
 #endif /* ! FLEXINT_H */
 
 /* %endif */
@@ -107,11 +143,12 @@
 
 #else	/* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif	/* __STDC__ */
+#endif	/* defined (__STDC__) */
 #endif	/* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -169,13 +206,22 @@
 #define YY_BUF_SIZE 16384
 #endif
 
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
 #define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
 /* %if-not-reentrant */
-extern int gram_leng;
+extern yy_size_t gram_leng;
 /* %endif */
 
 /* %if-c-only */
@@ -206,16 +252,6 @@
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -238,7 +274,7 @@
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -322,12 +358,12 @@
 
 /* yy_hold_char holds the character lost when gram_text is formed. */
 static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int gram_leng;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t gram_leng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1;		/* whether we need to initialize */
+static int yy_init = 0;		/* whether we need to initialize */
 static int yy_start = 0;	/* start state number */
 
 /* Flag which is used to allow gram_wrap()'s to do buffer switches
@@ -354,7 +390,7 @@
 
 YY_BUFFER_STATE gram__scan_buffer (char *base,yy_size_t size  );
 YY_BUFFER_STATE gram__scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE gram__scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE gram__scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 /* %endif */
 
@@ -389,7 +425,7 @@
 /* %% [1.0] gram_text/gram_in/gram_out/yy_state_type/gram_lineno etc. def's & init go here */
 /* Begin user sect3 */
 
-#define gram_wrap(n) 1
+#define gram_wrap() 1
 #define YY_SKIP_YYWRAP
 
 #define FLEX_DEBUG
@@ -438,58 +474,61 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[461] =
+static yyconst flex_int16_t yy_accept[482] =
     {   0,
-        0,    0,    0,    0,   66,   66,    0,    0,   84,   84,
-       84,   84,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  110,   59,    2,    2,
-       54,   59,   53,    1,   50,   59,   51,   51,   49,   59,
-       47,   56,   48,   59,  107,  108,  103,  107,  104,  105,
-      106,   65,  107,   63,   63,   88,   87,  107,   86,   85,
-       61,    2,    1,   61,   60,   61,   68,   67,  107,   71,
-       70,   69,   93,    2,    1,   93,   93,   90,  100,  107,
-       89,  107,  107,  101,   94,   96,  107,   58,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   77,   77,
+       93,   93,   93,   93,    0,    0,    0,    0,  110,   65,
+        2,    2,   59,   65,   58,   65,    1,   54,   65,   55,
+       55,   51,   65,   49,   54,   64,   61,   50,   65,   74,
+       74,  107,   78,   78,  107,   80,   79,   79,   68,    2,
+        1,   68,   67,   66,   68,  108,   99,  107,   98,  107,
+      107,  107,  102,  104,  107,   76,  107,   97,   96,  107,
+       95,   94,   71,    2,    1,   69,   71,   71,   70,   71,
+       72,    2,    1,   72,   72,   65,    0,   63,   48,   48,
 
-       46,   46,   46,   46,   46,   46,   55,   50,    4,    3,
-       51,    0,    0,    0,   64,    0,    0,   66,   62,   84,
-       84,   84,   84,   83,   81,   72,   83,   74,   75,   76,
-       77,   78,   79,   83,   80,   83,   98,    0,   98,    0,
-       95,    0,   91,   92,    0,   94,   97,    0,   99,    0,
-       99,  102,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,    3,   52,   57,    0,    0,    0,    0,    0,    0,
-        0,    0,   72,    0,    0,   73,    0,    0,    0,    0,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   60,   54,   54,
+        4,    3,   57,   55,   57,    0,    0,   53,    0,   73,
+       92,   90,   81,   92,   83,   84,   85,   86,   87,   88,
+       92,   89,   92,  106,  100,  101,    0,  103,    0,  102,
+      105,    0,   75,    0,    0,   77,   93,   93,   93,   93,
+       71,   69,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,    3,   57,   56,   62,   52,    0,
 
-        0,    0,    0,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,    0,   72,    0,
-        0,    0,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   20,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   32,   46,   46,   46,
-       46,   46,   46,   39,   46,   42,   46,   46,   45,    0,
-        0,    0,   46,    7,   46,   46,   46,   12,   46,   46,
-       46,   46,   46,   46,   46,   46,   23,   46,   46,   46,
+       81,    0,    0,   82,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,    0,   81,    0,    0,   48,    7,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   22,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   34,   48,   48,   48,   48,   48,   48,
+       41,   48,   44,   48,   48,   47,    0,    0,    0,   48,
 
-       46,   46,   29,   46,   46,   46,   46,   46,   36,   46,
-       38,   40,   43,   46,    0,    0,   82,    6,   46,    9,
-       46,   46,   14,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   30,   46,   46,   46,   46,   46,
-       46,   46,    0,   46,   10,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       33,   46,   35,   46,   46,   44,    0,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   26,
-       27,   46,   46,   46,   37,   46,    0,   46,   46,   46,
-       15,   46,   46,   46,   46,   21,   22,   46,   46,   46,
+        8,   48,   48,   48,   13,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   25,   48,   48,   48,   48,   48,
+       31,   48,   48,   48,   48,   48,   38,   48,   40,   42,
+       45,   48,    0,    0,   91,    6,   48,   10,   48,   48,
+       15,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   32,   48,   48,   48,   48,   48,   48,
+       48,    0,   48,   11,   48,   48,   48,   48,   48,   48,
+       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
+       35,   48,   37,   48,   48,   46,    5,    0,   48,   48,
+       48,   48,   48,   48,   48,   48,   21,   48,   48,   48,
 
-       46,   46,   46,    0,    0,   46,   11,   46,   46,   46,
-       19,   46,   46,   46,   46,   46,   46,   46,    5,   46,
-       46,   16,   46,   46,   24,   46,   46,   31,   34,   41,
-        8,   46,   46,   46,   46,   46,   13,   46,   46,   46,
-       46,   46,   18,   46,   46,   46,   25,   46,   46,   46,
-       46,   46,   17,   46,   46,   46,   46,   46,   28,    0
+       48,   28,   29,   48,   48,   48,   39,   48,    0,   48,
+       48,   48,   16,   48,   48,   48,   48,   23,   24,   48,
+       48,   48,   48,   48,   48,    0,    0,   48,   12,   48,
+       48,   48,   20,   48,   48,   48,   48,   48,   48,   48,
+       48,   48,   17,   48,   48,   26,   48,   48,   33,   36,
+       43,    9,   48,   48,   48,   48,   48,   14,   48,   48,
+       48,   48,   48,   19,   48,   48,   48,   27,   48,   48,
+       48,   48,   48,   18,   48,   48,   48,   48,   48,   30,
+        0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -497,17 +536,17 @@
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         2,    2,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    4,    1,    5,    6,    7,    8,    1,    9,    1,
-        1,   10,    1,   11,   12,   13,   14,   15,   16,   16,
+        1,    4,    5,    6,    7,    5,    8,    5,    9,    5,
+        5,   10,    5,   11,   12,   13,   14,   15,   16,   16,
        16,   16,   16,   16,   16,   17,   17,   18,   19,   20,
-       21,   22,   23,   24,   25,   25,   25,   25,   25,   25,
-       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
-       13,   13,   13,   13,   26,   13,   13,   27,   13,   13,
-       28,   29,   30,    1,   31,    1,   32,   33,   34,   35,
+       21,   22,   23,    5,   24,   24,   24,   24,   24,   24,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
+       25,   25,   25,   25,   26,   25,   25,   27,   25,   25,
+       28,   29,   30,    5,   31,    5,   32,   33,   34,   35,
 
-       36,   37,   38,   39,   40,   13,   41,   42,   43,   44,
-       45,   46,   47,   48,   49,   50,   51,   52,   13,   53,
-       54,   13,   55,   56,   57,    1,    1,    1,    1,    1,
+       36,   37,   38,   39,   40,   25,   41,   42,   43,   44,
+       45,   46,   47,   48,   49,   50,   51,   52,   25,   53,
+       54,   25,   55,   56,   57,    5,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -526,310 +565,352 @@
 
 static yyconst flex_int32_t yy_meta[59] =
     {   0,
-        1,    1,    2,    1,    1,    1,    3,    1,    1,    1,
-        1,    4,    5,    1,    6,    6,    6,    1,    1,    1,
-        1,    7,    1,    3,    6,    5,    5,    3,    1,    3,
-        5,    6,    6,    6,    6,    6,    6,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,    1,    1,    1,    7
+        1,    2,    3,    2,    4,    5,    4,    5,    5,    5,
+        5,    6,    7,    8,    9,    9,    9,    4,    5,    5,
+        5,    5,    4,    9,   10,   10,   10,   11,    4,   12,
+       10,    9,    9,    9,    9,    9,    9,   10,   10,   10,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+       10,   10,   10,   10,    5,    5,    5,   13
     } ;
 
-static yyconst flex_int16_t yy_base[483] =
+static yyconst flex_int16_t yy_base[508] =
     {   0,
-        0,  733,   56,   57,   65,   68,  728,  727,   96,   99,
-      106,  109,  138,  144,   85,  102,  142,  150,  161,  174,
-      206,    0,  162,  182,  220,  225,  736,  740,  740,  740,
-      740,  275,  740,  740,    0,   51,  176,   61,  740,    0,
-      740,  740,  740,  693,  740,  740,  740,  103,  740,  740,
-      740,  740,  164,  740,  720,  740,  740,  192,  740,  740,
-      740,  740,  740,   59,  740,  691,  740,  740,  326,  740,
-      740,  740,  740,  740,  740,   60,  690,  740,  231,  132,
-      740,  187,   71,  243,  740,  740,  674,  740,    0,  690,
-       75,  151,  689,  686,  683,   74,  690,  173,  674,  220,
+        0,  899,  895,  894,   56,   57,   58,   61,   70,   89,
+       96,  115,  119,  128,   62,  129,   72,   91,   66,   77,
+      138,  143,   80,  142,  185,  896,  150,  155,  902,    0,
+      907,  907,  907,  243,  907,  907,  907,  301,   98,  288,
+       62,  907,  146,  907,  315,  907,  907,  907,  859,  907,
+      886,  907,  907,  907,  368,  907,  907,  907,  907,  907,
+      907,  116,  907,  907,  857,  907,  907,  841,  907,  297,
+       91,  155,  907,  907,  126,  907,  175,  907,  907,  325,
+      907,  907,    0,  907,    0,    0,  307,  907,  907,  855,
+      907,  907,  907,  322,  854,    0,    0,  907,    0,  855,
 
-      147,  157,  220,  680,  687,  690,  740,    0,  740,    0,
-      269,    0,  699,  680,  740,  287,  290,  690,  740,  740,
-      293,  689,  301,  740,  740,   67,    0,  740,  740,  740,
-      740,  740,  740,    0,  740,    0,  740,  317,  321,    0,
-      740,  341,  740,  740,  344,  740,  740,  358,  740,  349,
-      352,  740,    0,  673,  220,  668,  667,  668,  131,  665,
-      672,  188,  677,  662,  666,  223,  672,  657,  658,  226,
-      657,  657,  665,  666,  669,  652,  658,  652,  657,  648,
-      661,    0,    0,  740,  650,  369,  250,  378,  381,  384,
-      387,  269,  324,    0,    0,    0,  671,  390,  152,  393,
+      849,  114,  117,  853,  850,  847,  303,  854,  302,  838,
+      305,  306,  132,  304,  844,  851,  854,  907,  421,    0,
+      907,    0,    0,  345,  465,  863,  862,  907,  843,  907,
+      907,  907,  165,    0,  907,  907,  907,  907,  907,  907,
+        0,  907,    0,  907,  907,  907,  361,  907,  364,  907,
+      907,  367,  907,  376,  383,  853,  907,  386,  852,  400,
+        0,    0,    0,    0,  836,  844,  359,  830,  829,  830,
+      270,  827,  834,  829,  272,  838,  823,  827,  383,  833,
+      818,  819,  315,  818,  818,  826,  827,  830,  813,  819,
+      813,  818,  809,  822,    0,    0,    0,  907,  907,  811,
 
-      388,  397,  202,  660,  640,  238,  640,  653,  643,  651,
-      650,  649,  672,  633,  632,  669,  648,  641,  642,  315,
-      241,  629,  630,  626,  640,  629,  636,  620,  631,  627,
-      620,  624,  630,  629,  619,  630,  628,  625,  740,    0,
-        0,  396,  612,  621,  607,  613,  608,  621,  606,  619,
-      640,  616,  604,  609,    0,  602,  597,  610,  344,  609,
-      604,  594,  606,  598,  589,  603,    0,  588,  392,  597,
-      586,  599,  584,    0,  589,    0,  588,  586,    0,  626,
-        0,    0,  575,    0,  586,  591,  575,    0,  393,  575,
-      578,  394,  591,  590,  589,  580,    0,  573,  581,  573,
+      360,    0,    0,    0,  407,  403,  421,  321,  427,  427,
+      434,  343,  438,  450,  455,  458,  378,  822,  817,  801,
+      278,  801,  814,  804,  812,  811,  810,  833,  794,  805,
+      792,  829,  808,  801,  802,  364,  411,  789,  790,  786,
+      800,  789,  796,  780,  791,  787,  780,  784,  790,  789,
+      779,  790,  788,  785,  907,    0,    0,  772,    0,  781,
+      767,  773,  768,  781,  766,  779,  800,  776,  764,  769,
+      757,    0,  761,  756,  769,  433,  768,  763,  753,  765,
+      757,  748,  762,    0,  747,  436,  756,  745,  758,  743,
+        0,  748,    0,  747,  745,    0,  785,    0,    0,  734,
 
-      567,  565,    0,  564,  601,  576,  565,  562,    0,  559,
-        0,  395,    0,  559,  399,    0,  740,    0,  557,  557,
-      571,  552,  397,  555,  557,  553,  558,  551,  553,  549,
-      564,  559,  549,  557,    0,  546,  543,  558,  553,  543,
-      537,  550,  414,  407,    0,  535,  548,  535,  546,  530,
-      531,  567,  546,  533,  540,  524,  525,  539,  524,  539,
-        0,  522,    0,  525,  536,    0,  562,  520,  520,  516,
-      515,  525,  511,  524,  527,  515,  508,  519,  513,    0,
-        0,  511,  505,  503,    0,  518,  545,  501,  500,  514,
-        0,  506,  499,  496,  509,    0,    0,  502,  491,  500,
+        0,  745,  750,  734,    0,  437,  734,  737,  443,  750,
+      749,  748,  747,  738,    0,  731,  739,  731,  725,  723,
+        0,  722,  759,  734,  723,  720,    0,  717,    0,  453,
+        0,  717,  454,    0,  907,    0,  715,  715,  729,  710,
+      454,  713,  715,  711,  716,  719,  708,  710,  706,  721,
+      716,  706,  714,    0,  703,  700,  715,  710,  700,  694,
+      707,  488,  463,    0,  692,  705,  692,  703,  687,  688,
+      724,  699,  702,  689,  696,  680,  681,  695,  680,  695,
+        0,  678,    0,  681,  692,    0,  907,  717,  676,  676,
+      672,  671,  681,  667,  680,  683,    0,  671,  664,  675,
 
-      507,  502,  495,  531,  348,  499,    0,  489,  480,  481,
-        0,  481,  477,  408,  485,  485,  479,  490,  740,  491,
-      475,    0,  473,  482,    0,  475,  480,    0,    0,    0,
-        0,  483,  409,  473,  469,  467,    0,  478,  470,  472,
-      452,  455,    0,  445,  432,  395,    0,  402,  399,  422,
-      384,  386,    0,  395,  374,  361,  318,  251,    0,  740,
-      440,  447,  454,  461,  464,  470,  476,  483,  487,  493,
-      281,  275,  236,  218,  500,  206,  151,  138,  116,  102,
-       56,  506
+      669,    0,    0,  667,  661,  659,    0,  674,  700,  657,
+      656,  670,    0,  662,  655,  652,  665,    0,    0,  658,
+      647,  656,  663,  658,  651,  686,  470,  655,    0,  645,
+      626,  623,    0,  611,  603,  465,  598,  595,  588,  599,
+      600,  584,    0,  579,  588,    0,  579,  584,    0,    0,
+        0,    0,  555,  475,  541,  534,  530,    0,  539,  530,
+      537,  519,  528,    0,  533,  526,  521,    0,  527,  524,
+      483,  444,  444,    0,  456,  438,  434,  442,  424,    0,
+      907,  506,  519,  532,  545,  558,  571,  578,  588,  600,
+      613,  626,  634,  641,  648,  658,  666,  454,  406,  389,
+
+      384,  373,  138,  102,   88,   57,  676
     } ;
 
-static yyconst flex_int16_t yy_def[483] =
+static yyconst flex_int16_t yy_def[508] =
     {   0,
-      460,    1,  461,  461,  461,  461,  462,  462,  461,  461,
-      461,  461,  463,  463,  461,  461,  461,  461,  464,  464,
-      461,   21,   21,   21,   21,   21,  460,  460,  460,  460,
-      460,  460,  460,  460,  465,  460,  460,  460,  460,  466,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  467,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  468,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
+      481,    1,  482,  482,  483,  483,  483,  483,  484,  484,
+      483,  483,  483,  483,  483,  483,  483,  483,  483,  483,
+      483,  483,  483,  483,  481,   25,  485,  485,  481,  486,
+      481,  481,  481,  481,  481,  481,  481,  487,  481,  488,
+      488,  481,  489,  481,  487,  481,  481,  481,  486,  481,
+      481,  481,  481,  481,  490,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  491,
+      481,  481,  492,  481,  492,  493,  481,  481,  481,  492,
+      481,  481,  481,  481,  481,  486,  494,  481,  495,  495,
 
-      469,  469,  469,  469,  469,  469,  460,  465,  460,  470,
-      460,  471,  466,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  472,  460,  460,  460,
-      460,  460,  460,  473,  460,  474,  460,  460,  460,  475,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  470,  471,  460,  460,  460,  460,  460,  460,  460,
-      460,  467,  460,  476,  477,  474,  475,  460,  460,  460,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  481,  487,   45,
+      481,  496,  497,  488,  497,  489,  489,  481,  481,  481,
+      481,  481,  481,  498,  481,  481,  481,  481,  481,  481,
+      499,  481,  500,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      492,  493,  494,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  496,  497,  125,  481,  481,  481,
 
-      460,  460,  460,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  460,  460,  478,
-      479,  460,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  460,
-      480,  481,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
+      481,  501,  502,  500,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  491,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  481,  481,  503,  504,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  481,  505,  506,  495,
 
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  460,  473,  460,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  460,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  460,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  482,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  481,  499,  481,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  481,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  481,  481,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
 
-      469,  469,  469,  482,  482,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  460,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,  469,
-      469,  469,  469,  469,  469,  469,  469,  469,  469,    0,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460
+      495,  495,  495,  495,  495,  495,  495,  495,  507,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  507,  507,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  495,  495,  495,  495,
+        0,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+
+      481,  481,  481,  481,  481,  481,  481
     } ;
 
-static yyconst flex_int16_t yy_nxt[799] =
+static yyconst flex_int16_t yy_nxt[966] =
     {   0,
-       28,   29,   30,   29,   31,   28,   28,   32,   33,   28,
-       34,   28,   35,   36,   37,   38,   38,   28,   39,   40,
-       41,   28,   28,   28,   35,   35,   35,   28,   28,   28,
-       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
-       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
-       35,   35,   35,   35,   42,   43,   28,   28,   46,   46,
-      109,  317,   47,   47,  110,   48,   48,   52,  109,  109,
-       52,   47,  110,  110,   47,  111,  111,  111,  146,   49,
-       49,  193,  193,   50,   50,   51,   51,   67,   49,   68,
-      147,   49,   50,   53,   51,   50,   53,   51,   56,  148,
+       30,   31,   32,   31,   30,   33,   30,   34,   35,   36,
+       37,   30,   38,   39,   40,   41,   41,   30,   42,   43,
+       44,   36,   30,   45,   45,   45,   45,   46,   30,   30,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
+       45,   45,   45,   45,   47,   48,   36,   30,   53,   53,
+       57,   54,   54,   57,   66,  335,   58,   67,   76,   58,
+       69,   60,   32,   60,   66,   70,  124,  124,  124,   76,
+       61,   75,   81,   62,   55,   55,   55,   63,   82,   55,
+       60,   32,   60,   66,   77,   65,  334,   64,   66,   61,
 
-       57,   56,   47,   57,   67,   47,   68,  316,   59,  162,
-      155,   59,   47,   69,   60,   47,  115,   60,  163,   49,
-      156,  282,   49,   50,   58,   51,   50,   58,   51,   49,
-       69,  116,   49,   50,   58,   51,   50,   58,   51,   62,
-       30,   62,   70,  281,   71,   62,   30,   62,   63,   66,
-       72,   64,   71,  141,   63,   65,  241,   64,   72,   70,
-      142,   65,   74,   30,   74,  117,  118,  117,   47,   87,
-       69,   75,  211,  141,   76,   74,   30,   74,   69,   77,
-      142,   45,  172,  212,   75,   49,  173,   76,   47,   87,
-      111,  111,  111,  121,  122,  121,  143,  174,  157,   70,
+       75,   67,   62,   68,   69,   77,   63,  121,   80,   70,
+      299,  122,  148,   56,   56,   56,   64,   66,   56,  149,
+       67,   66,   68,   69,   67,  121,   71,   69,   70,  122,
+       66,   66,   70,   67,   67,   71,   69,   69,   72,  153,
+       78,   70,   70,   79,   81,   78,  298,   72,   79,  167,
+       82,   92,   32,   92,  154,  127,   92,   32,   92,  168,
+       93,   95,  150,   94,  169,   93,   80,  128,   94,  170,
+       80,   80,  187,   73,  151,   74,  155,  156,  155,  201,
+      201,  188,   73,  152,   74,   83,   84,   32,   84,   83,
+       83,   83,   83,   83,   83,   85,   83,   86,   87,   88,
 
-      144,   45,  112,  158,  165,   49,  175,   70,   46,  146,
-       78,  240,   79,   80,   81,  145,   45,  166,   45,   82,
-      123,  147,  167,  196,  215,   83,   47,   45,  112,   84,
-      148,   47,   45,   50,  220,   51,   45,  137,   45,   45,
-      216,  195,  138,   49,   45,  139,  139,  139,   49,  149,
-      140,  169,  205,  220,  150,  176,  206,  151,  151,  151,
-       85,  225,   86,  115,  177,  226,  221,  170,  207,  245,
-      171,  460,  262,  178,   45,  263,   45,  246,  116,   45,
-      194,   45,   88,  111,  111,  111,  183,   89,  186,  187,
-      186,  117,  118,  117,  189,  122,  189,  123,  459,   89,
+       88,   88,   83,   83,   83,   83,   83,   83,   86,   86,
+       86,   86,   83,   83,   89,   86,   86,   86,   86,   86,
+       86,   86,   86,   86,   86,   86,   86,   86,   86,   86,
+       86,   86,   86,   86,   86,   86,   86,   86,   86,   83,
+       83,   83,   83,   97,   97,   97,   97,   97,   97,   97,
+       98,   97,   97,   97,   97,   99,   97,   97,   97,   97,
+       97,   97,   97,   97,   97,   97,   99,   99,   99,   99,
+       97,   97,   97,   99,   99,  100,  101,  102,  103,  104,
+      105,   99,  106,   99,  107,  108,  109,  110,  111,   99,
+      112,  113,  114,  115,  116,   99,  117,  118,   97,   97,
 
-       89,   89,  191,  192,  191,   89,   89,   90,   89,   91,
-       92,   93,   94,   89,   95,   89,   96,   97,   98,   99,
-      100,   89,  101,  102,  103,  104,  105,   89,  106,  107,
-      125,  139,  139,  139,  125,  139,  139,  139,  239,  239,
-      126,  126,  198,  199,  198,  200,  201,  200,  125,  260,
-      419,  127,  405,  458,  125,  298,  261,  128,  129,  202,
-      203,  202,  130,  151,  151,  151,  151,  151,  151,  131,
-      186,  187,  186,  132,  298,  133,  134,  135,  136,  117,
-      118,  117,  189,  122,  189,  189,  122,  189,  191,  192,
-      191,  198,  199,  198,  200,  201,  200,  143,  202,  203,
+       97,   96,  124,  124,  124,   96,  145,   96,  231,  261,
+      146,  226,  119,  119,  125,  481,  121,  262,   96,  481,
+      122,  481,  227,   96,  232,  147,  158,  159,  158,   96,
+       96,  121,  481,  178,  174,  122,  182,  481,  175,  189,
+      125,  185,  148,  481,  481,  186,  179,  176,  190,  149,
+      241,  180,  183,  160,  242,  184,  153,  191,   96,  124,
+      124,  124,  205,  206,  205,  207,  208,  207,  209,  210,
+      209,  154,  481,  132,  255,  255,  132,  211,  212,  211,
+      481,  257,  133,  133,  155,  156,  155,  214,  159,  214,
+      132,  220,  256,  134,  236,  221,  132,  204,  277,  135,
 
-      202,  144,  137,  307,  322,  325,  341,  138,  348,  457,
-      139,  139,  139,  343,  343,  343,  145,  367,  368,  426,
-      438,  456,  307,  322,  325,  341,  455,  348,  343,  343,
-      343,  454,  453,  452,  451,  450,  449,  368,  426,  438,
-       45,   45,   45,   45,   45,   45,   45,   54,   54,   54,
-       54,   54,   54,   54,   61,   61,   61,   61,   61,   61,
-       61,   73,   73,   73,   73,   73,   73,   73,  108,  108,
-      113,  448,  113,  113,  113,  113,  120,  120,  447,  120,
-      120,  120,  120,  124,  124,  124,  124,  124,  124,  124,
-      153,  153,  153,  182,  446,  182,  182,  182,  182,  182,
+      136,  216,  217,  216,  137,  278,  160,  222,  205,  206,
+      205,  138,  145,  236,  203,  139,  146,  140,  141,  142,
+      143,   96,  207,  208,  207,   96,  237,   96,  209,  210,
+      209,  147,  119,  119,  150,  211,  212,  211,   96,  155,
+      156,  155,  279,   96,  316,  280,  151,  325,  340,   96,
+       96,  214,  159,  214,  343,  152,  214,  159,  214,  216,
+      217,  216,  202,  316,  360,  367,  325,  340,  362,  362,
+      362,  480,  387,  343,  389,  427,  447,  479,   96,  197,
+      197,  197,  478,  360,  367,  477,  459,  476,  197,  475,
+      387,  388,  474,  389,  473,  447,  197,  197,  197,  197,
 
-      197,  445,  197,  197,  197,  197,  404,  444,  404,  404,
-      404,  404,  404,  443,  442,  441,  440,  439,  437,  436,
-      435,  434,  433,  432,  431,  430,  429,  428,  427,  425,
-      424,  423,  422,  421,  420,  405,  418,  417,  416,  415,
-      414,  413,  412,  411,  410,  409,  408,  407,  406,  405,
-      403,  402,  401,  400,  399,  398,  397,  396,  395,  394,
-      393,  392,  391,  390,  389,  388,  387,  386,  385,  384,
-      383,  382,  381,  380,  379,  378,  377,  376,  375,  374,
-      373,  372,  371,  370,  369,  366,  365,  364,  363,  362,
-      361,  360,  359,  358,  357,  356,  355,  354,  353,  352,
+      197,  197,  362,  362,  362,  459,   50,   50,   50,   50,
+       50,   50,   50,   50,   50,   50,   50,   50,   50,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   59,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   91,   91,   91,   91,   91,
+       91,   91,   91,   91,   91,   91,   91,   91,   96,  472,
+      471,   96,  470,   96,   96,  469,  468,  467,  466,   96,
+       96,  120,  465,  464,  120,  463,  120,  120,  462,  120,
+      120,  461,  120,  120,  123,  460,  123,  123,  126,  126,
+      458,  126,  126,  126,  126,  126,  126,  126,  126,  126,
 
-      351,  350,  349,  347,  346,  345,  344,  342,  340,  339,
-      338,  337,  336,  335,  334,  333,  332,  331,  330,  329,
-      328,  327,  326,  324,  323,  321,  320,  319,  318,  315,
-      314,  313,  312,  311,  310,  309,  308,  306,  305,  304,
-      303,  302,  301,  300,  299,  297,  296,  295,  294,  293,
-      292,  291,  290,  289,  288,  287,  286,  285,  284,  283,
-      280,  279,  278,  277,  276,  275,  274,  273,  272,  271,
-      270,  269,  268,  267,  266,  265,  264,  259,  258,  257,
-      256,  255,  254,  253,  252,  251,  250,  249,  248,  247,
-      244,  243,  242,  238,  237,  236,  235,  234,  233,  232,
+      131,  131,  131,  131,  131,  131,  131,  131,  131,  131,
+      131,  131,  131,  157,  157,  157,  157,  157,  157,  157,
+      157,  157,  157,  457,  456,  157,  161,  455,  454,  161,
+      161,  161,  453,  452,  451,  450,  161,  449,  161,  162,
+      162,  448,  162,  162,  163,  163,  163,  163,  163,  163,
+      163,  163,  163,  164,  164,  446,  164,  164,  195,  195,
+      445,  195,  195,  195,  195,  195,  195,  195,  195,  195,
+      195,  196,  196,  444,  196,  196,  426,  426,  443,  426,
+      426,  426,  426,  426,  426,  426,  426,  426,  426,  442,
+      441,  427,  440,  439,  438,  437,  436,  435,  434,  433,
 
-      231,  230,  229,  228,  227,  224,  223,  222,  219,  218,
-      217,  214,  213,  210,  209,  208,  204,  190,  188,  185,
-      184,  181,  180,  179,  168,  164,  161,  160,  159,  154,
-      152,  114,  114,  119,  114,  460,   55,   55,   44,   27,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460
+      432,  431,  430,  429,  428,  427,  425,  424,  423,  422,
+      421,  420,  419,  418,  417,  416,  415,  414,  413,  412,
+      411,  410,  409,  408,  407,  406,  405,  404,  403,  402,
+      401,  400,  399,  398,  397,  396,  395,  394,  393,  392,
+      391,  390,  386,  385,  384,  383,  382,  381,  380,  379,
+      378,  377,  376,  375,  374,  373,  372,  371,  370,  369,
+      368,  366,  365,  364,  363,  361,  359,  358,  357,  356,
+      355,  354,  353,  352,  351,  350,  349,  348,  347,  346,
+      345,  344,  342,  341,  339,  338,  337,  336,  333,  332,
+      331,  330,  329,  328,  327,  326,  324,  323,  322,  321,
 
+      320,  319,  318,  317,  315,  314,  313,  312,  311,  310,
+      309,  308,  307,  306,  305,  304,  303,  302,  301,  300,
+      297,  296,  295,  294,  293,  292,  291,  290,  289,  288,
+      287,  286,  285,  284,  283,  282,  281,  276,  275,  274,
+      273,  272,  271,  270,  269,  268,  267,  266,  265,  264,
+      263,  260,  259,  258,  254,  253,  252,  251,  250,  249,
+      248,  247,  246,  245,  244,  243,  240,  239,  238,  235,
+      234,  233,  230,  229,  228,  225,  224,  223,  219,  218,
+      215,  213,  200,  199,  198,  194,  193,  192,  181,  177,
+      173,  172,  171,  166,  165,  129,  129,  144,  129,  130,
+
+      129,  481,   90,   51,   51,   49,   29,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481
     } ;
 
-static yyconst flex_int16_t yy_chk[799] =
+static yyconst flex_int16_t yy_chk[966] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    3,    4,
-       36,  481,    3,    4,   36,    3,    4,    5,   64,   76,
-        6,    5,   64,   76,    6,   38,   38,   38,   83,    3,
-        4,  126,  126,    3,    4,    3,    4,   15,    5,   15,
-       83,    6,    5,    5,    5,    6,    6,    6,    9,   83,
+        1,    1,    1,    1,    1,    1,    1,    1,    5,    6,
+        7,    5,    6,    8,   15,  506,    7,   15,   19,    8,
+       15,    9,    9,    9,   17,   15,   41,   41,   41,   20,
+        9,   17,   23,    9,    5,    6,    7,    9,   23,    8,
+       10,   10,   10,   18,   19,   10,  505,    9,   11,   10,
 
-        9,   10,    9,   10,   16,   10,   16,  480,   11,   96,
-       91,   12,   11,   15,   11,   12,   48,   12,   96,    9,
-       91,  479,   10,    9,    9,    9,   10,   10,   10,   11,
-       16,   48,   12,   11,   11,   11,   12,   12,   12,   13,
-       13,   13,   15,  478,   17,   14,   14,   14,   13,   14,
-       17,   13,   18,   80,   14,   13,  477,   14,   18,   16,
-       80,   14,   19,   19,   19,   53,   53,   53,   23,   23,
-       17,   19,  159,  199,   19,   20,   20,   20,   18,   20,
-      199,   23,  101,  159,   20,   23,  101,   20,   24,   24,
-       37,   37,   37,   58,   58,   58,   82,  102,   92,   17,
+       18,   11,   10,   11,   11,   20,   10,   39,   23,   11,
+      504,   39,   71,    5,    6,    7,   10,   12,    8,   71,
+       12,   13,   12,   12,   13,   62,   13,   13,   12,   62,
+       14,   16,   13,   14,   16,   14,   14,   16,   13,   75,
+       21,   14,   16,   21,   24,   22,  503,   14,   22,  102,
+       24,   27,   27,   27,   75,   43,   28,   28,   28,  102,
+       27,   28,   72,   27,  103,   28,   21,   43,   28,  103,
+       24,   22,  113,   13,   72,   13,   77,   77,   77,  133,
+      133,  113,   14,   72,   14,   25,   25,   25,   25,   25,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
 
-       82,   24,   37,   92,   98,   24,  102,   18,   21,  203,
-       21,  476,   21,   21,   21,   82,   23,   98,   23,   21,
-       58,  203,   98,  474,  162,   21,   25,   25,   37,   21,
-      203,   26,   26,   21,  166,   21,   24,   79,   24,   25,
-      162,  473,   79,   25,   26,   79,   79,   79,   26,   84,
-       79,  100,  155,  166,   84,  103,  155,   84,   84,   84,
-       21,  170,   21,  187,  103,  170,  166,  100,  155,  206,
-      100,  192,  221,  103,   25,  221,   25,  206,  187,   26,
-      472,   26,   32,  111,  111,  111,  471,   32,  116,  116,
-      116,  117,  117,  117,  121,  121,  121,  192,  458,   32,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
+       25,   25,   25,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
 
-       32,   32,  123,  123,  123,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       69,  138,  138,  138,   69,  139,  139,  139,  193,  193,
-       69,   69,  142,  142,  142,  145,  145,  145,   69,  220,
-      405,   69,  405,  457,   69,  259,  220,   69,   69,  148,
-      148,  148,   69,  150,  150,  150,  151,  151,  151,   69,
-      186,  186,  186,   69,  259,   69,   69,   69,   69,  188,
-      188,  188,  189,  189,  189,  190,  190,  190,  191,  191,
-      191,  198,  198,  198,  200,  200,  200,  201,  202,  202,
+       34,   38,   40,   40,   40,   38,   70,   38,  175,  221,
+       70,  171,   38,   38,   40,   45,   87,  221,   38,   45,
+       87,   45,  171,   38,  175,   70,   80,   80,   80,   38,
+       38,   94,   45,  109,  107,   94,  111,   45,  107,  114,
+       40,  112,  208,   45,   45,  112,  109,  107,  114,  208,
+      183,  109,  111,   80,  183,  111,  212,  114,   38,  124,
+      124,  124,  147,  147,  147,  149,  149,  149,  152,  152,
+      152,  212,   45,   55,  201,  201,   55,  154,  154,  154,
+      217,  502,   55,   55,  155,  155,  155,  158,  158,  158,
+       55,  167,  501,   55,  179,  167,   55,  500,  236,   55,
 
-      202,  201,  242,  269,  289,  292,  312,  242,  323,  456,
-      242,  242,  242,  315,  315,  315,  201,  343,  344,  414,
-      433,  455,  269,  289,  292,  312,  454,  323,  343,  343,
-      343,  452,  451,  450,  449,  448,  446,  344,  414,  433,
-      461,  461,  461,  461,  461,  461,  461,  462,  462,  462,
-      462,  462,  462,  462,  463,  463,  463,  463,  463,  463,
-      463,  464,  464,  464,  464,  464,  464,  464,  465,  465,
-      466,  445,  466,  466,  466,  466,  467,  467,  444,  467,
-      467,  467,  467,  468,  468,  468,  468,  468,  468,  468,
-      469,  469,  469,  470,  442,  470,  470,  470,  470,  470,
+       55,  160,  160,  160,   55,  236,  217,  167,  205,  205,
+      205,   55,  206,  179,  499,   55,  206,   55,   55,   55,
+       55,  119,  207,  207,  207,  119,  179,  119,  209,  209,
+      209,  206,  119,  119,  210,  211,  211,  211,  119,  213,
+      213,  213,  237,  119,  276,  237,  210,  286,  306,  119,
+      119,  214,  214,  214,  309,  210,  215,  215,  215,  216,
+      216,  216,  498,  276,  330,  341,  286,  306,  333,  333,
+      333,  479,  427,  309,  363,  427,  436,  478,  119,  125,
+      125,  125,  477,  330,  341,  476,  454,  475,  125,  473,
+      362,  362,  472,  363,  471,  436,  125,  125,  125,  125,
 
-      475,  441,  475,  475,  475,  475,  482,  440,  482,  482,
-      482,  482,  482,  439,  438,  436,  435,  434,  432,  427,
-      426,  424,  423,  421,  420,  418,  417,  416,  415,  413,
-      412,  410,  409,  408,  406,  404,  403,  402,  401,  400,
-      399,  398,  395,  394,  393,  392,  390,  389,  388,  387,
-      386,  384,  383,  382,  379,  378,  377,  376,  375,  374,
-      373,  372,  371,  370,  369,  368,  367,  365,  364,  362,
-      360,  359,  358,  357,  356,  355,  354,  353,  352,  351,
-      350,  349,  348,  347,  346,  342,  341,  340,  339,  338,
-      337,  336,  334,  333,  332,  331,  330,  329,  328,  327,
+      125,  125,  362,  362,  362,  454,  482,  482,  482,  482,
+      482,  482,  482,  482,  482,  482,  482,  482,  482,  483,
+      483,  483,  483,  483,  483,  483,  483,  483,  483,  483,
+      483,  483,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  485,  485,  485,  485,  485,
+      485,  485,  485,  485,  485,  485,  485,  485,  486,  470,
+      469,  486,  467,  486,  486,  466,  465,  463,  462,  486,
+      486,  487,  461,  460,  487,  459,  487,  487,  457,  487,
+      487,  456,  487,  487,  488,  455,  488,  488,  489,  489,
+      453,  489,  489,  489,  489,  489,  489,  489,  489,  489,
 
-      326,  325,  324,  322,  321,  320,  319,  314,  310,  308,
-      307,  306,  305,  304,  302,  301,  300,  299,  298,  296,
-      295,  294,  293,  291,  290,  287,  286,  285,  283,  280,
-      278,  277,  275,  273,  272,  271,  270,  268,  266,  265,
-      264,  263,  262,  261,  260,  258,  257,  256,  254,  253,
-      252,  251,  250,  249,  248,  247,  246,  245,  244,  243,
-      238,  237,  236,  235,  234,  233,  232,  231,  230,  229,
-      228,  227,  226,  225,  224,  223,  222,  219,  218,  217,
-      216,  215,  214,  213,  212,  211,  210,  209,  208,  207,
-      205,  204,  197,  185,  181,  180,  179,  178,  177,  176,
+      490,  490,  490,  490,  490,  490,  490,  490,  490,  490,
+      490,  490,  490,  491,  491,  491,  491,  491,  491,  491,
+      491,  491,  491,  448,  447,  491,  492,  445,  444,  492,
+      492,  492,  442,  441,  440,  439,  492,  438,  492,  493,
+      493,  437,  493,  493,  494,  494,  494,  494,  494,  494,
+      494,  494,  494,  495,  495,  435,  495,  495,  496,  496,
+      434,  496,  496,  496,  496,  496,  496,  496,  496,  496,
+      496,  497,  497,  432,  497,  497,  507,  507,  431,  507,
+      507,  507,  507,  507,  507,  507,  507,  507,  507,  430,
+      428,  426,  425,  424,  423,  422,  421,  420,  417,  416,
 
-      175,  174,  173,  172,  171,  169,  168,  167,  165,  164,
-      163,  161,  160,  158,  157,  156,  154,  122,  118,  114,
-      113,  106,  105,  104,   99,   97,   95,   94,   93,   90,
-       87,   77,   66,   55,   44,   27,    8,    7,    2,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460,  460,  460,
-      460,  460,  460,  460,  460,  460,  460,  460
+      415,  414,  412,  411,  410,  409,  408,  406,  405,  404,
+      401,  400,  399,  398,  396,  395,  394,  393,  392,  391,
+      390,  389,  388,  385,  384,  382,  380,  379,  378,  377,
+      376,  375,  374,  373,  372,  371,  370,  369,  368,  367,
+      366,  365,  361,  360,  359,  358,  357,  356,  355,  353,
+      352,  351,  350,  349,  348,  347,  346,  345,  344,  343,
+      342,  340,  339,  338,  337,  332,  328,  326,  325,  324,
+      323,  322,  320,  319,  318,  317,  316,  314,  313,  312,
+      311,  310,  308,  307,  304,  303,  302,  300,  297,  295,
+      294,  292,  290,  289,  288,  287,  285,  283,  282,  281,
 
+      280,  279,  278,  277,  275,  274,  273,  271,  270,  269,
+      268,  267,  266,  265,  264,  263,  262,  261,  260,  258,
+      254,  253,  252,  251,  250,  249,  248,  247,  246,  245,
+      244,  243,  242,  241,  240,  239,  238,  235,  234,  233,
+      232,  231,  230,  229,  228,  227,  226,  225,  224,  223,
+      222,  220,  219,  218,  200,  194,  193,  192,  191,  190,
+      189,  188,  187,  186,  185,  184,  182,  181,  180,  178,
+      177,  176,  174,  173,  172,  170,  169,  168,  166,  165,
+      159,  156,  129,  127,  126,  117,  116,  115,  110,  108,
+      106,  105,  104,  101,  100,   95,   90,   68,   65,   51,
+
+       49,   29,   26,    4,    3,    2,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481,  481,  481,  481,  481,  481,
+      481,  481,  481,  481,  481
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -840,18 +921,18 @@
 
 static yyconst flex_int16_t yy_rule_linenum[109] =
     {   0,
-      197,  198,  199,  200,  208,  219,  220,  221,  222,  223,
-      224,  225,  226,  227,  228,  229,  230,  231,  232,  233,
-      234,  235,  236,  237,  238,  239,  240,  241,  242,  243,
-      244,  245,  246,  247,  248,  249,  250,  251,  252,  253,
-      254,  255,  256,  257,  258,  260,  264,  265,  266,  268,
-      275,  279,  285,  288,  291,  294,  305,  313,  320,  337,
-      343,  364,  365,  376,  387,  388,  400,  408,  419,  435,
-      441,  451,  461,  472,  473,  474,  475,  476,  477,  478,
-      481,  483,  492,  504,  509,  510,  516,  517,  528,  534,
-      540,  546,  562,  596,  597,  598,  634,  636,  637,  639,
+      149,  150,  151,  152,  160,  178,  179,  180,  181,  182,
+      183,  184,  185,  186,  187,  188,  189,  190,  191,  192,
+      193,  194,  195,  196,  197,  198,  199,  200,  201,  202,
+      203,  204,  205,  206,  207,  208,  209,  210,  211,  212,
+      213,  214,  215,  216,  217,  218,  219,  221,  225,  226,
+      227,  228,  229,  231,  238,  242,  249,  254,  257,  260,
+      263,  271,  279,  286,  293,  312,  327,  332,  351,  363,
+      379,  394,  411,  412,  423,  434,  435,  447,  473,  518,
+      528,  537,  547,  548,  549,  550,  551,  552,  553,  556,
+      558,  566,  583,  588,  589,  595,  596,  607,  613,  619,
 
-      643,  658,  693,  694,  695,  696,  704,  705
+      625,  641,  642,  643,  659,  678,  718,  719
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -865,13 +946,13 @@
 #line 1 "scan-gram.l"
 /* Bison Grammar Scanner                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   This program is free software; you can redistribute it and/or modify
+   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 2 of the License, or
+   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,
@@ -880,153 +961,109 @@
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301  USA
-*/
-#line 27 "scan-gram.l"
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+#define YY_NO_INPUT 1
+#line 24 "scan-gram.l"
 /* Work around a bug in flex 2.5.31.  See Debian bug 333231
    <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
 #undef gram_wrap
 #define gram_wrap() 1
 
-#include "system.h"
-
-#include <mbswidth.h>
-#include <quote.h>
+#define FLEX_PREFIX(Id) gram_ ## Id
+#include "flex-scanner.h"
 
 #include "complain.h"
 #include "files.h"
-#include "getargs.h"
 #include "gram.h"
 #include "quotearg.h"
 #include "reader.h"
 #include "uniqstr.h"
 
-#define YY_USER_INIT					\
-  do							\
-    {							\
-      scanner_cursor.file = current_file;		\
-      scanner_cursor.line = 1;				\
-      scanner_cursor.column = 1;			\
-      code_start = scanner_cursor;			\
-    }							\
-  while (0)
+#include <c-ctype.h>
+#include <mbswidth.h>
+#include <quote.h>
 
-/* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
-int gram_get_lineno (void);
-FILE *gram_get_in (void);
-FILE *gram_get_out (void);
-int gram_get_leng (void);
-char *gram_get_text (void);
-void gram_set_lineno (int);
-void gram_set_in (FILE *);
-void gram_set_out (FILE *);
-int gram_get_debug (void);
-void gram_set_debug (int);
-int gram_lex_destroy (void);
+#include "scan-gram.h"
+
+#define YY_DECL GRAM_LEX_DECL
+
+#define YY_USER_INIT					\
+   code_start = scanner_cursor = loc->start;		\
 
 /* Location of scanner cursor.  */
-boundary scanner_cursor;
+static boundary scanner_cursor;
 
-static void adjust_location (location *, char const *, size_t);
-#define YY_USER_ACTION  adjust_location (loc, gram_text, gram_leng);
+#define YY_USER_ACTION  location_compute (loc, &scanner_cursor, gram_text, gram_leng);
 
 static size_t no_cr_read (FILE *, char *, size_t);
 #define YY_INPUT(buf, result, size) ((result) = no_cr_read (gram_in, buf, size))
 
-
-/* OBSTACK_FOR_STRING -- Used to store all the characters that we need to
-   keep (to construct ID, STRINGS etc.).  Use the following macros to
-   use it.
-
-   Use STRING_GROW to append what has just been matched, and
-   STRING_FINISH to end the string (it puts the ending 0).
-   STRING_FINISH also stores this string in LAST_STRING, which can be
-   used, and which is used by STRING_FREE to free the last string.  */
-
-static struct obstack obstack_for_string;
-
-/* A string representing the most recently saved token.  */
-char *last_string;
-
-/* The location of the most recently saved token, if it was a
-   BRACED_CODE token; otherwise, this has an unspecified value.  */
-location last_braced_code_loc;
-
-#define STRING_GROW   \
-  obstack_grow (&obstack_for_string, gram_text, gram_leng)
-
-#define STRING_FINISH					\
-  do {							\
-    obstack_1grow (&obstack_for_string, '\0');		\
-    last_string = obstack_finish (&obstack_for_string);	\
+#define ROLLBACK_CURRENT_TOKEN                                  \
+  do {                                                          \
+    scanner_cursor.column -= mbsnwidth (gram_text, gram_leng, 0);	\
+    yyless (0);                                                 \
   } while (0)
 
-#define STRING_FREE \
-  obstack_free (&obstack_for_string, last_string)
+/* A string representing the most recently saved token.  */
+static char *last_string;
+
+/* Bracketed identifier. */
+static uniqstr bracketed_id_str = 0;
+static location bracketed_id_loc;
+static boundary bracketed_id_start;
+static int bracketed_id_context_state = 0;
 
 void
-scanner_last_string_free (void)
+gram_scanner_last_string_free (void)
 {
   STRING_FREE;
 }
 
-/* Within well-formed rules, RULE_LENGTH is the number of values in
-   the current rule so far, which says where to find `$0' with respect
-   to the top of the stack.  It is not the same as the rule->length in
-   the case of mid rule actions.
-
-   Outside of well-formed rules, RULE_LENGTH has an undefined value.  */
-static int rule_length;
-
-static void rule_length_overflow (location) __attribute__ ((__noreturn__));
-
-/* Increment the rule length by one, checking for overflow.  */
-static inline void
-increment_rule_length (location loc)
-{
-  rule_length++;
-
-  /* Don't allow rule_length == INT_MAX, since that might cause
-     confusion with strtol if INT_MAX == LONG_MAX.  */
-  if (rule_length == INT_MAX)
-    rule_length_overflow (loc);
-}
-
-static void handle_dollar (int token_type, char *cp, location loc);
-static void handle_at (int token_type, char *cp, location loc);
 static void handle_syncline (char *, location);
 static unsigned long int scan_integer (char const *p, int base, location loc);
 static int convert_ucn_to_byte (char const *hex_text);
 static void unexpected_eof (boundary, char const *);
 static void unexpected_newline (boundary, char const *);
 
+/* A C-like comment in directives/rules. */
 
+/* Strings and characters in directives/rules. */
 
+/* A identifier was just read in directives/rules.  Special state
+to capture the sequence 'identifier :'. */
 
+/* Three types of user code:
+- prologue (code between '%{' '%}' in the first section, before %%);
+- actions, printers, union, etc, (between braced in the middle section);
+- epilogue (everything after the second %%). */
 
+/* C and C++ comments in code. */
+
+/* Strings and characters in code. */
+
+/* Bracketed identifiers support. */
 
 /* POSIX says that a tag must be both an id and a C union member, but
    historically almost any character is allowed in a tag.  We disallow
    NUL and newline, as this simplifies our implementation.  */
 /* Zero or more instances of backslash-newline.  Following GCC, allow
    white space between the backslash and the newline.  */
-#line 1016 "scan-gram.c"
+#line 1052 "scan-gram.c"
 
 #define INITIAL 0
-#define SC_COMMENT 1
-#define SC_LINE_COMMENT 2
-#define SC_YACC_COMMENT 3
-#define SC_STRING 4
-#define SC_CHARACTER 5
-#define SC_AFTER_IDENTIFIER 6
-#define SC_ESCAPED_STRING 7
-#define SC_ESCAPED_CHARACTER 8
-#define SC_PRE_CODE 9
-#define SC_BRACED_CODE 10
-#define SC_PROLOGUE 11
-#define SC_EPILOGUE 12
+#define SC_YACC_COMMENT 1
+#define SC_ESCAPED_STRING 2
+#define SC_ESCAPED_CHARACTER 3
+#define SC_AFTER_IDENTIFIER 4
+#define SC_PROLOGUE 5
+#define SC_BRACED_CODE 6
+#define SC_EPILOGUE 7
+#define SC_COMMENT 8
+#define SC_LINE_COMMENT 9
+#define SC_STRING 10
+#define SC_CHARACTER 11
+#define SC_BRACKETED_ID 12
+#define SC_RETURN_BRACKETED_ID 13
 
 #ifndef YY_NO_UNISTD_H
 /* Special case for "unistd.h", since it is non-ANSI. We include it way
@@ -1046,11 +1083,46 @@
 
 /* %if-c-only Reentrant structure and macros (non-C++). */
 /* %if-reentrant */
+/* %if-c-only */
+
+static int yy_init_globals (void );
+
+/* %endif */
 /* %if-reentrant */
 /* %endif */
+/* %endif End reentrant structures and macros. */
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int gram_lex_destroy (void );
+
+int gram_get_debug (void );
+
+void gram_set_debug (int debug_flag  );
+
+YY_EXTRA_TYPE gram_get_extra (void );
+
+void gram_set_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *gram_get_in (void );
+
+void gram_set_in  (FILE * in_str  );
+
+FILE *gram_get_out (void );
+
+void gram_set_out  (FILE * out_str  );
+
+yy_size_t gram_get_leng (void );
+
+char *gram_get_text (void );
+
+int gram_get_lineno (void );
+
+void gram_set_lineno (int line_number  );
+
 /* %if-bison-bridge */
 /* %endif */
-/* %endif End reentrant structures and macros. */
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1107,7 +1179,7 @@
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( gram_text, gram_leng, 1, gram_out )
+#define ECHO do { if (fwrite( gram_text, gram_leng, 1, gram_out )) {} } while (0)
 /* %endif */
 /* %if-c++-only C++ definition */
 /* %endif */
@@ -1232,20 +1304,17 @@
 	register int yy_act;
     
 /* %% [7.0] user's declarations go here */
-#line 165 "scan-gram.l"
+#line 120 "scan-gram.l"
 
 
   /* Nesting level of the current code in braces.  */
-  int braces_level IF_LINT (= 0);
+  int braces_level PACIFY_CC (= 0);
 
   /* Parent context state, when applicable.  */
-  int context_state IF_LINT (= 0);
-
-  /* Token type to return, when applicable.  */
-  int token_type IF_LINT (= 0);
+  int context_state PACIFY_CC (= 0);
 
   /* Location of most recent identifier, when applicable.  */
-  location id_loc IF_LINT (= empty_location);
+  location id_loc PACIFY_CC (= empty_location);
 
   /* Where containing code started, when applicable.  Its initial
      value is relevant only when gram_lex is invoked in the SC_EPILOGUE
@@ -1254,7 +1323,7 @@
 
   /* Where containing comment or string or character literal started,
      when applicable.  */
-  boundary token_start IF_LINT (= scanner_cursor);
+  boundary token_start PACIFY_CC (= scanner_cursor);
 
 
 
@@ -1262,11 +1331,11 @@
   | Scanning white space.  |
   `-----------------------*/
 
-#line 1266 "scan-gram.c"
+#line 1335 "scan-gram.c"
 
-	if ( (yy_init) )
+	if ( !(yy_init) )
 		{
-		(yy_init) = 0;
+		(yy_init) = 1;
 
 #ifdef YY_USER_INIT
 		YY_USER_INIT;
@@ -1326,13 +1395,13 @@
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 461 )
+				if ( yy_current_state >= 482 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 460 );
+		while ( yy_current_state != 481 );
 		yy_cp = (yy_last_accepting_cpos);
 		yy_current_state = (yy_last_accepting_state);
 
@@ -1376,21 +1445,21 @@
 /* Comments and white space.  */
 case 1:
 YY_RULE_SETUP
-#line 197 "scan-gram.l"
-warn_at (*loc, _("stray `,' treated as white space"));
+#line 149 "scan-gram.l"
+warn_at (*loc, _("stray ',' treated as white space"));
 	YY_BREAK
 case 2:
 /* rule 2 can match eol */
-#line 199 "scan-gram.l"
+#line 151 "scan-gram.l"
 case 3:
 /* rule 3 can match eol */
 YY_RULE_SETUP
-#line 199 "scan-gram.l"
-;
+#line 151 "scan-gram.l"
+continue;
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 200 "scan-gram.l"
+#line 152 "scan-gram.l"
 {
     token_start = loc->start;
     context_state = YY_START;
@@ -1402,7 +1471,7 @@
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 208 "scan-gram.l"
+#line 160 "scan-gram.l"
 {
     handle_syncline (gram_text + sizeof "#line " - 1, *loc);
   }
@@ -1411,292 +1480,324 @@
 /*----------------------------.
   | Scanning Bison directives.  |
   `----------------------------*/
+/* For directives that are also command line options, the regex must be
+	"%..."
+     after "[-_]"s are removed, and the directive must match the --long
+     option name, with a single string argument.  Otherwise, add exceptions
+     to ../build-aux/cross-options.pl.  */
 
 
 case 6:
 YY_RULE_SETUP
-#line 219 "scan-gram.l"
+#line 178 "scan-gram.l"
 return PERCENT_NONASSOC;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 220 "scan-gram.l"
-return PERCENT_DEBUG;
+#line 179 "scan-gram.l"
+return PERCENT_CODE;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 221 "scan-gram.l"
-return PERCENT_DEFAULT_PREC;
+#line 180 "scan-gram.l"
+return PERCENT_DEBUG;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 222 "scan-gram.l"
-return PERCENT_DEFINE;
+#line 181 "scan-gram.l"
+return PERCENT_DEFAULT_PREC;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 223 "scan-gram.l"
-return PERCENT_DEFINES;
+#line 182 "scan-gram.l"
+return PERCENT_DEFINE;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 224 "scan-gram.l"
-token_type = PERCENT_DESTRUCTOR; BEGIN SC_PRE_CODE;
+#line 183 "scan-gram.l"
+return PERCENT_DEFINES;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 225 "scan-gram.l"
-return PERCENT_DPREC;
+#line 184 "scan-gram.l"
+return PERCENT_DESTRUCTOR;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 226 "scan-gram.l"
-return PERCENT_ERROR_VERBOSE;
+#line 185 "scan-gram.l"
+return PERCENT_DPREC;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 227 "scan-gram.l"
-return PERCENT_EXPECT;
+#line 186 "scan-gram.l"
+return PERCENT_ERROR_VERBOSE;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 228 "scan-gram.l"
-return PERCENT_EXPECT_RR;
+#line 187 "scan-gram.l"
+return PERCENT_EXPECT;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 229 "scan-gram.l"
-return PERCENT_FILE_PREFIX;
+#line 188 "scan-gram.l"
+return PERCENT_EXPECT_RR;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 230 "scan-gram.l"
-return PERCENT_YACC;
+#line 189 "scan-gram.l"
+return PERCENT_FILE_PREFIX;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 231 "scan-gram.l"
-token_type = PERCENT_INITIAL_ACTION; BEGIN SC_PRE_CODE;
+#line 190 "scan-gram.l"
+return PERCENT_YACC;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 232 "scan-gram.l"
-return PERCENT_GLR_PARSER;
+#line 191 "scan-gram.l"
+return PERCENT_INITIAL_ACTION;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 233 "scan-gram.l"
-return PERCENT_LEFT;
+#line 192 "scan-gram.l"
+return PERCENT_GLR_PARSER;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 234 "scan-gram.l"
-token_type = PERCENT_LEX_PARAM; BEGIN SC_PRE_CODE;
+#line 193 "scan-gram.l"
+return PERCENT_LANGUAGE;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 235 "scan-gram.l"
-return PERCENT_LOCATIONS;
+#line 194 "scan-gram.l"
+return PERCENT_LEFT;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 236 "scan-gram.l"
-return PERCENT_MERGE;
+#line 195 "scan-gram.l"
+return PERCENT_LEX_PARAM;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 237 "scan-gram.l"
-return PERCENT_NAME_PREFIX;
+#line 196 "scan-gram.l"
+return PERCENT_LOCATIONS;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 238 "scan-gram.l"
-return PERCENT_NO_DEFAULT_PREC;
+#line 197 "scan-gram.l"
+return PERCENT_MERGE;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 239 "scan-gram.l"
-return PERCENT_NO_LINES;
+#line 198 "scan-gram.l"
+return PERCENT_NAME_PREFIX;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 240 "scan-gram.l"
-return PERCENT_NONASSOC;
+#line 199 "scan-gram.l"
+return PERCENT_NO_DEFAULT_PREC;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 241 "scan-gram.l"
-return PERCENT_NONDETERMINISTIC_PARSER;
+#line 200 "scan-gram.l"
+return PERCENT_NO_LINES;
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 242 "scan-gram.l"
-return PERCENT_NTERM;
+#line 201 "scan-gram.l"
+return PERCENT_NONASSOC;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 243 "scan-gram.l"
-return PERCENT_OUTPUT;
+#line 202 "scan-gram.l"
+return PERCENT_NONDETERMINISTIC_PARSER;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 244 "scan-gram.l"
-token_type = PERCENT_PARSE_PARAM; BEGIN SC_PRE_CODE;
+#line 203 "scan-gram.l"
+return PERCENT_NTERM;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 245 "scan-gram.l"
-rule_length--; return PERCENT_PREC;
+#line 204 "scan-gram.l"
+return PERCENT_OUTPUT;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 246 "scan-gram.l"
-token_type = PERCENT_PRINTER; BEGIN SC_PRE_CODE;
+#line 205 "scan-gram.l"
+return PERCENT_PARSE_PARAM;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 247 "scan-gram.l"
-return PERCENT_PURE_PARSER;
+#line 206 "scan-gram.l"
+return PERCENT_PREC;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 248 "scan-gram.l"
-return PERCENT_REQUIRE;
+#line 207 "scan-gram.l"
+return PERCENT_PRINTER;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 249 "scan-gram.l"
-return PERCENT_RIGHT;
+#line 208 "scan-gram.l"
+return PERCENT_PURE_PARSER;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 250 "scan-gram.l"
-return PERCENT_SKELETON;
+#line 209 "scan-gram.l"
+return PERCENT_REQUIRE;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 251 "scan-gram.l"
-return PERCENT_START;
+#line 210 "scan-gram.l"
+return PERCENT_RIGHT;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 252 "scan-gram.l"
-return PERCENT_TOKEN;
+#line 211 "scan-gram.l"
+return PERCENT_SKELETON;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 253 "scan-gram.l"
-return PERCENT_TOKEN;
+#line 212 "scan-gram.l"
+return PERCENT_START;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 254 "scan-gram.l"
-return PERCENT_TOKEN_TABLE;
+#line 213 "scan-gram.l"
+return PERCENT_TOKEN;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 255 "scan-gram.l"
-return PERCENT_TYPE;
+#line 214 "scan-gram.l"
+return PERCENT_TOKEN;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 256 "scan-gram.l"
-token_type = PERCENT_UNION; BEGIN SC_PRE_CODE;
+#line 215 "scan-gram.l"
+return PERCENT_TOKEN_TABLE;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 257 "scan-gram.l"
-return PERCENT_VERBOSE;
+#line 216 "scan-gram.l"
+return PERCENT_TYPE;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 258 "scan-gram.l"
-return PERCENT_YACC;
+#line 217 "scan-gram.l"
+return PERCENT_UNION;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 260 "scan-gram.l"
+#line 218 "scan-gram.l"
+return PERCENT_VERBOSE;
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 219 "scan-gram.l"
+return PERCENT_YACC;
+	YY_BREAK
+case 48:
+/* rule 48 can match eol */
+YY_RULE_SETUP
+#line 221 "scan-gram.l"
 {
     complain_at (*loc, _("invalid directive: %s"), quote (gram_text));
   }
 	YY_BREAK
-case 47:
-YY_RULE_SETUP
-#line 264 "scan-gram.l"
-return EQUAL;
-	YY_BREAK
-case 48:
-YY_RULE_SETUP
-#line 265 "scan-gram.l"
-rule_length = 0; return PIPE;
-	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 266 "scan-gram.l"
-return SEMICOLON;
+#line 225 "scan-gram.l"
+return EQUAL;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 268 "scan-gram.l"
-{
-    val->symbol = symbol_get (gram_text, *loc);
-    id_loc = *loc;
-    increment_rule_length (*loc);
-    BEGIN SC_AFTER_IDENTIFIER;
-  }
+#line 226 "scan-gram.l"
+return PIPE;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 275 "scan-gram.l"
+#line 227 "scan-gram.l"
+return SEMICOLON;
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 228 "scan-gram.l"
+return TYPE_TAG_ANY;
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 229 "scan-gram.l"
+return TYPE_TAG_NONE;
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 231 "scan-gram.l"
+{
+    val->uniqstr = uniqstr_new (gram_text);
+    id_loc = *loc;
+    bracketed_id_str = NULL;
+    BEGIN SC_AFTER_IDENTIFIER;
+  }
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 238 "scan-gram.l"
 {
     val->integer = scan_integer (gram_text, 10, *loc);
     return INT;
   }
 	YY_BREAK
-case 52:
+case 56:
 YY_RULE_SETUP
-#line 279 "scan-gram.l"
+#line 242 "scan-gram.l"
 {
     val->integer = scan_integer (gram_text, 16, *loc);
     return INT;
   }
 	YY_BREAK
-/* Characters.  We don't check there is only one.  */
-case 53:
+/* Identifiers may not start with a digit.  Yet, don't silently
+     accept "1FOO" as "1 FOO".  */
+case 57:
 YY_RULE_SETUP
-#line 285 "scan-gram.l"
-STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
+#line 249 "scan-gram.l"
+{
+    complain_at (*loc, _("invalid identifier: %s"), quote (gram_text));
+  }
+	YY_BREAK
+/* Characters.  */
+case 58:
+YY_RULE_SETUP
+#line 254 "scan-gram.l"
+token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
 	YY_BREAK
 /* Strings. */
-case 54:
+case 59:
 YY_RULE_SETUP
-#line 288 "scan-gram.l"
+#line 257 "scan-gram.l"
 token_start = loc->start; BEGIN SC_ESCAPED_STRING;
 	YY_BREAK
 /* Prologue. */
-case 55:
+case 60:
 YY_RULE_SETUP
-#line 291 "scan-gram.l"
+#line 260 "scan-gram.l"
 code_start = loc->start; BEGIN SC_PROLOGUE;
 	YY_BREAK
 /* Code in between braces.  */
-case 56:
+case 61:
 YY_RULE_SETUP
-#line 294 "scan-gram.l"
+#line 263 "scan-gram.l"
 {
-    if (current_rule && current_rule->action)
-      grammar_midrule_action ();
     STRING_GROW;
-    token_type = BRACED_CODE;
     braces_level = 0;
     code_start = loc->start;
     BEGIN SC_BRACED_CODE;
   }
 	YY_BREAK
 /* A type. */
-case 57:
+case 62:
 YY_RULE_SETUP
-#line 305 "scan-gram.l"
+#line 271 "scan-gram.l"
 {
     obstack_grow (&obstack_for_string, gram_text + 1, gram_leng - 2);
     STRING_FINISH;
@@ -1705,9 +1806,9 @@
     return TYPE;
   }
 	YY_BREAK
-case 58:
+case 63:
 YY_RULE_SETUP
-#line 313 "scan-gram.l"
+#line 279 "scan-gram.l"
 {
     static int percent_percent_count;
     if (++percent_percent_count == 2)
@@ -1715,15 +1816,27 @@
     return PERCENT_PERCENT;
   }
 	YY_BREAK
-case 59:
+case 64:
 YY_RULE_SETUP
-#line 320 "scan-gram.l"
+#line 286 "scan-gram.l"
 {
-    complain_at (*loc, _("invalid character: %s"), quote (gram_text));
+    bracketed_id_str = NULL;
+    bracketed_id_start = loc->start;
+    bracketed_id_context_state = YY_START;
+    BEGIN SC_BRACKETED_ID;
+  }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 293 "scan-gram.l"
+{
+    complain_at (*loc, "%s: %s",
+                 ngettext ("invalid character", "invalid characters", gram_leng),
+                 quote_mem (gram_text, gram_leng));
   }
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 324 "scan-gram.l"
+#line 299 "scan-gram.l"
 {
     loc->start = loc->end = scanner_cursor;
     yyterminate ();
@@ -1735,92 +1848,182 @@
   `-----------------------------------------------------------------*/
 
 
-case 60:
+case 66:
 YY_RULE_SETUP
-#line 337 "scan-gram.l"
+#line 312 "scan-gram.l"
 {
-    rule_length = 0;
+    if (bracketed_id_str)
+      {
+	ROLLBACK_CURRENT_TOKEN;
+	BEGIN SC_RETURN_BRACKETED_ID;
+	*loc = id_loc;
+	return ID;
+      }
+    else
+      {
+	bracketed_id_start = loc->start;
+	bracketed_id_context_state = YY_START;
+	BEGIN SC_BRACKETED_ID;
+      }
+  }
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 327 "scan-gram.l"
+{
+    BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
-    BEGIN INITIAL;
     return ID_COLON;
   }
 	YY_BREAK
-case 61:
+case 68:
 YY_RULE_SETUP
-#line 343 "scan-gram.l"
+#line 332 "scan-gram.l"
 {
-    scanner_cursor.column -= mbsnwidth (gram_text, gram_leng, 0);
-    yyless (0);
+    ROLLBACK_CURRENT_TOKEN;
+    BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
-    BEGIN INITIAL;
     return ID;
   }
 	YY_BREAK
 case YY_STATE_EOF(SC_AFTER_IDENTIFIER):
-#line 350 "scan-gram.l"
+#line 338 "scan-gram.l"
 {
+    BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
-    BEGIN INITIAL;
     return ID;
   }
 	YY_BREAK
 
+/*--------------------------------.
+  | Scanning bracketed identifiers. |
+  `--------------------------------*/
+
+
+case 69:
+YY_RULE_SETUP
+#line 351 "scan-gram.l"
+{
+    if (bracketed_id_str)
+      {
+	complain_at (*loc, _("unexpected identifier in bracketed name: %s"),
+		     quote (gram_text));
+      }
+    else
+      {
+	bracketed_id_str = uniqstr_new (gram_text);
+	bracketed_id_loc = *loc;
+      }
+  }
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 363 "scan-gram.l"
+{
+    BEGIN bracketed_id_context_state;
+    if (bracketed_id_str)
+      {
+	if (INITIAL == bracketed_id_context_state)
+	  {
+	    val->uniqstr = bracketed_id_str;
+	    bracketed_id_str = 0;
+	    *loc = bracketed_id_loc;
+	    return BRACKETED_ID;
+	  }
+      }
+    else
+      complain_at (*loc, _("an identifier expected"));
+  }
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 379 "scan-gram.l"
+{
+    complain_at (*loc, "%s: %s",
+                 ngettext ("invalid character in bracketed name",
+                           "invalid characters in bracketed name", gram_leng),
+                 quote_mem (gram_text, gram_leng));
+  }
+	YY_BREAK
+case YY_STATE_EOF(SC_BRACKETED_ID):
+#line 386 "scan-gram.l"
+{
+    BEGIN bracketed_id_context_state;
+    unexpected_eof (bracketed_id_start, "]");
+  }
+	YY_BREAK
+
+
+
+case 72:
+YY_RULE_SETUP
+#line 394 "scan-gram.l"
+{
+    ROLLBACK_CURRENT_TOKEN;
+    val->uniqstr = bracketed_id_str;
+    bracketed_id_str = 0;
+    *loc = bracketed_id_loc;
+    BEGIN INITIAL;
+    return BRACKETED_ID;
+  }
+	YY_BREAK
+
 /*---------------------------------------------------------------.
-  | Scanning a Yacc comment.  The initial `/ *' is already eaten.  |
+  | Scanning a Yacc comment.  The initial '/ *' is already eaten.  |
   `---------------------------------------------------------------*/
 
 
-case 62:
+case 73:
 YY_RULE_SETUP
-#line 364 "scan-gram.l"
+#line 411 "scan-gram.l"
 BEGIN context_state;
 	YY_BREAK
-case 63:
-/* rule 63 can match eol */
+case 74:
+/* rule 74 can match eol */
 YY_RULE_SETUP
-#line 365 "scan-gram.l"
-;
+#line 412 "scan-gram.l"
+continue;
 	YY_BREAK
 case YY_STATE_EOF(SC_YACC_COMMENT):
-#line 366 "scan-gram.l"
+#line 413 "scan-gram.l"
 unexpected_eof (token_start, "*/"); BEGIN context_state;
 	YY_BREAK
 
 /*------------------------------------------------------------.
-  | Scanning a C comment.  The initial `/ *' is already eaten.  |
+  | Scanning a C comment.  The initial '/ *' is already eaten.  |
   `------------------------------------------------------------*/
 
 
-case 64:
-/* rule 64 can match eol */
+case 75:
+/* rule 75 can match eol */
 YY_RULE_SETUP
-#line 376 "scan-gram.l"
+#line 423 "scan-gram.l"
 STRING_GROW; BEGIN context_state;
 	YY_BREAK
 case YY_STATE_EOF(SC_COMMENT):
-#line 377 "scan-gram.l"
+#line 424 "scan-gram.l"
 unexpected_eof (token_start, "*/"); BEGIN context_state;
 	YY_BREAK
 
 /*--------------------------------------------------------------.
-  | Scanning a line comment.  The initial `//' is already eaten.  |
+  | Scanning a line comment.  The initial '//' is already eaten.  |
   `--------------------------------------------------------------*/
 
 
-case 65:
-/* rule 65 can match eol */
+case 76:
+/* rule 76 can match eol */
 YY_RULE_SETUP
-#line 387 "scan-gram.l"
+#line 434 "scan-gram.l"
 STRING_GROW; BEGIN context_state;
 	YY_BREAK
-case 66:
-/* rule 66 can match eol */
+case 77:
+/* rule 77 can match eol */
 YY_RULE_SETUP
-#line 388 "scan-gram.l"
+#line 435 "scan-gram.l"
 STRING_GROW;
 	YY_BREAK
 case YY_STATE_EOF(SC_LINE_COMMENT):
-#line 389 "scan-gram.l"
+#line 436 "scan-gram.l"
 BEGIN context_state;
 	YY_BREAK
 
@@ -1830,27 +2033,30 @@
   `------------------------------------------------*/
 
 
-case 67:
+case 78:
+/* rule 78 can match eol */
 YY_RULE_SETUP
-#line 400 "scan-gram.l"
+#line 447 "scan-gram.l"
 {
+    if (gram_text[0] == '\n')
+      unexpected_newline (token_start, "\"");
     STRING_FINISH;
     loc->start = token_start;
     val->chars = last_string;
-    increment_rule_length (*loc);
     BEGIN INITIAL;
     return STRING;
   }
 	YY_BREAK
-case 68:
-/* rule 68 can match eol */
-YY_RULE_SETUP
-#line 408 "scan-gram.l"
-unexpected_newline (token_start, "\"");	BEGIN INITIAL;
-	YY_BREAK
 case YY_STATE_EOF(SC_ESCAPED_STRING):
-#line 409 "scan-gram.l"
-unexpected_eof (token_start, "\"");	BEGIN INITIAL;
+#line 456 "scan-gram.l"
+{
+    unexpected_eof (token_start, "\"");
+    STRING_FINISH;
+    loc->start = token_start;
+    val->chars = last_string;
+    BEGIN INITIAL;
+    return STRING;
+  }
 	YY_BREAK
 
 /*----------------------------------------------------------.
@@ -1859,42 +2065,61 @@
   `----------------------------------------------------------*/
 
 
-case 69:
+case 79:
+/* rule 79 can match eol */
 YY_RULE_SETUP
-#line 419 "scan-gram.l"
+#line 473 "scan-gram.l"
 {
-    unsigned char last_string_1;
-    STRING_GROW;
     STRING_FINISH;
     loc->start = token_start;
-    val->symbol = symbol_get (quotearg_style (escape_quoting_style,
-					      last_string),
-			      *loc);
-    symbol_class_set (val->symbol, token_sym, *loc, false);
-    last_string_1 = last_string[1];
-    symbol_user_token_number_set (val->symbol, last_string_1, *loc);
+    val->character = last_string[0];
+    {
+      /* FIXME: Eventually, make these errors.  */
+      if (last_string[0] == '\0')
+        {
+          warn_at (*loc, _("empty character literal"));
+          /* '\0' seems dangerous even if we are about to complain.  */
+          val->character = '\'';
+        }
+      else if (last_string[1] != '\0')
+        warn_at (*loc, _("extra characters in character literal"));
+    }
+    if (gram_text[0] == '\n')
+      unexpected_newline (token_start, "'");
     STRING_FREE;
-    increment_rule_length (*loc);
     BEGIN INITIAL;
-    return ID;
+    return CHAR;
   }
 	YY_BREAK
-case 70:
-/* rule 70 can match eol */
-YY_RULE_SETUP
-#line 435 "scan-gram.l"
-unexpected_newline (token_start, "'");	BEGIN INITIAL;
-	YY_BREAK
 case YY_STATE_EOF(SC_ESCAPED_CHARACTER):
-#line 436 "scan-gram.l"
-unexpected_eof (token_start, "'");	BEGIN INITIAL;
+#line 494 "scan-gram.l"
+{
+    STRING_FINISH;
+    loc->start = token_start;
+    val->character = last_string[0];
+    {
+      /* FIXME: Eventually, make these errors.  */
+      if (last_string[0] == '\0')
+        {
+          warn_at (*loc, _("empty character literal"));
+          /* '\0' seems dangerous even if we are about to complain.  */
+          val->character = '\'';
+        }
+      else if (last_string[1] != '\0')
+        warn_at (*loc, _("extra characters in character literal"));
+    }
+    unexpected_eof (token_start, "'");
+    STRING_FREE;
+    BEGIN INITIAL;
+    return CHAR;
+  }
 	YY_BREAK
 
 
 
-case 71:
+case 80:
 YY_RULE_SETUP
-#line 441 "scan-gram.l"
+#line 518 "scan-gram.l"
 complain_at (*loc, _("invalid null character"));
 	YY_BREAK
 
@@ -1903,94 +2128,96 @@
   `----------------------------*/
 
 
-case 72:
-YY_RULE_SETUP
-#line 451 "scan-gram.l"
-{
-    unsigned long int c = strtoul (gram_text + 1, NULL, 8);
-    if (UCHAR_MAX < c)
-      complain_at (*loc, _("invalid escape sequence: %s"), quote (gram_text));
-    else if (! c)
-      complain_at (*loc, _("invalid null character: %s"), quote (gram_text));
-    else
-      obstack_1grow (&obstack_for_string, c);
-  }
-	YY_BREAK
-case 73:
-YY_RULE_SETUP
-#line 461 "scan-gram.l"
-{
-    verify (UCHAR_MAX < ULONG_MAX);
-    unsigned long int c = strtoul (gram_text + 2, NULL, 16);
-    if (UCHAR_MAX < c)
-      complain_at (*loc, _("invalid escape sequence: %s"), quote (gram_text));
-    else if (! c)
-      complain_at (*loc, _("invalid null character: %s"), quote (gram_text));
-    else
-      obstack_1grow (&obstack_for_string, c);
-  }
-	YY_BREAK
-case 74:
-YY_RULE_SETUP
-#line 472 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\a');
-	YY_BREAK
-case 75:
-YY_RULE_SETUP
-#line 473 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\b');
-	YY_BREAK
-case 76:
-YY_RULE_SETUP
-#line 474 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\f');
-	YY_BREAK
-case 77:
-YY_RULE_SETUP
-#line 475 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\n');
-	YY_BREAK
-case 78:
-YY_RULE_SETUP
-#line 476 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\r');
-	YY_BREAK
-case 79:
-YY_RULE_SETUP
-#line 477 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\t');
-	YY_BREAK
-case 80:
-YY_RULE_SETUP
-#line 478 "scan-gram.l"
-obstack_1grow (&obstack_for_string, '\v');
-	YY_BREAK
-/* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
 case 81:
 YY_RULE_SETUP
-#line 481 "scan-gram.l"
-obstack_1grow (&obstack_for_string, gram_text[1]);
+#line 528 "scan-gram.l"
+{
+    unsigned long int c = strtoul (gram_text + 1, NULL, 8);
+    if (!c || UCHAR_MAX < c)
+      complain_at (*loc, _("invalid number after \\-escape: %s"),
+                   gram_text+1);
+    else
+      obstack_1grow (&obstack_for_string, c);
+  }
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 483 "scan-gram.l"
+#line 537 "scan-gram.l"
 {
-    int c = convert_ucn_to_byte (gram_text);
-    if (c < 0)
-      complain_at (*loc, _("invalid escape sequence: %s"), quote (gram_text));
-    else if (! c)
-      complain_at (*loc, _("invalid null character: %s"), quote (gram_text));
+    verify (UCHAR_MAX < ULONG_MAX);
+    unsigned long int c = strtoul (gram_text + 2, NULL, 16);
+    if (!c || UCHAR_MAX < c)
+      complain_at (*loc, _("invalid number after \\-escape: %s"),
+                   gram_text+1);
     else
       obstack_1grow (&obstack_for_string, c);
   }
 	YY_BREAK
 case 83:
-/* rule 83 can match eol */
 YY_RULE_SETUP
-#line 492 "scan-gram.l"
+#line 547 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\a');
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 548 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\b');
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 549 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\f');
+	YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 550 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\n');
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 551 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\r');
+	YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 552 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\t');
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 553 "scan-gram.l"
+obstack_1grow (&obstack_for_string, '\v');
+	YY_BREAK
+/* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
+case 90:
+YY_RULE_SETUP
+#line 556 "scan-gram.l"
+obstack_1grow (&obstack_for_string, gram_text[1]);
+	YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 558 "scan-gram.l"
 {
-    complain_at (*loc, _("unrecognized escape sequence: %s"), quote (gram_text));
-    STRING_GROW;
+    int c = convert_ucn_to_byte (gram_text);
+    if (c <= 0)
+      complain_at (*loc, _("invalid number after \\-escape: %s"),
+                   gram_text+1);
+    else
+      obstack_1grow (&obstack_for_string, c);
+  }
+	YY_BREAK
+case 92:
+/* rule 92 can match eol */
+YY_RULE_SETUP
+#line 566 "scan-gram.l"
+{
+    char const *p = gram_text + 1;
+    /* Quote only if escaping won't make the character visible.  */
+    if (c_isspace ((unsigned char) *p) && c_isprint ((unsigned char) *p))
+      p = quote (p);
+    else
+      p = quotearg_style_mem (escape_quoting_style, p, 1);
+    complain_at (*loc, _("invalid character after \\-escape: %s"), p);
   }
 	YY_BREAK
 
@@ -1999,46 +2226,46 @@
   `--------------------------------------------*/
 
 
-case 84:
-/* rule 84 can match eol */
+case 93:
+/* rule 93 can match eol */
 YY_RULE_SETUP
-#line 504 "scan-gram.l"
+#line 583 "scan-gram.l"
 STRING_GROW;
 	YY_BREAK
 
 
 
-case 85:
+case 94:
 YY_RULE_SETUP
-#line 509 "scan-gram.l"
+#line 588 "scan-gram.l"
 STRING_GROW; BEGIN context_state;
 	YY_BREAK
-case 86:
-/* rule 86 can match eol */
+case 95:
+/* rule 95 can match eol */
 YY_RULE_SETUP
-#line 510 "scan-gram.l"
+#line 589 "scan-gram.l"
 unexpected_newline (token_start, "'"); BEGIN context_state;
 	YY_BREAK
 case YY_STATE_EOF(SC_CHARACTER):
-#line 511 "scan-gram.l"
+#line 590 "scan-gram.l"
 unexpected_eof (token_start, "'"); BEGIN context_state;
 	YY_BREAK
 
 
 
-case 87:
+case 96:
 YY_RULE_SETUP
-#line 516 "scan-gram.l"
+#line 595 "scan-gram.l"
 STRING_GROW; BEGIN context_state;
 	YY_BREAK
-case 88:
-/* rule 88 can match eol */
+case 97:
+/* rule 97 can match eol */
 YY_RULE_SETUP
-#line 517 "scan-gram.l"
+#line 596 "scan-gram.l"
 unexpected_newline (token_start, "\""); BEGIN context_state;
 	YY_BREAK
 case YY_STATE_EOF(SC_STRING):
-#line 518 "scan-gram.l"
+#line 597 "scan-gram.l"
 unexpected_eof (token_start, "\""); BEGIN context_state;
 	YY_BREAK
 
@@ -2047,9 +2274,9 @@
   `---------------------------------------------------*/
 
 
-case 89:
+case 98:
 YY_RULE_SETUP
-#line 528 "scan-gram.l"
+#line 607 "scan-gram.l"
 {
     STRING_GROW;
     context_state = YY_START;
@@ -2057,9 +2284,9 @@
     BEGIN SC_CHARACTER;
   }
 	YY_BREAK
-case 90:
+case 99:
 YY_RULE_SETUP
-#line 534 "scan-gram.l"
+#line 613 "scan-gram.l"
 {
     STRING_GROW;
     context_state = YY_START;
@@ -2067,10 +2294,10 @@
     BEGIN SC_STRING;
   }
 	YY_BREAK
-case 91:
-/* rule 91 can match eol */
+case 100:
+/* rule 100 can match eol */
 YY_RULE_SETUP
-#line 540 "scan-gram.l"
+#line 619 "scan-gram.l"
 {
     STRING_GROW;
     context_state = YY_START;
@@ -2078,10 +2305,10 @@
     BEGIN SC_COMMENT;
   }
 	YY_BREAK
-case 92:
-/* rule 92 can match eol */
+case 101:
+/* rule 101 can match eol */
 YY_RULE_SETUP
-#line 546 "scan-gram.l"
+#line 625 "scan-gram.l"
 {
     STRING_GROW;
     context_state = YY_START;
@@ -2089,136 +2316,59 @@
   }
 	YY_BREAK
 
-/*---------------------------------------------------------------.
-  | Scanning after %union etc., possibly followed by white space.  |
-  | For %union only, allow arbitrary C code to appear before the   |
-  | following brace, as an extension to POSIX.			   |
-  `---------------------------------------------------------------*/
+/*-----------------------------------------------------------.
+  | Scanning some code in braces (actions). The initial "{" is |
+  | already eaten.                                             |
+  `-----------------------------------------------------------*/
 
 
-case 93:
+case 102:
+/* rule 102 can match eol */
 YY_RULE_SETUP
-#line 562 "scan-gram.l"
-{
-    bool valid = gram_text[0] == '{' || token_type == PERCENT_UNION;
-    scanner_cursor.column -= mbsnwidth (gram_text, gram_leng, 0);
-    yyless (0);
-
-    if (valid)
-      {
-	braces_level = -1;
-	code_start = loc->start;
-	BEGIN SC_BRACED_CODE;
-      }
-    else
-      {
-	complain_at (*loc, _("missing `{' in %s"),
-		     token_name (token_type));
-	obstack_sgrow (&obstack_for_string, "{}");
-	STRING_FINISH;
-	val->chars = last_string;
-	BEGIN INITIAL;
-	return token_type;
-      }
-  }
-	YY_BREAK
-case YY_STATE_EOF(SC_PRE_CODE):
-#line 585 "scan-gram.l"
-unexpected_eof (scanner_cursor, "{}"); BEGIN INITIAL;
-	YY_BREAK
-
-/*---------------------------------------------------------------.
-  | Scanning some code in braces (%union and actions). The initial |
-  | "{" is already eaten.                                          |
-  `---------------------------------------------------------------*/
-
-
-case 94:
-/* rule 94 can match eol */
-YY_RULE_SETUP
-#line 596 "scan-gram.l"
+#line 641 "scan-gram.l"
 STRING_GROW; braces_level++;
 	YY_BREAK
-case 95:
-/* rule 95 can match eol */
+case 103:
+/* rule 103 can match eol */
 YY_RULE_SETUP
-#line 597 "scan-gram.l"
+#line 642 "scan-gram.l"
 STRING_GROW; braces_level--;
 	YY_BREAK
-case 96:
-YY_RULE_SETUP
-#line 598 "scan-gram.l"
-{
-    bool outer_brace = --braces_level < 0;
-
-    /* As an undocumented Bison extension, append `;' before the last
-       brace in braced code, so that the user code can omit trailing
-       `;'.  But do not append `;' if emulating Yacc, since Yacc does
-       not append one.
-
-       FIXME: Bison should warn if a semicolon seems to be necessary
-       here, and should omit the semicolon if it seems unnecessary
-       (e.g., after ';', '{', or '}', each followed by comments or
-       white space).  Such a warning shouldn't depend on --yacc; it
-       should depend on a new --pedantic option, which would cause
-       Bison to warn if it detects an extension to POSIX.  --pedantic
-       should also diagnose other Bison extensions like %yacc.
-       Perhaps there should also be a GCC-style --pedantic-errors
-       option, so that such warnings are diagnosed as errors.  */
-    if (outer_brace && token_type == BRACED_CODE && ! yacc_flag)
-      obstack_1grow (&obstack_for_string, ';');
-
-    obstack_1grow (&obstack_for_string, '}');
-
-    if (outer_brace)
-      {
-	STRING_FINISH;
-	loc->start = code_start;
-	val->chars = last_string;
-	increment_rule_length (*loc);
-	last_braced_code_loc = *loc;
-	BEGIN INITIAL;
-	return token_type;
-      }
-  }
-	YY_BREAK
-/* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
-     (as `<' `<%').  */
-case 97:
-/* rule 97 can match eol */
-YY_RULE_SETUP
-#line 634 "scan-gram.l"
-STRING_GROW;
-	YY_BREAK
-case 98:
-YY_RULE_SETUP
-#line 636 "scan-gram.l"
-handle_dollar (token_type, gram_text, *loc);
-	YY_BREAK
-case 99:
-YY_RULE_SETUP
-#line 637 "scan-gram.l"
-handle_at (token_type, gram_text, *loc);
-	YY_BREAK
-case 100:
-YY_RULE_SETUP
-#line 639 "scan-gram.l"
-{
-    warn_at (*loc, _("stray `$'"));
-    obstack_sgrow (&obstack_for_string, "$][");
-  }
-	YY_BREAK
-case 101:
+case 104:
 YY_RULE_SETUP
 #line 643 "scan-gram.l"
 {
-    warn_at (*loc, _("stray `@'"));
-    obstack_sgrow (&obstack_for_string, "@@");
+    obstack_1grow (&obstack_for_string, '}');
+
+    --braces_level;
+    if (braces_level < 0)
+      {
+	STRING_FINISH;
+	loc->start = code_start;
+	val->code = last_string;
+	BEGIN INITIAL;
+	return BRACED_CODE;
+      }
   }
 	YY_BREAK
+/* Tokenize '<<%' correctly (as '<<' '%') rather than incorrrectly
+     (as '<' '<%').  */
+case 105:
+/* rule 105 can match eol */
+YY_RULE_SETUP
+#line 659 "scan-gram.l"
+STRING_GROW;
+	YY_BREAK
 case YY_STATE_EOF(SC_BRACED_CODE):
-#line 648 "scan-gram.l"
-unexpected_eof (code_start, "}"); BEGIN INITIAL;
+#line 661 "scan-gram.l"
+{
+    unexpected_eof (code_start, "}");
+    STRING_FINISH;
+    loc->start = code_start;
+    val->code = last_string;
+    BEGIN INITIAL;
+    return BRACED_CODE;
+  }
 	YY_BREAK
 
 /*--------------------------------------------------------------.
@@ -2226,9 +2376,9 @@
   `--------------------------------------------------------------*/
 
 
-case 102:
+case 106:
 YY_RULE_SETUP
-#line 658 "scan-gram.l"
+#line 678 "scan-gram.l"
 {
     STRING_FINISH;
     loc->start = code_start;
@@ -2238,8 +2388,15 @@
   }
 	YY_BREAK
 case YY_STATE_EOF(SC_PROLOGUE):
-#line 666 "scan-gram.l"
-unexpected_eof (code_start, "%}"); BEGIN INITIAL;
+#line 686 "scan-gram.l"
+{
+    unexpected_eof (code_start, "%}");
+    STRING_FINISH;
+    loc->start = code_start;
+    val->chars = last_string;
+    BEGIN INITIAL;
+    return PROLOGUE;
+  }
 	YY_BREAK
 
 /*---------------------------------------------------------------.
@@ -2249,7 +2406,7 @@
 
 
 case YY_STATE_EOF(SC_EPILOGUE):
-#line 677 "scan-gram.l"
+#line 704 "scan-gram.l"
 {
     STRING_FINISH;
     loc->start = code_start;
@@ -2259,49 +2416,25 @@
   }
 	YY_BREAK
 
-/*-----------------------------------------.
-  | Escape M4 quoting characters in C code.  |
-  `-----------------------------------------*/
-
-
-case 103:
-YY_RULE_SETUP
-#line 693 "scan-gram.l"
-obstack_sgrow (&obstack_for_string, "$][");
-	YY_BREAK
-case 104:
-YY_RULE_SETUP
-#line 694 "scan-gram.l"
-obstack_sgrow (&obstack_for_string, "@@");
-	YY_BREAK
-case 105:
-YY_RULE_SETUP
-#line 695 "scan-gram.l"
-obstack_sgrow (&obstack_for_string, "@{");
-	YY_BREAK
-case 106:
-YY_RULE_SETUP
-#line 696 "scan-gram.l"
-obstack_sgrow (&obstack_for_string, "@}");
-	YY_BREAK
-
 /*-----------------------------------------------------.
   | By default, grow the string obstack with the input.  |
   `-----------------------------------------------------*/
 case 107:
-#line 705 "scan-gram.l"
+#line 719 "scan-gram.l"
 case 108:
 /* rule 108 can match eol */
 YY_RULE_SETUP
-#line 705 "scan-gram.l"
+#line 719 "scan-gram.l"
 STRING_GROW;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 707 "scan-gram.l"
+#line 721 "scan-gram.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2305 "scan-gram.c"
+#line 2436 "scan-gram.c"
+case YY_STATE_EOF(SC_RETURN_BRACKETED_ID):
+	yyterminate();
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2499,21 +2632,21 @@
 
 	else
 		{
-			size_t num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
 			{ /* Not enough room in the buffer - grow it. */
 
 			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
 
 			int yy_c_buf_p_offset =
 				(int) ((yy_c_buf_p) - b->yy_ch_buf);
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -2568,6 +2701,14 @@
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
+	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) gram_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
 	(yy_n_chars) += number_to_move;
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -2606,7 +2747,7 @@
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 461 )
+			if ( yy_current_state >= 482 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2639,13 +2780,13 @@
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 461 )
+		if ( yy_current_state >= 482 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 460);
+	yy_is_jam = (yy_current_state == 481);
 
-	return yy_is_jam ? 0 : yy_current_state;
+		return yy_is_jam ? 0 : yy_current_state;
 }
 
 /* %if-c-only */
@@ -2680,7 +2821,7 @@
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -2865,13 +3006,6 @@
 	gram_free((void *) b  );
 }
 
-/* %if-c-only */
-
-/* %endif */
-
-/* %if-c++-only */
-/* %endif */
-
 /* Initializes or reinitializes a buffer.
  * This function is sometimes called more than once on the same buffer,
  * such as during a gram_restart() or at EOF.
@@ -3014,7 +3148,7 @@
 /* %if-c++-only */
 /* %endif */
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -3026,7 +3160,9 @@
 		(yy_buffer_stack) = (struct yy_buffer_state**)gram_alloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
-		
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in gram_ensure_buffer_stack()" );
+								  
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
 		(yy_buffer_stack_max) = num_to_alloc;
@@ -3044,6 +3180,8 @@
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in gram_ensure_buffer_stack()" );
 
 		/* zero only the new slots.*/
 		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -3092,28 +3230,28 @@
 /* %if-c-only */
 /** Setup the input buffer state to scan a string. The next call to gram_lex() will
  * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
  *       gram__scan_bytes() instead.
  */
-YY_BUFFER_STATE gram__scan_string (yyconst char * yy_str )
+YY_BUFFER_STATE gram__scan_string (yyconst char * yystr )
 {
     
-	return gram__scan_bytes(yy_str,strlen(yy_str) );
+	return gram__scan_bytes(yystr,strlen(yystr) );
 }
 /* %endif */
 
 /* %if-c-only */
 /** Setup the input buffer state to scan the given bytes. The next call to gram_lex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE gram__scan_bytes  (yyconst char * bytes, int  len )
+YY_BUFFER_STATE gram__scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
@@ -3121,15 +3259,15 @@
 	int i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = len + 2;
+	n = _yybytes_len + 2;
 	buf = (char *) gram_alloc(n  );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in gram__scan_bytes()" );
 
-	for ( i = 0; i < len; ++i )
-		buf[i] = bytes[i];
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
 
-	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
 	b = gram__scan_buffer(buf,n );
 	if ( ! b )
@@ -3209,7 +3347,7 @@
 /** Get the length of the current token.
  * 
  */
-int gram_get_leng  (void)
+yy_size_t gram_get_leng  (void)
 {
         return gram_leng;
 }
@@ -3267,6 +3405,36 @@
 /* %if-reentrant */
 /* %if-bison-bridge */
 /* %endif */
+/* %endif if-c-only */
+
+/* %if-c-only */
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from gram_lex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    gram_in = stdin;
+    gram_out = stdout;
+#else
+    gram_in = (FILE *) 0;
+    gram_out = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * gram_lex_init()
+     */
+    return 0;
+}
 /* %endif */
 
 /* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
@@ -3285,6 +3453,10 @@
 	gram_free((yy_buffer_stack) );
 	(yy_buffer_stack) = NULL;
 
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * gram_lex() is called, initialization will occur. */
+    yy_init_globals( );
+
 /* %if-reentrant */
 /* %endif */
     return 0;
@@ -3299,7 +3471,7 @@
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 {
 	register int i;
-    	for ( i = 0; i < n; ++i )
+	for ( i = 0; i < n; ++i )
 		s1[i] = s2[i];
 }
 #endif
@@ -3308,7 +3480,7 @@
 static int yy_flex_strlen (yyconst char * s )
 {
 	register int n;
-    	for ( n = 0; s[n]; ++n )
+	for ( n = 0; s[n]; ++n )
 		;
 
 	return n;
@@ -3344,93 +3516,8 @@
 
 /* %ok-for-header */
 
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
+#line 721 "scan-gram.l"
 
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-#line 707 "scan-gram.l"
-
-
-
-/* Keeps track of the maximum number of semantic values to the left of
-   a handle (those referenced by $0, $-1, etc.) are required by the
-   semantic actions of this grammar. */
-int max_left_semantic_context = 0;
-
-/* If BUF is null, add BUFSIZE (which in this case must be less than
-   INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
-   COLUMN.  If an overflow occurs, or might occur but is undetectable,
-   return INT_MAX.  Assume COLUMN is nonnegative.  */
-
-static inline int
-add_column_width (int column, char const *buf, size_t bufsize)
-{
-  size_t width;
-  unsigned int remaining_columns = INT_MAX - column;
-
-  if (buf)
-    {
-      if (INT_MAX / 2 <= bufsize)
-	return INT_MAX;
-      width = mbsnwidth (buf, bufsize, 0);
-    }
-  else
-    width = bufsize;
-
-  return width <= remaining_columns ? column + width : INT_MAX;
-}
-
-/* Set *LOC and adjust scanner cursor to account for token TOKEN of
-   size SIZE.  */
-
-static void
-adjust_location (location *loc, char const *token, size_t size)
-{
-  int line = scanner_cursor.line;
-  int column = scanner_cursor.column;
-  char const *p0 = token;
-  char const *p = token;
-  char const *lim = token + size;
-
-  loc->start = scanner_cursor;
-
-  for (p = token; p < lim; p++)
-    switch (*p)
-      {
-      case '\n':
-	line += line < INT_MAX;
-	column = 1;
-	p0 = p + 1;
-	break;
-
-      case '\t':
-	column = add_column_width (column, p0, p - p0);
-	column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
-	p0 = p + 1;
-	break;
-
-      default:
-	break;
-      }
-
-  scanner_cursor.line = line;
-  scanner_cursor.column = column = add_column_width (column, p0, p - p0);
-
-  loc->end = scanner_cursor;
-
-  if (line == INT_MAX && loc->start.line != INT_MAX)
-    warn_at (*loc, _("line number overflow"));
-  if (column == INT_MAX && loc->start.column != INT_MAX)
-    warn_at (*loc, _("column number overflow"));
-}
 
 
 /* Read bytes from FP into buffer BUF of size SIZE.  Return the
@@ -3480,173 +3567,6 @@
 }
 
 
-/*------------------------------------------------------------------.
-| TEXT is pointing to a wannabee semantic value (i.e., a `$').      |
-|                                                                   |
-| Possible inputs: $[<TYPENAME>]($|integer)                         |
-|                                                                   |
-| Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
-`------------------------------------------------------------------*/
-
-static inline bool
-handle_action_dollar (char *text, location loc)
-{
-  const char *type_name = NULL;
-  char *cp = text + 1;
-
-  if (! current_rule)
-    return false;
-
-  /* Get the type name if explicit. */
-  if (*cp == '<')
-    {
-      type_name = ++cp;
-      while (*cp != '>')
-	++cp;
-      *cp = '\0';
-      ++cp;
-    }
-
-  if (*cp == '$')
-    {
-      if (!type_name)
-	type_name = symbol_list_n_type_name_get (current_rule, loc, 0);
-      if (!type_name && typed)
-	complain_at (loc, _("$$ of `%s' has no declared type"),
-		     current_rule->sym->tag);
-      if (!type_name)
-	type_name = "";
-      obstack_fgrow1 (&obstack_for_string,
-		      "]b4_lhs_value([%s])[", type_name);
-      current_rule->used = true;
-    }
-  else
-    {
-      long int num = strtol (cp, NULL, 10);
-
-      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
-	{
-	  int n = num;
-	  if (max_left_semantic_context < 1 - n)
-	    max_left_semantic_context = 1 - n;
-	  if (!type_name && 0 < n)
-	    type_name = symbol_list_n_type_name_get (current_rule, loc, n);
-	  if (!type_name && typed)
-	    complain_at (loc, _("$%d of `%s' has no declared type"),
-			 n, current_rule->sym->tag);
-	  if (!type_name)
-	    type_name = "";
-	  obstack_fgrow3 (&obstack_for_string,
-			  "]b4_rhs_value(%d, %d, [%s])[",
-			  rule_length, n, type_name);
-	  symbol_list_n_used_set (current_rule, n, true);
-	}
-      else
-	complain_at (loc, _("integer out of range: %s"), quote (text));
-    }
-
-  return true;
-}
-
-
-/*----------------------------------------------------------------.
-| Map `$?' onto the proper M4 symbol, depending on its TOKEN_TYPE |
-| (are we in an action?).                                         |
-`----------------------------------------------------------------*/
-
-static void
-handle_dollar (int token_type, char *text, location loc)
-{
-  switch (token_type)
-    {
-    case BRACED_CODE:
-      if (handle_action_dollar (text, loc))
-	return;
-      break;
-
-    case PERCENT_DESTRUCTOR:
-    case PERCENT_INITIAL_ACTION:
-    case PERCENT_PRINTER:
-      if (text[1] == '$')
-	{
-	  obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
-	  return;
-	}
-      break;
-
-    default:
-      break;
-    }
-
-  complain_at (loc, _("invalid value: %s"), quote (text));
-}
-
-
-/*------------------------------------------------------.
-| TEXT is a location token (i.e., a `@...').  Output to |
-| OBSTACK_FOR_STRING a reference to this location.      |
-`------------------------------------------------------*/
-
-static inline bool
-handle_action_at (char *text, location loc)
-{
-  char *cp = text + 1;
-  locations_flag = true;
-
-  if (! current_rule)
-    return false;
-
-  if (*cp == '$')
-    obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
-  else
-    {
-      long int num = strtol (cp, NULL, 10);
-
-      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
-	{
-	  int n = num;
-	  obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
-			  rule_length, n);
-	}
-      else
-	complain_at (loc, _("integer out of range: %s"), quote (text));
-    }
-
-  return true;
-}
-
-
-/*----------------------------------------------------------------.
-| Map `@?' onto the proper M4 symbol, depending on its TOKEN_TYPE |
-| (are we in an action?).                                         |
-`----------------------------------------------------------------*/
-
-static void
-handle_at (int token_type, char *text, location loc)
-{
-  switch (token_type)
-    {
-    case BRACED_CODE:
-      handle_action_at (text, loc);
-      return;
-
-    case PERCENT_INITIAL_ACTION:
-    case PERCENT_DESTRUCTOR:
-    case PERCENT_PRINTER:
-      if (text[1] == '$')
-	{
-	  obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
-	  return;
-	}
-      break;
-
-    default:
-      break;
-    }
-
-  complain_at (loc, _("invalid value: %s"), quote (text));
-}
-
 
 /*------------------------------------------------------.
 | Scan NUMBER for a base-BASE integer at location LOC.  |
@@ -3725,36 +3645,28 @@
 }
 
 
-/*----------------------------------------------------------------.
-| Handle `#line INT "FILE"'.  ARGS has already skipped `#line '.  |
-`----------------------------------------------------------------*/
+/*---------------------------------------------------------------------.
+| Handle '#line INT( "FILE")?\n'.  ARGS has already skipped '#line '.  |
+`---------------------------------------------------------------------*/
 
 static void
 handle_syncline (char *args, location loc)
 {
-  char *after_num;
-  unsigned long int lineno = strtoul (args, &after_num, 10);
-  char *file = strchr (after_num, '"') + 1;
-  *strchr (file, '"') = '\0';
+  char *file;
+  unsigned long int lineno = strtoul (args, &file, 10);
   if (INT_MAX <= lineno)
     {
       warn_at (loc, _("line number overflow"));
       lineno = INT_MAX;
     }
-  scanner_cursor.file = current_file = uniqstr_new (file);
-  scanner_cursor.line = lineno;
-  scanner_cursor.column = 1;
-}
 
-
-/*---------------------------------.
-| Report a rule that is too long.  |
-`---------------------------------*/
-
-static void
-rule_length_overflow (location loc)
-{
-  fatal_at (loc, _("rule is too long"));
+  file = mbschr (file, '"');
+  if (file)
+    {
+      *mbschr (file + 1, '"') = '\0';
+      current_file = uniqstr_new (file + 1);
+    }
+  boundary_set (&scanner_cursor, current_file, lineno, 1);
 }
 
 
@@ -3770,6 +3682,10 @@
   location loc;
   loc.start = start;
   loc.end = scanner_cursor;
+  token_end = quote (token_end);
+  /* Instead of '\'', display "'".  */
+  if (!strcmp (token_end, "'\\''"))
+    token_end = "\"'\"";
   complain_at (loc, _(msgid), token_end);
 }
 
@@ -3782,7 +3698,7 @@
 static void
 unexpected_eof (boundary start, char const *token_end)
 {
-  unexpected_end (start, N_("missing `%s' at end of file"), token_end);
+  unexpected_end (start, N_("missing %s at end of file"), token_end);
 }
 
 
@@ -3793,7 +3709,7 @@
 static void
 unexpected_newline (boundary start, char const *token_end)
 {
-  unexpected_end (start, N_("missing `%s' at end of line"), token_end);
+  unexpected_end (start, N_("missing %s at end of line"), token_end);
 }
 
 
@@ -3802,7 +3718,7 @@
 `-------------------------*/
 
 void
-scanner_initialize (void)
+gram_scanner_initialize (void)
 {
   obstack_init (&obstack_for_string);
 }
@@ -3813,10 +3729,10 @@
 `-----------------------------------------------*/
 
 void
-scanner_free (void)
+gram_scanner_free (void)
 {
   obstack_free (&obstack_for_string, 0);
   /* Reclaim Flex's buffers.  */
-  gram__delete_buffer (YY_CURRENT_BUFFER);
+  gram_lex_destroy ();
 }
 
diff --git a/src/scan-gram.h b/src/scan-gram.h
new file mode 100644
index 0000000..72138a2
--- /dev/null
+++ b/src/scan-gram.h
@@ -0,0 +1,38 @@
+/* Bison Grammar Scanner
+
+   Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
+
+   This file is part of Bison, the GNU Compiler Compiler.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef SCAN_GRAM_H_
+# define SCAN_GRAM_H_
+
+/* From the scanner.  */
+extern FILE *gram_in;
+extern int gram__flex_debug;
+void gram_scanner_initialize (void);
+void gram_scanner_free (void);
+void gram_scanner_last_string_free (void);
+
+/* These are declared by the scanner, but not used.  We put them here
+   to pacify "make syntax-check".  */
+extern FILE *gram_out;
+extern int gram_lineno;
+
+# define GRAM_LEX_DECL int gram_lex (GRAM_STYPE *val, location *loc)
+GRAM_LEX_DECL;
+
+#endif /* !SCAN_GRAM_H_ */
diff --git a/src/scan-gram.l b/src/scan-gram.l
index cf704c7..9083dce 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -1,12 +1,12 @@
 /* Bison Grammar Scanner                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   This program is free software; you can redistribute it and/or modify
+   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 2 of the License, or
+   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,
@@ -15,12 +15,9 @@
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301  USA
-*/
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-%option debug nodefault nounput noyywrap never-interactive
+%option debug nodefault noinput nounput noyywrap never-interactive
 %option prefix="gram_" outfile="lex.yy.c"
 
 %{
@@ -29,112 +26,56 @@
 #undef gram_wrap
 #define gram_wrap() 1
 
-#include "system.h"
-
-#include <mbswidth.h>
-#include <quote.h>
+#define FLEX_PREFIX(Id) gram_ ## Id
+#include "flex-scanner.h"
 
 #include "complain.h"
 #include "files.h"
-#include "getargs.h"
 #include "gram.h"
 #include "quotearg.h"
 #include "reader.h"
 #include "uniqstr.h"
 
-#define YY_USER_INIT					\
-  do							\
-    {							\
-      scanner_cursor.file = current_file;		\
-      scanner_cursor.line = 1;				\
-      scanner_cursor.column = 1;			\
-      code_start = scanner_cursor;			\
-    }							\
-  while (0)
+#include <c-ctype.h>
+#include <mbswidth.h>
+#include <quote.h>
 
-/* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
-int gram_get_lineno (void);
-FILE *gram_get_in (void);
-FILE *gram_get_out (void);
-int gram_get_leng (void);
-char *gram_get_text (void);
-void gram_set_lineno (int);
-void gram_set_in (FILE *);
-void gram_set_out (FILE *);
-int gram_get_debug (void);
-void gram_set_debug (int);
-int gram_lex_destroy (void);
+#include "scan-gram.h"
+
+#define YY_DECL GRAM_LEX_DECL
+
+#define YY_USER_INIT					\
+   code_start = scanner_cursor = loc->start;		\
 
 /* Location of scanner cursor.  */
-boundary scanner_cursor;
+static boundary scanner_cursor;
 
-static void adjust_location (location *, char const *, size_t);
-#define YY_USER_ACTION  adjust_location (loc, yytext, yyleng);
+#define YY_USER_ACTION  location_compute (loc, &scanner_cursor, yytext, yyleng);
 
 static size_t no_cr_read (FILE *, char *, size_t);
 #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
 
-
-/* OBSTACK_FOR_STRING -- Used to store all the characters that we need to
-   keep (to construct ID, STRINGS etc.).  Use the following macros to
-   use it.
-
-   Use STRING_GROW to append what has just been matched, and
-   STRING_FINISH to end the string (it puts the ending 0).
-   STRING_FINISH also stores this string in LAST_STRING, which can be
-   used, and which is used by STRING_FREE to free the last string.  */
-
-static struct obstack obstack_for_string;
-
-/* A string representing the most recently saved token.  */
-char *last_string;
-
-/* The location of the most recently saved token, if it was a
-   BRACED_CODE token; otherwise, this has an unspecified value.  */
-location last_braced_code_loc;
-
-#define STRING_GROW   \
-  obstack_grow (&obstack_for_string, yytext, yyleng)
-
-#define STRING_FINISH					\
-  do {							\
-    obstack_1grow (&obstack_for_string, '\0');		\
-    last_string = obstack_finish (&obstack_for_string);	\
+#define ROLLBACK_CURRENT_TOKEN                                  \
+  do {                                                          \
+    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);	\
+    yyless (0);                                                 \
   } while (0)
 
-#define STRING_FREE \
-  obstack_free (&obstack_for_string, last_string)
+/* A string representing the most recently saved token.  */
+static char *last_string;
+
+/* Bracketed identifier. */
+static uniqstr bracketed_id_str = 0;
+static location bracketed_id_loc;
+static boundary bracketed_id_start;
+static int bracketed_id_context_state = 0;
 
 void
-scanner_last_string_free (void)
+gram_scanner_last_string_free (void)
 {
   STRING_FREE;
 }
 
-/* Within well-formed rules, RULE_LENGTH is the number of values in
-   the current rule so far, which says where to find `$0' with respect
-   to the top of the stack.  It is not the same as the rule->length in
-   the case of mid rule actions.
-
-   Outside of well-formed rules, RULE_LENGTH has an undefined value.  */
-static int rule_length;
-
-static void rule_length_overflow (location) __attribute__ ((__noreturn__));
-
-/* Increment the rule length by one, checking for overflow.  */
-static inline void
-increment_rule_length (location loc)
-{
-  rule_length++;
-
-  /* Don't allow rule_length == INT_MAX, since that might cause
-     confusion with strtol if INT_MAX == LONG_MAX.  */
-  if (rule_length == INT_MAX)
-    rule_length_overflow (loc);
-}
-
-static void handle_dollar (int token_type, char *cp, location loc);
-static void handle_at (int token_type, char *cp, location loc);
 static void handle_syncline (char *, location);
 static unsigned long int scan_integer (char const *p, int base, location loc);
 static int convert_ucn_to_byte (char const *hex_text);
@@ -142,15 +83,29 @@
 static void unexpected_newline (boundary, char const *);
 
 %}
-%x SC_COMMENT SC_LINE_COMMENT SC_YACC_COMMENT
-%x SC_STRING SC_CHARACTER
-%x SC_AFTER_IDENTIFIER
+ /* A C-like comment in directives/rules. */
+%x SC_YACC_COMMENT
+ /* Strings and characters in directives/rules. */
 %x SC_ESCAPED_STRING SC_ESCAPED_CHARACTER
-%x SC_PRE_CODE SC_BRACED_CODE SC_PROLOGUE SC_EPILOGUE
+ /* A identifier was just read in directives/rules.  Special state
+    to capture the sequence 'identifier :'. */
+%x SC_AFTER_IDENTIFIER
 
-letter	  [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
-id	  {letter}({letter}|[0-9])*
-directive %{letter}({letter}|[0-9]|-)*
+ /* Three types of user code:
+    - prologue (code between '%{' '%}' in the first section, before %%);
+    - actions, printers, union, etc, (between braced in the middle section);
+    - epilogue (everything after the second %%). */
+%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE
+ /* C and C++ comments in code. */
+%x SC_COMMENT SC_LINE_COMMENT
+ /* Strings and characters in code. */
+%x SC_STRING SC_CHARACTER
+ /* Bracketed identifiers support. */
+%x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID
+
+letter	   [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
+notletter [^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{]
+id	  {letter}({letter}|[-0-9])*
 int	  [0-9]+
 
 /* POSIX says that a tag must be both an id and a C union member, but
@@ -165,16 +120,13 @@
 %%
 %{
   /* Nesting level of the current code in braces.  */
-  int braces_level IF_LINT (= 0);
+  int braces_level PACIFY_CC (= 0);
 
   /* Parent context state, when applicable.  */
-  int context_state IF_LINT (= 0);
-
-  /* Token type to return, when applicable.  */
-  int token_type IF_LINT (= 0);
+  int context_state PACIFY_CC (= 0);
 
   /* Location of most recent identifier, when applicable.  */
-  location id_loc IF_LINT (= empty_location);
+  location id_loc PACIFY_CC (= empty_location);
 
   /* Where containing code started, when applicable.  Its initial
      value is relevant only when yylex is invoked in the SC_EPILOGUE
@@ -183,7 +135,7 @@
 
   /* Where containing comment or string or character literal started,
      when applicable.  */
-  boundary token_start IF_LINT (= scanner_cursor);
+  boundary token_start PACIFY_CC (= scanner_cursor);
 %}
 
 
@@ -191,12 +143,12 @@
   | Scanning white space.  |
   `-----------------------*/
 
-<INITIAL,SC_AFTER_IDENTIFIER,SC_PRE_CODE>
+<INITIAL,SC_AFTER_IDENTIFIER,SC_BRACKETED_ID,SC_RETURN_BRACKETED_ID>
 {
   /* Comments and white space.  */
-  ","	       warn_at (*loc, _("stray `,' treated as white space"));
+  ","          warn_at (*loc, _("stray ',' treated as white space"));
   [ \f\n\t\v]  |
-  "//".*       ;
+  "//".*       continue;
   "/*" {
     token_start = loc->start;
     context_state = YY_START;
@@ -205,7 +157,7 @@
 
   /* #line directives are not documented, and may be withdrawn or
      modified in future versions of Bison.  */
-  ^"#line "{int}" \"".*"\"\n" {
+  ^"#line "{int}(" \"".*"\"")?"\n" {
     handle_syncline (yytext + sizeof "#line " - 1, *loc);
   }
 }
@@ -214,61 +166,72 @@
   /*----------------------------.
   | Scanning Bison directives.  |
   `----------------------------*/
+
+  /* For directives that are also command line options, the regex must be
+	"%..."
+     after "[-_]"s are removed, and the directive must match the --long
+     option name, with a single string argument.  Otherwise, add exceptions
+     to ../build-aux/cross-options.pl.  */
+
 <INITIAL>
 {
-  "%binary"               return PERCENT_NONASSOC;
-  "%debug"                return PERCENT_DEBUG;
-  "%default"[-_]"prec"    return PERCENT_DEFAULT_PREC;
-  "%define"               return PERCENT_DEFINE;
-  "%defines"              return PERCENT_DEFINES;
-  "%destructor"		  token_type = PERCENT_DESTRUCTOR; BEGIN SC_PRE_CODE;
-  "%dprec"		  return PERCENT_DPREC;
-  "%error"[-_]"verbose"   return PERCENT_ERROR_VERBOSE;
-  "%expect"               return PERCENT_EXPECT;
-  "%expect"[-_]"rr"	  return PERCENT_EXPECT_RR;
-  "%file-prefix"          return PERCENT_FILE_PREFIX;
+  "%binary"                         return PERCENT_NONASSOC;
+  "%code"                           return PERCENT_CODE;
+  "%debug"                          return PERCENT_DEBUG;
+  "%default"[-_]"prec"              return PERCENT_DEFAULT_PREC;
+  "%define"                         return PERCENT_DEFINE;
+  "%defines"                        return PERCENT_DEFINES;
+  "%destructor"                     return PERCENT_DESTRUCTOR;
+  "%dprec"                          return PERCENT_DPREC;
+  "%error"[-_]"verbose"             return PERCENT_ERROR_VERBOSE;
+  "%expect"                         return PERCENT_EXPECT;
+  "%expect"[-_]"rr"                 return PERCENT_EXPECT_RR;
+  "%file-prefix"                    return PERCENT_FILE_PREFIX;
   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
-  "%initial-action"       token_type = PERCENT_INITIAL_ACTION; BEGIN SC_PRE_CODE;
-  "%glr-parser"           return PERCENT_GLR_PARSER;
-  "%left"                 return PERCENT_LEFT;
-  "%lex-param"		  token_type = PERCENT_LEX_PARAM; BEGIN SC_PRE_CODE;
-  "%locations"            return PERCENT_LOCATIONS;
-  "%merge"		  return PERCENT_MERGE;
-  "%name"[-_]"prefix"     return PERCENT_NAME_PREFIX;
-  "%no"[-_]"default"[-_]"prec"	return PERCENT_NO_DEFAULT_PREC;
-  "%no"[-_]"lines"        return PERCENT_NO_LINES;
-  "%nonassoc"             return PERCENT_NONASSOC;
-  "%nondeterministic-parser"   return PERCENT_NONDETERMINISTIC_PARSER;
-  "%nterm"                return PERCENT_NTERM;
-  "%output"               return PERCENT_OUTPUT;
-  "%parse-param"	  token_type = PERCENT_PARSE_PARAM; BEGIN SC_PRE_CODE;
-  "%prec"                 rule_length--; return PERCENT_PREC;
-  "%printer"              token_type = PERCENT_PRINTER; BEGIN SC_PRE_CODE;
-  "%pure"[-_]"parser"     return PERCENT_PURE_PARSER;
-  "%require"              return PERCENT_REQUIRE;
-  "%right"                return PERCENT_RIGHT;
-  "%skeleton"             return PERCENT_SKELETON;
-  "%start"                return PERCENT_START;
-  "%term"                 return PERCENT_TOKEN;
-  "%token"                return PERCENT_TOKEN;
-  "%token"[-_]"table"     return PERCENT_TOKEN_TABLE;
-  "%type"                 return PERCENT_TYPE;
-  "%union"		  token_type = PERCENT_UNION; BEGIN SC_PRE_CODE;
-  "%verbose"              return PERCENT_VERBOSE;
-  "%yacc"                 return PERCENT_YACC;
+  "%initial-action"                 return PERCENT_INITIAL_ACTION;
+  "%glr-parser"                     return PERCENT_GLR_PARSER;
+  "%language"                       return PERCENT_LANGUAGE;
+  "%left"                           return PERCENT_LEFT;
+  "%lex-param"                      return PERCENT_LEX_PARAM;
+  "%locations"                      return PERCENT_LOCATIONS;
+  "%merge"                          return PERCENT_MERGE;
+  "%name"[-_]"prefix"               return PERCENT_NAME_PREFIX;
+  "%no"[-_]"default"[-_]"prec"      return PERCENT_NO_DEFAULT_PREC;
+  "%no"[-_]"lines"                  return PERCENT_NO_LINES;
+  "%nonassoc"                       return PERCENT_NONASSOC;
+  "%nondeterministic-parser"        return PERCENT_NONDETERMINISTIC_PARSER;
+  "%nterm"                          return PERCENT_NTERM;
+  "%output"                         return PERCENT_OUTPUT;
+  "%parse-param"                    return PERCENT_PARSE_PARAM;
+  "%prec"                           return PERCENT_PREC;
+  "%printer"                        return PERCENT_PRINTER;
+  "%pure"[-_]"parser"               return PERCENT_PURE_PARSER;
+  "%require"                        return PERCENT_REQUIRE;
+  "%right"                          return PERCENT_RIGHT;
+  "%skeleton"                       return PERCENT_SKELETON;
+  "%start"                          return PERCENT_START;
+  "%term"                           return PERCENT_TOKEN;
+  "%token"                          return PERCENT_TOKEN;
+  "%token"[-_]"table"               return PERCENT_TOKEN_TABLE;
+  "%type"                           return PERCENT_TYPE;
+  "%union"                          return PERCENT_UNION;
+  "%verbose"                        return PERCENT_VERBOSE;
+  "%yacc"                           return PERCENT_YACC;
 
-  {directive} {
+  "%"{id}|"%"{notletter}([[:graph:]])+ {
     complain_at (*loc, _("invalid directive: %s"), quote (yytext));
   }
 
   "="                     return EQUAL;
-  "|"                     rule_length = 0; return PIPE;
+  "|"                     return PIPE;
   ";"                     return SEMICOLON;
+  "<*>"                   return TYPE_TAG_ANY;
+  "<>"                    return TYPE_TAG_NONE;
 
   {id} {
-    val->symbol = symbol_get (yytext, *loc);
+    val->uniqstr = uniqstr_new (yytext);
     id_loc = *loc;
-    increment_rule_length (*loc);
+    bracketed_id_str = NULL;
     BEGIN SC_AFTER_IDENTIFIER;
   }
 
@@ -281,8 +244,14 @@
     return INT;
   }
 
-  /* Characters.  We don't check there is only one.  */
-  "'"	      STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
+  /* Identifiers may not start with a digit.  Yet, don't silently
+     accept "1FOO" as "1 FOO".  */
+  {int}{id} {
+    complain_at (*loc, _("invalid identifier: %s"), quote (yytext));
+  }
+
+  /* Characters.  */
+  "'"	      token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
 
   /* Strings. */
   "\""	      token_start = loc->start; BEGIN SC_ESCAPED_STRING;
@@ -292,10 +261,7 @@
 
   /* Code in between braces.  */
   "{" {
-    if (current_rule && current_rule->action)
-      grammar_midrule_action ();
     STRING_GROW;
-    token_type = BRACED_CODE;
     braces_level = 0;
     code_start = loc->start;
     BEGIN SC_BRACED_CODE;
@@ -317,8 +283,17 @@
     return PERCENT_PERCENT;
   }
 
-  . {
-    complain_at (*loc, _("invalid character: %s"), quote (yytext));
+  "[" {
+    bracketed_id_str = NULL;
+    bracketed_id_start = loc->start;
+    bracketed_id_context_state = YY_START;
+    BEGIN SC_BRACKETED_ID;
+  }
+
+  [^\[%A-Za-z0-9_<>{}\"\'*;|=/, \f\n\t\v]+|. {
+    complain_at (*loc, "%s: %s",
+                 ngettext ("invalid character", "invalid characters", yyleng),
+                 quote_mem (yytext, yyleng));
   }
 
   <<EOF>> {
@@ -334,41 +309,113 @@
 
 <SC_AFTER_IDENTIFIER>
 {
+  "[" {
+    if (bracketed_id_str)
+      {
+	ROLLBACK_CURRENT_TOKEN;
+	BEGIN SC_RETURN_BRACKETED_ID;
+	*loc = id_loc;
+	return ID;
+      }
+    else
+      {
+	bracketed_id_start = loc->start;
+	bracketed_id_context_state = YY_START;
+	BEGIN SC_BRACKETED_ID;
+      }
+  }
   ":" {
-    rule_length = 0;
+    BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
-    BEGIN INITIAL;
     return ID_COLON;
   }
   . {
-    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);
-    yyless (0);
+    ROLLBACK_CURRENT_TOKEN;
+    BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
-    BEGIN INITIAL;
     return ID;
   }
   <<EOF>> {
+    BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
-    BEGIN INITIAL;
     return ID;
   }
 }
 
+  /*--------------------------------.
+  | Scanning bracketed identifiers. |
+  `--------------------------------*/
+
+<SC_BRACKETED_ID>
+{
+  {id} {
+    if (bracketed_id_str)
+      {
+	complain_at (*loc, _("unexpected identifier in bracketed name: %s"),
+		     quote (yytext));
+      }
+    else
+      {
+	bracketed_id_str = uniqstr_new (yytext);
+	bracketed_id_loc = *loc;
+      }
+  }
+  "]" {
+    BEGIN bracketed_id_context_state;
+    if (bracketed_id_str)
+      {
+	if (INITIAL == bracketed_id_context_state)
+	  {
+	    val->uniqstr = bracketed_id_str;
+	    bracketed_id_str = 0;
+	    *loc = bracketed_id_loc;
+	    return BRACKETED_ID;
+	  }
+      }
+    else
+      complain_at (*loc, _("an identifier expected"));
+  }
+
+  [^\].A-Za-z0-9_/ \f\n\t\v]+|. {
+    complain_at (*loc, "%s: %s",
+                 ngettext ("invalid character in bracketed name",
+                           "invalid characters in bracketed name", yyleng),
+                 quote_mem (yytext, yyleng));
+  }
+
+  <<EOF>> {
+    BEGIN bracketed_id_context_state;
+    unexpected_eof (bracketed_id_start, "]");
+  }
+}
+
+<SC_RETURN_BRACKETED_ID>
+{
+  . {
+    ROLLBACK_CURRENT_TOKEN;
+    val->uniqstr = bracketed_id_str;
+    bracketed_id_str = 0;
+    *loc = bracketed_id_loc;
+    BEGIN INITIAL;
+    return BRACKETED_ID;
+  }
+}
+
 
   /*---------------------------------------------------------------.
-  | Scanning a Yacc comment.  The initial `/ *' is already eaten.  |
+  | Scanning a Yacc comment.  The initial '/ *' is already eaten.  |
   `---------------------------------------------------------------*/
 
 <SC_YACC_COMMENT>
 {
   "*/"     BEGIN context_state;
-  .|\n	   ;
+  .|\n	   continue;
   <<EOF>>  unexpected_eof (token_start, "*/"); BEGIN context_state;
 }
 
 
   /*------------------------------------------------------------.
-  | Scanning a C comment.  The initial `/ *' is already eaten.  |
+  | Scanning a C comment.  The initial '/ *' is already eaten.  |
   `------------------------------------------------------------*/
 
 <SC_COMMENT>
@@ -379,7 +426,7 @@
 
 
   /*--------------------------------------------------------------.
-  | Scanning a line comment.  The initial `//' is already eaten.  |
+  | Scanning a line comment.  The initial '//' is already eaten.  |
   `--------------------------------------------------------------*/
 
 <SC_LINE_COMMENT>
@@ -397,16 +444,23 @@
 
 <SC_ESCAPED_STRING>
 {
-  "\"" {
+  "\""|"\n" {
+    if (yytext[0] == '\n')
+      unexpected_newline (token_start, "\"");
     STRING_FINISH;
     loc->start = token_start;
     val->chars = last_string;
-    increment_rule_length (*loc);
     BEGIN INITIAL;
     return STRING;
   }
-  \n		unexpected_newline (token_start, "\"");	BEGIN INITIAL;
-  <<EOF>>	unexpected_eof (token_start, "\"");	BEGIN INITIAL;
+  <<EOF>> {
+    unexpected_eof (token_start, "\"");
+    STRING_FINISH;
+    loc->start = token_start;
+    val->chars = last_string;
+    BEGIN INITIAL;
+    return STRING;
+  }
 }
 
   /*----------------------------------------------------------.
@@ -416,24 +470,47 @@
 
 <SC_ESCAPED_CHARACTER>
 {
-  "'" {
-    unsigned char last_string_1;
-    STRING_GROW;
+  "'"|"\n" {
     STRING_FINISH;
     loc->start = token_start;
-    val->symbol = symbol_get (quotearg_style (escape_quoting_style,
-					      last_string),
-			      *loc);
-    symbol_class_set (val->symbol, token_sym, *loc, false);
-    last_string_1 = last_string[1];
-    symbol_user_token_number_set (val->symbol, last_string_1, *loc);
+    val->character = last_string[0];
+    {
+      /* FIXME: Eventually, make these errors.  */
+      if (last_string[0] == '\0')
+        {
+          warn_at (*loc, _("empty character literal"));
+          /* '\0' seems dangerous even if we are about to complain.  */
+          val->character = '\'';
+        }
+      else if (last_string[1] != '\0')
+        warn_at (*loc, _("extra characters in character literal"));
+    }
+    if (yytext[0] == '\n')
+      unexpected_newline (token_start, "'");
     STRING_FREE;
-    increment_rule_length (*loc);
     BEGIN INITIAL;
-    return ID;
+    return CHAR;
   }
-  \n		unexpected_newline (token_start, "'");	BEGIN INITIAL;
-  <<EOF>>	unexpected_eof (token_start, "'");	BEGIN INITIAL;
+  <<EOF>> {
+    STRING_FINISH;
+    loc->start = token_start;
+    val->character = last_string[0];
+    {
+      /* FIXME: Eventually, make these errors.  */
+      if (last_string[0] == '\0')
+        {
+          warn_at (*loc, _("empty character literal"));
+          /* '\0' seems dangerous even if we are about to complain.  */
+          val->character = '\'';
+        }
+      else if (last_string[1] != '\0')
+        warn_at (*loc, _("extra characters in character literal"));
+    }
+    unexpected_eof (token_start, "'");
+    STRING_FREE;
+    BEGIN INITIAL;
+    return CHAR;
+  }
 }
 
 <SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING>
@@ -450,10 +527,9 @@
 {
   \\[0-7]{1,3} {
     unsigned long int c = strtoul (yytext + 1, NULL, 8);
-    if (UCHAR_MAX < c)
-      complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
-    else if (! c)
-      complain_at (*loc, _("invalid null character: %s"), quote (yytext));
+    if (!c || UCHAR_MAX < c)
+      complain_at (*loc, _("invalid number after \\-escape: %s"),
+                   yytext+1);
     else
       obstack_1grow (&obstack_for_string, c);
   }
@@ -461,10 +537,9 @@
   \\x[0-9abcdefABCDEF]+ {
     verify (UCHAR_MAX < ULONG_MAX);
     unsigned long int c = strtoul (yytext + 2, NULL, 16);
-    if (UCHAR_MAX < c)
-      complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
-    else if (! c)
-      complain_at (*loc, _("invalid null character: %s"), quote (yytext));
+    if (!c || UCHAR_MAX < c)
+      complain_at (*loc, _("invalid number after \\-escape: %s"),
+                   yytext+1);
     else
       obstack_1grow (&obstack_for_string, c);
   }
@@ -482,16 +557,20 @@
 
   \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
     int c = convert_ucn_to_byte (yytext);
-    if (c < 0)
-      complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
-    else if (! c)
-      complain_at (*loc, _("invalid null character: %s"), quote (yytext));
+    if (c <= 0)
+      complain_at (*loc, _("invalid number after \\-escape: %s"),
+                   yytext+1);
     else
       obstack_1grow (&obstack_for_string, c);
   }
   \\(.|\n)	{
-    complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext));
-    STRING_GROW;
+    char const *p = yytext + 1;
+    /* Quote only if escaping won't make the character visible.  */
+    if (c_isspace ((unsigned char) *p) && c_isprint ((unsigned char) *p))
+      p = quote (p);
+    else
+      p = quotearg_style_mem (escape_quoting_style, p, 1);
+    complain_at (*loc, _("invalid character after \\-escape: %s"), p);
   }
 }
 
@@ -501,7 +580,7 @@
 
 <SC_CHARACTER,SC_STRING>
 {
-  {splice}|\\{splice}[^\n$@\[\]]	STRING_GROW;
+  {splice}|\\{splice}[^\n\[\]]	STRING_GROW;
 }
 
 <SC_CHARACTER>
@@ -551,101 +630,42 @@
 }
 
 
-  /*---------------------------------------------------------------.
-  | Scanning after %union etc., possibly followed by white space.  |
-  | For %union only, allow arbitrary C code to appear before the   |
-  | following brace, as an extension to POSIX.			   |
-  `---------------------------------------------------------------*/
 
-<SC_PRE_CODE>
-{
-  . {
-    bool valid = yytext[0] == '{' || token_type == PERCENT_UNION;
-    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);
-    yyless (0);
-
-    if (valid)
-      {
-	braces_level = -1;
-	code_start = loc->start;
-	BEGIN SC_BRACED_CODE;
-      }
-    else
-      {
-	complain_at (*loc, _("missing `{' in %s"),
-		     token_name (token_type));
-	obstack_sgrow (&obstack_for_string, "{}");
-	STRING_FINISH;
-	val->chars = last_string;
-	BEGIN INITIAL;
-	return token_type;
-      }
-  }
-
-  <<EOF>>  unexpected_eof (scanner_cursor, "{}"); BEGIN INITIAL;
-}
-
-
-  /*---------------------------------------------------------------.
-  | Scanning some code in braces (%union and actions). The initial |
-  | "{" is already eaten.                                          |
-  `---------------------------------------------------------------*/
+  /*-----------------------------------------------------------.
+  | Scanning some code in braces (actions). The initial "{" is |
+  | already eaten.                                             |
+  `-----------------------------------------------------------*/
 
 <SC_BRACED_CODE>
 {
   "{"|"<"{splice}"%"  STRING_GROW; braces_level++;
   "%"{splice}">"      STRING_GROW; braces_level--;
   "}" {
-    bool outer_brace = --braces_level < 0;
-
-    /* As an undocumented Bison extension, append `;' before the last
-       brace in braced code, so that the user code can omit trailing
-       `;'.  But do not append `;' if emulating Yacc, since Yacc does
-       not append one.
-
-       FIXME: Bison should warn if a semicolon seems to be necessary
-       here, and should omit the semicolon if it seems unnecessary
-       (e.g., after ';', '{', or '}', each followed by comments or
-       white space).  Such a warning shouldn't depend on --yacc; it
-       should depend on a new --pedantic option, which would cause
-       Bison to warn if it detects an extension to POSIX.  --pedantic
-       should also diagnose other Bison extensions like %yacc.
-       Perhaps there should also be a GCC-style --pedantic-errors
-       option, so that such warnings are diagnosed as errors.  */
-    if (outer_brace && token_type == BRACED_CODE && ! yacc_flag)
-      obstack_1grow (&obstack_for_string, ';');
-
     obstack_1grow (&obstack_for_string, '}');
 
-    if (outer_brace)
+    --braces_level;
+    if (braces_level < 0)
       {
 	STRING_FINISH;
 	loc->start = code_start;
-	val->chars = last_string;
-	increment_rule_length (*loc);
-	last_braced_code_loc = *loc;
+	val->code = last_string;
 	BEGIN INITIAL;
-	return token_type;
+	return BRACED_CODE;
       }
   }
 
-  /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
-     (as `<' `<%').  */
+  /* Tokenize '<<%' correctly (as '<<' '%') rather than incorrrectly
+     (as '<' '<%').  */
   "<"{splice}"<"  STRING_GROW;
 
-  "$"("<"{tag}">")?(-?[0-9]+|"$")  handle_dollar (token_type, yytext, *loc);
-  "@"(-?[0-9]+|"$")		   handle_at (token_type, yytext, *loc);
-
-  "$"  {
-    warn_at (*loc, _("stray `$'"));
-    obstack_sgrow (&obstack_for_string, "$][");
+  <<EOF>> {
+    unexpected_eof (code_start, "}");
+    STRING_FINISH;
+    loc->start = code_start;
+    val->code = last_string;
+    BEGIN INITIAL;
+    return BRACED_CODE;
   }
-  "@"  {
-    warn_at (*loc, _("stray `@'"));
-    obstack_sgrow (&obstack_for_string, "@@");
-  }
-
-  <<EOF>>  unexpected_eof (code_start, "}"); BEGIN INITIAL;
 }
 
 
@@ -663,7 +683,14 @@
     return PROLOGUE;
   }
 
-  <<EOF>>  unexpected_eof (code_start, "%}"); BEGIN INITIAL;
+  <<EOF>> {
+    unexpected_eof (code_start, "%}");
+    STRING_FINISH;
+    loc->start = code_start;
+    val->chars = last_string;
+    BEGIN INITIAL;
+    return PROLOGUE;
+  }
 }
 
 
@@ -684,19 +711,6 @@
 }
 
 
-  /*-----------------------------------------.
-  | Escape M4 quoting characters in C code.  |
-  `-----------------------------------------*/
-
-<SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
-{
-  \$	obstack_sgrow (&obstack_for_string, "$][");
-  \@	obstack_sgrow (&obstack_for_string, "@@");
-  \[	obstack_sgrow (&obstack_for_string, "@{");
-  \]	obstack_sgrow (&obstack_for_string, "@}");
-}
-
-
   /*-----------------------------------------------------.
   | By default, grow the string obstack with the input.  |
   `-----------------------------------------------------*/
@@ -706,79 +720,6 @@
 
 %%
 
-/* Keeps track of the maximum number of semantic values to the left of
-   a handle (those referenced by $0, $-1, etc.) are required by the
-   semantic actions of this grammar. */
-int max_left_semantic_context = 0;
-
-/* If BUF is null, add BUFSIZE (which in this case must be less than
-   INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
-   COLUMN.  If an overflow occurs, or might occur but is undetectable,
-   return INT_MAX.  Assume COLUMN is nonnegative.  */
-
-static inline int
-add_column_width (int column, char const *buf, size_t bufsize)
-{
-  size_t width;
-  unsigned int remaining_columns = INT_MAX - column;
-
-  if (buf)
-    {
-      if (INT_MAX / 2 <= bufsize)
-	return INT_MAX;
-      width = mbsnwidth (buf, bufsize, 0);
-    }
-  else
-    width = bufsize;
-
-  return width <= remaining_columns ? column + width : INT_MAX;
-}
-
-/* Set *LOC and adjust scanner cursor to account for token TOKEN of
-   size SIZE.  */
-
-static void
-adjust_location (location *loc, char const *token, size_t size)
-{
-  int line = scanner_cursor.line;
-  int column = scanner_cursor.column;
-  char const *p0 = token;
-  char const *p = token;
-  char const *lim = token + size;
-
-  loc->start = scanner_cursor;
-
-  for (p = token; p < lim; p++)
-    switch (*p)
-      {
-      case '\n':
-	line += line < INT_MAX;
-	column = 1;
-	p0 = p + 1;
-	break;
-
-      case '\t':
-	column = add_column_width (column, p0, p - p0);
-	column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
-	p0 = p + 1;
-	break;
-
-      default:
-	break;
-      }
-
-  scanner_cursor.line = line;
-  scanner_cursor.column = column = add_column_width (column, p0, p - p0);
-
-  loc->end = scanner_cursor;
-
-  if (line == INT_MAX && loc->start.line != INT_MAX)
-    warn_at (*loc, _("line number overflow"));
-  if (column == INT_MAX && loc->start.column != INT_MAX)
-    warn_at (*loc, _("column number overflow"));
-}
-
-
 /* Read bytes from FP into buffer BUF of size SIZE.  Return the
    number of bytes read.  Remove '\r' from input, treating \r\n
    and isolated \r as \n.  */
@@ -826,173 +767,6 @@
 }
 
 
-/*------------------------------------------------------------------.
-| TEXT is pointing to a wannabee semantic value (i.e., a `$').      |
-|                                                                   |
-| Possible inputs: $[<TYPENAME>]($|integer)                         |
-|                                                                   |
-| Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
-`------------------------------------------------------------------*/
-
-static inline bool
-handle_action_dollar (char *text, location loc)
-{
-  const char *type_name = NULL;
-  char *cp = text + 1;
-
-  if (! current_rule)
-    return false;
-
-  /* Get the type name if explicit. */
-  if (*cp == '<')
-    {
-      type_name = ++cp;
-      while (*cp != '>')
-	++cp;
-      *cp = '\0';
-      ++cp;
-    }
-
-  if (*cp == '$')
-    {
-      if (!type_name)
-	type_name = symbol_list_n_type_name_get (current_rule, loc, 0);
-      if (!type_name && typed)
-	complain_at (loc, _("$$ of `%s' has no declared type"),
-		     current_rule->sym->tag);
-      if (!type_name)
-	type_name = "";
-      obstack_fgrow1 (&obstack_for_string,
-		      "]b4_lhs_value([%s])[", type_name);
-      current_rule->used = true;
-    }
-  else
-    {
-      long int num = strtol (cp, NULL, 10);
-
-      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
-	{
-	  int n = num;
-	  if (max_left_semantic_context < 1 - n)
-	    max_left_semantic_context = 1 - n;
-	  if (!type_name && 0 < n)
-	    type_name = symbol_list_n_type_name_get (current_rule, loc, n);
-	  if (!type_name && typed)
-	    complain_at (loc, _("$%d of `%s' has no declared type"),
-			 n, current_rule->sym->tag);
-	  if (!type_name)
-	    type_name = "";
-	  obstack_fgrow3 (&obstack_for_string,
-			  "]b4_rhs_value(%d, %d, [%s])[",
-			  rule_length, n, type_name);
-	  symbol_list_n_used_set (current_rule, n, true);
-	}
-      else
-	complain_at (loc, _("integer out of range: %s"), quote (text));
-    }
-
-  return true;
-}
-
-
-/*----------------------------------------------------------------.
-| Map `$?' onto the proper M4 symbol, depending on its TOKEN_TYPE |
-| (are we in an action?).                                         |
-`----------------------------------------------------------------*/
-
-static void
-handle_dollar (int token_type, char *text, location loc)
-{
-  switch (token_type)
-    {
-    case BRACED_CODE:
-      if (handle_action_dollar (text, loc))
-	return;
-      break;
-
-    case PERCENT_DESTRUCTOR:
-    case PERCENT_INITIAL_ACTION:
-    case PERCENT_PRINTER:
-      if (text[1] == '$')
-	{
-	  obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
-	  return;
-	}
-      break;
-
-    default:
-      break;
-    }
-
-  complain_at (loc, _("invalid value: %s"), quote (text));
-}
-
-
-/*------------------------------------------------------.
-| TEXT is a location token (i.e., a `@...').  Output to |
-| OBSTACK_FOR_STRING a reference to this location.      |
-`------------------------------------------------------*/
-
-static inline bool
-handle_action_at (char *text, location loc)
-{
-  char *cp = text + 1;
-  locations_flag = true;
-
-  if (! current_rule)
-    return false;
-
-  if (*cp == '$')
-    obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
-  else
-    {
-      long int num = strtol (cp, NULL, 10);
-
-      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
-	{
-	  int n = num;
-	  obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
-			  rule_length, n);
-	}
-      else
-	complain_at (loc, _("integer out of range: %s"), quote (text));
-    }
-
-  return true;
-}
-
-
-/*----------------------------------------------------------------.
-| Map `@?' onto the proper M4 symbol, depending on its TOKEN_TYPE |
-| (are we in an action?).                                         |
-`----------------------------------------------------------------*/
-
-static void
-handle_at (int token_type, char *text, location loc)
-{
-  switch (token_type)
-    {
-    case BRACED_CODE:
-      handle_action_at (text, loc);
-      return;
-
-    case PERCENT_INITIAL_ACTION:
-    case PERCENT_DESTRUCTOR:
-    case PERCENT_PRINTER:
-      if (text[1] == '$')
-	{
-	  obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
-	  return;
-	}
-      break;
-
-    default:
-      break;
-    }
-
-  complain_at (loc, _("invalid value: %s"), quote (text));
-}
-
 
 /*------------------------------------------------------.
 | Scan NUMBER for a base-BASE integer at location LOC.  |
@@ -1071,36 +845,28 @@
 }
 
 
-/*----------------------------------------------------------------.
-| Handle `#line INT "FILE"'.  ARGS has already skipped `#line '.  |
-`----------------------------------------------------------------*/
+/*---------------------------------------------------------------------.
+| Handle '#line INT( "FILE")?\n'.  ARGS has already skipped '#line '.  |
+`---------------------------------------------------------------------*/
 
 static void
 handle_syncline (char *args, location loc)
 {
-  char *after_num;
-  unsigned long int lineno = strtoul (args, &after_num, 10);
-  char *file = strchr (after_num, '"') + 1;
-  *strchr (file, '"') = '\0';
+  char *file;
+  unsigned long int lineno = strtoul (args, &file, 10);
   if (INT_MAX <= lineno)
     {
       warn_at (loc, _("line number overflow"));
       lineno = INT_MAX;
     }
-  scanner_cursor.file = current_file = uniqstr_new (file);
-  scanner_cursor.line = lineno;
-  scanner_cursor.column = 1;
-}
 
-
-/*---------------------------------.
-| Report a rule that is too long.  |
-`---------------------------------*/
-
-static void
-rule_length_overflow (location loc)
-{
-  fatal_at (loc, _("rule is too long"));
+  file = mbschr (file, '"');
+  if (file)
+    {
+      *mbschr (file + 1, '"') = '\0';
+      current_file = uniqstr_new (file + 1);
+    }
+  boundary_set (&scanner_cursor, current_file, lineno, 1);
 }
 
 
@@ -1116,6 +882,10 @@
   location loc;
   loc.start = start;
   loc.end = scanner_cursor;
+  token_end = quote (token_end);
+  /* Instead of '\'', display "'".  */
+  if (!strcmp (token_end, "'\\''"))
+    token_end = "\"'\"";
   complain_at (loc, _(msgid), token_end);
 }
 
@@ -1128,7 +898,7 @@
 static void
 unexpected_eof (boundary start, char const *token_end)
 {
-  unexpected_end (start, N_("missing `%s' at end of file"), token_end);
+  unexpected_end (start, N_("missing %s at end of file"), token_end);
 }
 
 
@@ -1139,7 +909,7 @@
 static void
 unexpected_newline (boundary start, char const *token_end)
 {
-  unexpected_end (start, N_("missing `%s' at end of line"), token_end);
+  unexpected_end (start, N_("missing %s at end of line"), token_end);
 }
 
 
@@ -1148,7 +918,7 @@
 `-------------------------*/
 
 void
-scanner_initialize (void)
+gram_scanner_initialize (void)
 {
   obstack_init (&obstack_for_string);
 }
@@ -1159,9 +929,9 @@
 `-----------------------------------------------*/
 
 void
-scanner_free (void)
+gram_scanner_free (void)
 {
   obstack_free (&obstack_for_string, 0);
   /* Reclaim Flex's buffers.  */
-  yy_delete_buffer (YY_CURRENT_BUFFER);
+  yylex_destroy ();
 }
diff --git a/src/scan-skel-c.c b/src/scan-skel-c.c
index 1a047cf..fb1aea6 100644
--- a/src/scan-skel-c.c
+++ b/src/scan-skel-c.c
@@ -1,2 +1,3 @@
 #include <config.h>
+#include "system.h"
 #include "scan-skel.c"
diff --git a/src/scan-skel.c b/src/scan-skel.c
index f2dd18c..9841730 100644
--- a/src/scan-skel.c
+++ b/src/scan-skel.c
@@ -6,10 +6,37 @@
 
 /* A lexical scanner generated by flex */
 
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+#define yy_create_buffer skel__create_buffer
+#define yy_delete_buffer skel__delete_buffer
+#define yy_flex_debug skel__flex_debug
+#define yy_init_buffer skel__init_buffer
+#define yy_flush_buffer skel__flush_buffer
+#define yy_load_buffer_state skel__load_buffer_state
+#define yy_switch_to_buffer skel__switch_to_buffer
+#define yyin skel_in
+#define yyleng skel_leng
+#define yylex skel_lex
+#define yylineno skel_lineno
+#define yyout skel_out
+#define yyrestart skel_restart
+#define yytext skel_text
+#define yywrap skel_wrap
+#define yyalloc skel_alloc
+#define yyrealloc skel_realloc
+#define yyfree skel_free
+
+/* %endif */
+/* %endif */
+/* %ok-for-header */
+
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
+#define YY_FLEX_SUBMINOR_VERSION 37
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -47,7 +74,15 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
 #include <inttypes.h>
 typedef int8_t flex_int8_t;
 typedef uint8_t flex_uint8_t;
@@ -62,7 +97,6 @@
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -93,6 +127,8 @@
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#endif /* ! C99 */
+
 #endif /* ! FLEXINT_H */
 
 /* %endif */
@@ -107,11 +143,12 @@
 
 #else	/* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif	/* __STDC__ */
+#endif	/* defined (__STDC__) */
 #endif	/* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -169,13 +206,22 @@
 #define YY_BUF_SIZE 16384
 #endif
 
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
 #define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
 /* %if-not-reentrant */
-extern int skel_leng;
+extern yy_size_t skel_leng;
 /* %endif */
 
 /* %if-c-only */
@@ -206,16 +252,6 @@
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -238,7 +274,7 @@
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -322,12 +358,12 @@
 
 /* yy_hold_char holds the character lost when skel_text is formed. */
 static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int skel_leng;
+static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t skel_leng;
 
 /* Points to current character in buffer. */
 static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1;		/* whether we need to initialize */
+static int yy_init = 0;		/* whether we need to initialize */
 static int yy_start = 0;	/* start state number */
 
 /* Flag which is used to allow skel_wrap()'s to do buffer switches
@@ -354,7 +390,7 @@
 
 YY_BUFFER_STATE skel__scan_buffer (char *base,yy_size_t size  );
 YY_BUFFER_STATE skel__scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE skel__scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE skel__scan_bytes (yyconst char *bytes,yy_size_t len  );
 
 /* %endif */
 
@@ -389,7 +425,7 @@
 /* %% [1.0] skel_text/skel_in/skel_out/yy_state_type/skel_lineno etc. def's & init go here */
 /* Begin user sect3 */
 
-#define skel_wrap(n) 1
+#define skel_wrap() 1
 #define YY_SKIP_YYWRAP
 
 #define FLEX_DEBUG
@@ -429,8 +465,8 @@
 	(yy_c_buf_p) = yy_cp;
 
 /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 13
-#define YY_END_OF_BUFFER 14
+#define YY_NUM_RULES 22
+#define YY_END_OF_BUFFER 23
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -438,33 +474,31 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[69] =
+static yyconst flex_int16_t yy_accept[45] =
     {   0,
-        0,    0,   14,   12,   11,   10,   12,   10,    2,   10,
-       10,    3,    4,   10,   10,   10,   10,   10,   10,   10,
-       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
-        6,    5,   10,   10,   10,   10,   10,   10,    1,    0,
-       10,   10,   10,   10,   10,   10,   10,   10,    7,   10,
-       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
-       10,   10,   10,   10,   10,    9,    8,    0
+        0,    0,    0,    0,    0,    0,   23,   11,   10,    9,
+       12,   19,   21,   20,   20,   11,    9,    5,    1,    9,
+        4,    9,    2,    3,   12,   19,   17,   18,   13,   16,
+       14,   15,    8,    9,    9,    9,    9,    9,    9,    9,
+        9,    7,    6,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
     {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    2,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    1,    1,    1,    1,    1,    1,    4,
+        5,    1,    1,    5,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    6,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    3,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    4,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    5,    1,    6,    1,    1,    7,
+        1,    1,    1,    1,    7,    8,    7,    7,    7,    7,
 
-        8,    9,    1,   10,   11,    1,    1,   12,   13,   14,
-       15,   16,    1,   17,   18,   19,   20,    1,    1,   21,
-        1,    1,   22,    1,   23,    1,    1,    1,    1,    1,
+        9,   10,    7,    7,   11,    7,    7,   12,    7,   13,
+       14,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,   15,    1,   16,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -481,79 +515,66 @@
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[24] =
+static yyconst flex_int32_t yy_meta[17] =
     {   0,
-        1,    2,    1,    3,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1
+        1,    1,    2,    3,    1,    4,    1,    5,    1,    1,
+        1,    1,    1,    1,    5,    5
     } ;
 
-static yyconst flex_int16_t yy_base[74] =
+static yyconst flex_int16_t yy_base[53] =
     {   0,
-        0,    1,  107,    0,  138,    2,    0,    4,  138,   24,
-       39,  138,  138,    1,   63,   45,    0,    2,    3,    9,
-        5,   18,   22,   28,   11,   21,   33,   38,   34,   32,
-      138,  138,   49,   46,   59,   54,   30,   81,  138,    8,
-       58,   56,   47,   65,   61,   69,   68,   66,  138,   78,
-       79,   77,   80,   87,   88,   91,   95,   89,   90,   97,
-      100,  104,  106,  112,  114,  138,  138,  138,  125,    0,
-      128,  131,  134
+        0,    1,   60,   26,    6,    8,   29,    0,  105,   11,
+        0,   25,  105,  105,  105,    0,    0,  105,  105,   41,
+      105,   46,  105,  105,    0,  105,  105,  105,  105,  105,
+      105,  105,  105,   60,    4,   23,   25,   28,   43,   38,
+       57,  105,  105,  105,   71,   76,   81,   86,   91,   96,
+        0,  101
     } ;
 
-static yyconst flex_int16_t yy_def[74] =
+static yyconst flex_int16_t yy_def[53] =
     {   0,
-       69,   69,   68,   70,   68,   71,   70,   71,   68,   71,
-       10,   68,   68,   10,   10,   10,   10,   10,   10,   10,
-       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
-       68,   68,   10,   10,   72,   10,   10,   72,   68,   73,
-       10,   10,   10,   10,   10,   10,   10,   10,   68,   10,
-       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
-       10,   10,   10,   10,   10,   68,   68,    0,   68,   68,
-       68,   68,   68
+       45,   45,   46,   46,   47,   47,   44,   48,   44,   44,
+       49,   50,   44,   44,   44,   48,   51,   44,   44,   52,
+       44,   44,   44,   44,   49,   44,   44,   44,   44,   44,
+       44,   44,   44,   52,   34,   34,   34,   34,   34,   34,
+       34,   44,   44,    0,   44,   44,   44,   44,   44,   44,
+       44,   44
     } ;
 
-static yyconst flex_int16_t yy_nxt[162] =
+static yyconst flex_int16_t yy_nxt[122] =
     {   0,
-        7,    5,    5,    6,    6,    9,   22,   68,   10,   39,
-        8,    8,    8,    8,   23,    8,   11,   18,   21,    8,
-       25,    8,   24,   12,   13,   68,   68,   68,    8,   27,
-       29,    8,    8,   26,   14,   28,   31,   30,    8,   34,
-       43,   32,    8,    8,    8,   68,   68,   15,    8,    8,
-       16,   35,   33,   36,   37,   20,    8,    8,   17,    8,
-       39,   45,   40,   41,    8,   44,    8,   46,    8,   42,
-       47,    8,   49,   19,   50,    8,    8,   48,    8,    8,
-       40,   40,   39,   51,   40,   52,   53,    8,    8,    8,
-        8,   56,   57,   54,   60,   61,   55,    8,    8,    8,
+       17,   44,    9,    9,   44,   10,   10,   14,   15,   14,
+       15,   17,   17,   18,   37,   17,   19,   20,   21,   20,
+       20,   20,   20,   20,   22,   23,   24,   27,   44,   28,
+       29,   12,   30,   20,   38,   20,   40,   39,   20,   31,
+       32,   17,   17,   42,   33,   17,   17,   17,   20,   33,
+       17,   41,   20,   20,   20,   34,   20,   35,   20,   20,
+       17,   17,   43,   33,   17,   12,   44,   20,   44,   44,
+       36,    8,    8,    8,    8,    8,   11,   11,   11,   11,
+       11,   13,   13,   13,   13,   13,   16,   44,   16,   44,
+       16,   25,   25,   25,   44,   25,   26,   26,   26,   26,
 
-        8,    8,   40,   40,   58,    8,   68,    8,   59,   62,
-        8,   64,   63,   65,    8,   66,    8,   67,   68,   68,
-       68,   68,    8,   68,    8,    4,    4,    4,    8,   68,
-        8,   38,   38,   38,   40,   40,   40,    3,   68,   68,
-       68,   68,   68,   68,   68,   68,   68,   68,   68,   68,
-       68,   68,   68,   68,   68,   68,   68,   68,   68,   68,
-       68
+       26,   20,   44,   20,    7,   44,   44,   44,   44,   44,
+       44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
+       44
     } ;
 
-static yyconst flex_int16_t yy_chk[162] =
+static yyconst flex_int16_t yy_chk[122] =
     {   0,
-       70,    1,    2,    1,    2,    6,   18,    8,    6,   40,
-       17,   14,   18,   19,   19,   21,    6,   14,   17,   20,
-       21,   25,   20,    6,    6,    8,    8,   10,   22,   23,
-       25,   26,   23,   22,   10,   24,   27,   26,   24,   30,
-       37,   28,   30,   27,   29,   10,   10,   11,   28,   11,
-       11,   33,   29,   33,   34,   16,   34,   43,   11,   33,
-       35,   42,   35,   36,   36,   41,   42,   43,   41,   36,
-       44,   45,   46,   15,   47,   44,   48,   45,   47,   46,
-       35,   35,   38,   48,   38,   50,   51,   52,   50,   51,
-       53,   54,   55,   52,   58,   59,   53,   54,   55,   58,
+       51,    0,    1,    2,    0,    1,    2,    5,    5,    6,
+        6,   10,   10,   10,   35,   10,   10,   10,   10,   10,
+       10,   10,   10,   10,   10,   10,   10,   12,    7,   12,
+       12,    4,   12,   36,   36,   37,   38,   37,   38,   12,
+       12,   20,   20,   40,   20,   20,   22,   22,   40,   22,
+       22,   39,   22,   39,   22,   22,   22,   22,   22,   22,
+       34,   34,   41,   34,   34,    3,    0,   41,    0,    0,
+       34,   45,   45,   45,   45,   45,   46,   46,   46,   46,
+       46,   47,   47,   47,   47,   47,   48,    0,   48,    0,
+       48,   49,   49,   49,    0,   49,   50,   50,   50,   50,
 
-       59,   56,   38,   38,   56,   57,    3,   60,   57,   60,
-       61,   62,   61,   63,   62,   64,   63,   65,    0,    0,
-        0,    0,   64,    0,   65,   69,   69,   69,   71,    0,
-       71,   72,   72,   72,   73,   73,   73,   68,   68,   68,
-       68,   68,   68,   68,   68,   68,   68,   68,   68,   68,
-       68,   68,   68,   68,   68,   68,   68,   68,   68,   68,
-       68
+       50,   52,    0,   52,   44,   44,   44,   44,   44,   44,
+       44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
+       44
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -562,10 +583,11 @@
 extern int skel__flex_debug;
 int skel__flex_debug = 1;
 
-static yyconst flex_int16_t yy_rule_linenum[13] =
+static yyconst flex_int16_t yy_rule_linenum[22] =
     {   0,
-       70,   97,   98,   99,  101,  102,  103,  104,  105,  108,
-      109,  110
+       72,   73,   74,   75,   76,   78,   79,   81,   90,   91,
+       92,  105,  107,  108,  109,  110,  111,  113,  134,  139,
+      140
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -579,33 +601,33 @@
 #line 1 "scan-skel.l"
 /* Scan Bison Skeletons.                                       -*- C -*-
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
-   Foundation, Inc.
+   Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
-#line 27 "scan-skel.l"
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+#define YY_NO_INPUT 1
+#line 24 "scan-skel.l"
 /* Work around a bug in flex 2.5.31.  See Debian bug 333231
    <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
 #undef skel_wrap
 #define skel_wrap() 1
 
-#include "system.h"
+#define FLEX_PREFIX(Id) skel_ ## Id
+#include "flex-scanner.h"
 
+#include <dirname.h>
 #include <error.h>
 #include <quotearg.h>
 
@@ -614,29 +636,25 @@
 #include "files.h"
 #include "scan-skel.h"
 
-/* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
-int skel_lex (void);
-int skel_get_lineno (void);
-FILE *skel_get_in (void);
-FILE *skel_get_out (void);
-int skel_get_leng (void);
-char *skel_get_text (void);
-void skel_set_lineno (int);
-void skel_set_in (FILE *);
-void skel_set_out (FILE *);
-int skel_get_debug (void);
-void skel_set_debug (int);
-int skel_lex_destroy (void);
+#define YY_DECL static int skel_lex (void)
+YY_DECL;
 
 #define QPUTS(String) \
    fputs (quotearg_style (c_quoting_style, String), skel_out)
 
-#define BASE_QPUTS(File) \
-   QPUTS (base_name (File))
+static void at_directive_perform (int at_directive_argc,
+                                  char *at_directive_argv[],
+                                  char **outnamep, int *out_linenop);
+static void fail_for_at_directive_too_many_args (char const *at_directive_name);
+static void fail_for_at_directive_too_few_args (char const *at_directive_name);
+static void fail_for_invalid_at (char const *at);
 
-#line 638 "scan-skel.c"
+
+#line 654 "scan-skel.c"
 
 #define INITIAL 0
+#define SC_AT_DIRECTIVE_ARGS 1
+#define SC_AT_DIRECTIVE_SKIP_WS 2
 
 #ifndef YY_NO_UNISTD_H
 /* Special case for "unistd.h", since it is non-ANSI. We include it way
@@ -656,11 +674,46 @@
 
 /* %if-c-only Reentrant structure and macros (non-C++). */
 /* %if-reentrant */
+/* %if-c-only */
+
+static int yy_init_globals (void );
+
+/* %endif */
 /* %if-reentrant */
 /* %endif */
+/* %endif End reentrant structures and macros. */
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int skel_lex_destroy (void );
+
+int skel_get_debug (void );
+
+void skel_set_debug (int debug_flag  );
+
+YY_EXTRA_TYPE skel_get_extra (void );
+
+void skel_set_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *skel_get_in (void );
+
+void skel_set_in  (FILE * in_str  );
+
+FILE *skel_get_out (void );
+
+void skel_set_out  (FILE * out_str  );
+
+yy_size_t skel_get_leng (void );
+
+char *skel_get_text (void );
+
+int skel_get_lineno (void );
+
+void skel_set_lineno (int line_number  );
+
 /* %if-bison-bridge */
 /* %endif */
-/* %endif End reentrant structures and macros. */
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -717,7 +770,7 @@
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( skel_text, skel_leng, 1, skel_out )
+#define ECHO do { if (fwrite( skel_text, skel_leng, 1, skel_out )) {} } while (0)
 /* %endif */
 /* %if-c++-only C++ definition */
 /* %endif */
@@ -839,19 +892,26 @@
 	register int yy_act;
     
 /* %% [7.0] user's declarations go here */
-#line 63 "scan-skel.l"
+#line 58 "scan-skel.l"
 
 
 
-  int lineno IF_LINT (= 0);
+  int out_lineno PACIFY_CC (= 0);
   char *outname = NULL;
 
+  /* Currently, only the @warn, @complain, @fatal, @warn_at, @complain_at, and
+     @fatal_at directives take multiple arguments, and the last three already
+     can't take more than 7.  at_directive_argv[0] is the directive name.  */
+  #define AT_DIRECTIVE_ARGC_MAX 8
+  int at_directive_argc = 0;
+  char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX];
 
-#line 851 "scan-skel.c"
 
-	if ( (yy_init) )
+#line 911 "scan-skel.c"
+
+	if ( !(yy_init) )
 		{
-		(yy_init) = 0;
+		(yy_init) = 1;
 
 #ifdef YY_USER_INIT
 		YY_USER_INIT;
@@ -910,13 +970,13 @@
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 69 )
+				if ( yy_current_state >= 45 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 68 );
+		while ( yy_current_state != 44 );
 		yy_cp = (yy_last_accepting_cpos);
 		yy_current_state = (yy_last_accepting_state);
 
@@ -935,13 +995,13 @@
 			{
 			if ( yy_act == 0 )
 				fprintf( stderr, "--scanner backing up\n" );
-			else if ( yy_act < 13 )
+			else if ( yy_act < 22 )
 				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
 				         (long)yy_rule_linenum[yy_act], skel_text );
-			else if ( yy_act == 13 )
+			else if ( yy_act == 22 )
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				         skel_text );
-			else if ( yy_act == 14 )
+			else if ( yy_act == 23 )
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 			else
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -958,95 +1018,71 @@
 			goto yy_find_action;
 
 case 1:
-/* rule 1 can match eol */
 YY_RULE_SETUP
-#line 70 "scan-skel.l"
-{
-  char const *file_name = skel_text + sizeof "@output " - 1;
-  skel_text[skel_leng - 1] = '\0';
-
-  /* Decode special file names.  They include the directory part,
-     contrary to their "free" occurrences, used for issuing #includes,
-     which must not include the directory part.  */
-
-  if (*file_name == '@')
-    {
-      if (strcmp (file_name, "@output_header_name@") == 0)
-	file_name = spec_defines_file;
-      else if (strcmp (file_name, "@output_parser_name@") == 0)
-	file_name = parser_file_name;
-      else
-	fatal ("invalid token in skeleton: %s", skel_text);
-    }
-  if (outname)
-    {
-      free (outname);
-      xfclose (skel_out);
-    }
-  outname = xstrdup (file_name);
-  skel_out = xfopen (outname, "w");
-  lineno = 1;
-}
+#line 72 "scan-skel.l"
+fputc ('@', skel_out);
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 97 "scan-skel.l"
-fputc ('@', skel_out);
+#line 73 "scan-skel.l"
+fputc ('[', skel_out);
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 98 "scan-skel.l"
-fputc ('[', skel_out);
+#line 74 "scan-skel.l"
+fputc (']', skel_out);
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 99 "scan-skel.l"
-fputc (']', skel_out);
+#line 75 "scan-skel.l"
+continue;  /* Used by b4_cat in ../data/bison.m4.  */
 	YY_BREAK
 case 5:
+/* rule 5 can match eol */
 YY_RULE_SETUP
-#line 101 "scan-skel.l"
-fprintf (skel_out, "%d", lineno + 1);
+#line 76 "scan-skel.l"
+continue;
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 102 "scan-skel.l"
-QPUTS (outname);
+#line 78 "scan-skel.l"
+fprintf (skel_out, "%d", out_lineno + 1);
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 103 "scan-skel.l"
-QPUTS (dir_prefix);
+#line 79 "scan-skel.l"
+QPUTS (outname);
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 104 "scan-skel.l"
-BASE_QPUTS (parser_file_name);
-	YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 105 "scan-skel.l"
-BASE_QPUTS (spec_defines_file);
+#line 81 "scan-skel.l"
+{
+  skel_text[skel_leng-1] = '\0';
+  obstack_grow (&obstack_for_string, skel_text, skel_leng);
+  at_directive_argv[at_directive_argc++] =
+    obstack_finish (&obstack_for_string);
+  BEGIN SC_AT_DIRECTIVE_ARGS;
+}
 	YY_BREAK
 /* This pattern must not match more than the previous @ patterns. */
-case 10:
+case 9:
 YY_RULE_SETUP
-#line 108 "scan-skel.l"
-fatal ("invalid @ in skeleton: %s", skel_text);
+#line 90 "scan-skel.l"
+fail_for_invalid_at (skel_text);
+	YY_BREAK
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 91 "scan-skel.l"
+out_lineno++; ECHO;
 	YY_BREAK
 case 11:
-/* rule 11 can match eol */
 YY_RULE_SETUP
-#line 109 "scan-skel.l"
-lineno++; ECHO;
-	YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 110 "scan-skel.l"
+#line 92 "scan-skel.l"
 ECHO;
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 112 "scan-skel.l"
+#line 94 "scan-skel.l"
 {
   if (outname)
     {
@@ -1056,12 +1092,100 @@
   return EOF;
 }
 	YY_BREAK
+
+
+case 12:
+/* rule 12 can match eol */
+YY_RULE_SETUP
+#line 105 "scan-skel.l"
+STRING_GROW;
+	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 120 "scan-skel.l"
+#line 107 "scan-skel.l"
+obstack_1grow (&obstack_for_string, '@');
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 108 "scan-skel.l"
+obstack_1grow (&obstack_for_string, '[');
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 109 "scan-skel.l"
+obstack_1grow (&obstack_for_string, ']');
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 110 "scan-skel.l"
+continue; /* For starting an argument that begins with whitespace. */
+	YY_BREAK
+case 17:
+/* rule 17 can match eol */
+YY_RULE_SETUP
+#line 111 "scan-skel.l"
+continue;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 113 "scan-skel.l"
+{
+    if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
+      fail_for_at_directive_too_many_args (at_directive_argv[0]);
+
+    obstack_1grow (&obstack_for_string, '\0');
+    at_directive_argv[at_directive_argc++] =
+      obstack_finish (&obstack_for_string);
+
+    /* Like M4, skip whitespace after a comma.  */
+    if (skel_text[1] == ',')
+      BEGIN SC_AT_DIRECTIVE_SKIP_WS;
+    else
+      {
+        at_directive_perform (at_directive_argc, at_directive_argv,
+                              &outname, &out_lineno);
+        obstack_free (&obstack_for_string, at_directive_argv[0]);
+        at_directive_argc = 0;
+        BEGIN INITIAL;
+      }
+  }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 134 "scan-skel.l"
+fail_for_invalid_at (skel_text);
+	YY_BREAK
+
+
+
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 139 "scan-skel.l"
+continue;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 140 "scan-skel.l"
+{ yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
+	YY_BREAK
+
+
+
+case YY_STATE_EOF(SC_AT_DIRECTIVE_ARGS):
+case YY_STATE_EOF(SC_AT_DIRECTIVE_SKIP_WS):
+#line 145 "scan-skel.l"
+{
+    fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
+  }
+	YY_BREAK
+
+case 22:
+YY_RULE_SETUP
+#line 150 "scan-skel.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1065 "scan-skel.c"
+#line 1189 "scan-skel.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1259,21 +1383,21 @@
 
 	else
 		{
-			size_t num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
 			{ /* Not enough room in the buffer - grow it. */
 
 			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
 
 			int yy_c_buf_p_offset =
 				(int) ((yy_c_buf_p) - b->yy_ch_buf);
 
 			if ( b->yy_is_our_buffer )
 				{
-				int new_size = b->yy_buf_size * 2;
+				yy_size_t new_size = b->yy_buf_size * 2;
 
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1328,6 +1452,14 @@
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
+	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) skel_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
 	(yy_n_chars) += number_to_move;
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -1365,7 +1497,7 @@
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 69 )
+			if ( yy_current_state >= 45 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1398,13 +1530,13 @@
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 69 )
+		if ( yy_current_state >= 45 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 68);
+	yy_is_jam = (yy_current_state == 44);
 
-	return yy_is_jam ? 0 : yy_current_state;
+		return yy_is_jam ? 0 : yy_current_state;
 }
 
 /* %if-c-only */
@@ -1439,7 +1571,7 @@
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -1623,13 +1755,6 @@
 	skel_free((void *) b  );
 }
 
-/* %if-c-only */
-
-/* %endif */
-
-/* %if-c++-only */
-/* %endif */
-
 /* Initializes or reinitializes a buffer.
  * This function is sometimes called more than once on the same buffer,
  * such as during a skel_restart() or at EOF.
@@ -1772,7 +1897,7 @@
 /* %if-c++-only */
 /* %endif */
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -1784,7 +1909,9 @@
 		(yy_buffer_stack) = (struct yy_buffer_state**)skel_alloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
-		
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in skel_ensure_buffer_stack()" );
+								  
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
 		(yy_buffer_stack_max) = num_to_alloc;
@@ -1802,6 +1929,8 @@
 								((yy_buffer_stack),
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in skel_ensure_buffer_stack()" );
 
 		/* zero only the new slots.*/
 		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1850,28 +1979,28 @@
 /* %if-c-only */
 /** Setup the input buffer state to scan a string. The next call to skel_lex() will
  * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
  *       skel__scan_bytes() instead.
  */
-YY_BUFFER_STATE skel__scan_string (yyconst char * yy_str )
+YY_BUFFER_STATE skel__scan_string (yyconst char * yystr )
 {
     
-	return skel__scan_bytes(yy_str,strlen(yy_str) );
+	return skel__scan_bytes(yystr,strlen(yystr) );
 }
 /* %endif */
 
 /* %if-c-only */
 /** Setup the input buffer state to scan the given bytes. The next call to skel_lex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE skel__scan_bytes  (yyconst char * bytes, int  len )
+YY_BUFFER_STATE skel__scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
@@ -1879,15 +2008,15 @@
 	int i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = len + 2;
+	n = _yybytes_len + 2;
 	buf = (char *) skel_alloc(n  );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in skel__scan_bytes()" );
 
-	for ( i = 0; i < len; ++i )
-		buf[i] = bytes[i];
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
 
-	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
 	b = skel__scan_buffer(buf,n );
 	if ( ! b )
@@ -1967,7 +2096,7 @@
 /** Get the length of the current token.
  * 
  */
-int skel_get_leng  (void)
+yy_size_t skel_get_leng  (void)
 {
         return skel_leng;
 }
@@ -2025,6 +2154,36 @@
 /* %if-reentrant */
 /* %if-bison-bridge */
 /* %endif */
+/* %endif if-c-only */
+
+/* %if-c-only */
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from skel_lex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    skel_in = stdin;
+    skel_out = stdout;
+#else
+    skel_in = (FILE *) 0;
+    skel_out = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * skel_lex_init()
+     */
+    return 0;
+}
 /* %endif */
 
 /* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
@@ -2043,6 +2202,10 @@
 	skel_free((yy_buffer_stack) );
 	(yy_buffer_stack) = NULL;
 
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * skel_lex() is called, initialization will occur. */
+    yy_init_globals( );
+
 /* %if-reentrant */
 /* %endif */
     return 0;
@@ -2057,7 +2220,7 @@
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 {
 	register int i;
-    	for ( i = 0; i < n; ++i )
+	for ( i = 0; i < n; ++i )
 		s1[i] = s2[i];
 }
 #endif
@@ -2066,7 +2229,7 @@
 static int yy_flex_strlen (yyconst char * s )
 {
 	register int n;
-    	for ( n = 0; s[n]; ++n )
+	for ( n = 0; s[n]; ++n )
 		;
 
 	return n;
@@ -2102,19 +2265,7 @@
 
 /* %ok-for-header */
 
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-#line 120 "scan-skel.l"
+#line 150 "scan-skel.l"
 
 
 
@@ -2125,10 +2276,152 @@
 void
 scan_skel (FILE *in)
 {
+  static bool initialized = false;
+  if (!initialized)
+    {
+      initialized = true;
+      obstack_init (&obstack_for_string);
+    }
   skel_in = in;
   skel__flex_debug = trace_flag & trace_skeleton;
   skel_lex ();
+}
+
+void
+skel_scanner_free (void)
+{
+  obstack_free (&obstack_for_string, 0);
   /* Reclaim Flex's buffers.  */
-  skel__delete_buffer (YY_CURRENT_BUFFER);
+  skel_lex_destroy ();
+}
+
+static void
+at_directive_perform (int at_directive_argc,
+                      char *at_directive_argv[],
+                      char **outnamep, int *out_linenop)
+{
+  if (0 == strcmp (at_directive_argv[0], "@basename"))
+    {
+      if (at_directive_argc > 2)
+        fail_for_at_directive_too_many_args (at_directive_argv[0]);
+      fputs (last_component (at_directive_argv[1]), skel_out);
+    }
+  else if (0 == strcmp (at_directive_argv[0], "@warn")
+           || 0 == strcmp (at_directive_argv[0], "@complain")
+           || 0 == strcmp (at_directive_argv[0], "@fatal"))
+    {
+      void (*func)(char const *, ...);
+      switch (at_directive_argv[0][1])
+        {
+          case 'w': func = warn; break;
+          case 'c': func = complain; break;
+          case 'f': func = fatal; break;
+          default: aver (false); break;
+        }
+      switch (at_directive_argc)
+        {
+          case 2:
+            func (_(at_directive_argv[1]));
+            break;
+          case 3:
+            func (_(at_directive_argv[1]), at_directive_argv[2]);
+            break;
+          case 4:
+            func (_(at_directive_argv[1]), at_directive_argv[2],
+                  at_directive_argv[3]);
+            break;
+          case 5:
+            func (_(at_directive_argv[1]), at_directive_argv[2],
+                  at_directive_argv[3], at_directive_argv[4]);
+            break;
+          case 6:
+            func (_(at_directive_argv[1]), at_directive_argv[2],
+                  at_directive_argv[3], at_directive_argv[4],
+                  at_directive_argv[5]);
+            break;
+          default:
+            fail_for_at_directive_too_many_args (at_directive_argv[0]);
+            break;
+        }
+    }
+  else if (0 == strcmp (at_directive_argv[0], "@warn_at")
+           || 0 == strcmp (at_directive_argv[0], "@complain_at")
+           || 0 == strcmp (at_directive_argv[0], "@fatal_at"))
+    {
+      void (*func)(location, char const *, ...);
+      location loc;
+      if (at_directive_argc < 4)
+        fail_for_at_directive_too_few_args (at_directive_argv[0]);
+      switch (at_directive_argv[0][1])
+        {
+          case 'w': func = warn_at; break;
+          case 'c': func = complain_at; break;
+          case 'f': func = fatal_at; break;
+          default: aver (false); break;
+        }
+      boundary_set_from_string (&loc.start, at_directive_argv[1]);
+      boundary_set_from_string (&loc.end, at_directive_argv[2]);
+      switch (at_directive_argc)
+        {
+          case 4:
+            func (loc, _(at_directive_argv[3]));
+            break;
+          case 5:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4]);
+            break;
+          case 6:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4],
+                  at_directive_argv[5]);
+            break;
+          case 7:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4],
+                  at_directive_argv[5], at_directive_argv[6]);
+            break;
+          case 8:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4],
+                  at_directive_argv[5], at_directive_argv[6],
+                  at_directive_argv[7]);
+            break;
+          default:
+            fail_for_at_directive_too_many_args (at_directive_argv[0]);
+            break;
+        }
+    }
+  else if (0 == strcmp (at_directive_argv[0], "@output"))
+    {
+      if (at_directive_argc > 2)
+        fail_for_at_directive_too_many_args (at_directive_argv[0]);
+      if (*outnamep)
+        {
+          free (*outnamep);
+          xfclose (skel_out);
+        }
+      *outnamep = xstrdup (at_directive_argv[1]);
+      output_file_name_check (outnamep);
+      skel_out = xfopen (*outnamep, "w");
+      *out_linenop = 1;
+    }
+  else
+    fail_for_invalid_at (at_directive_argv[0]);
+}
+
+static void
+fail_for_at_directive_too_few_args (char const *at_directive_name)
+{
+  fatal (_("too few arguments for %s directive in skeleton"),
+         at_directive_name);
+}
+
+static void
+fail_for_at_directive_too_many_args (char const *at_directive_name)
+{
+  fatal (_("too many arguments for %s directive in skeleton"),
+         at_directive_name);
+}
+
+static void
+fail_for_invalid_at (char const *at)
+{
+  fatal ("invalid @ in skeleton: %s", at);
 }
 
diff --git a/src/scan-skel.h b/src/scan-skel.h
index a7e14c3..2c6930b 100644
--- a/src/scan-skel.h
+++ b/src/scan-skel.h
@@ -1,23 +1,21 @@
 /* Scan Bison Skeletons.
 
-   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2005-2007, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 void scan_skel (FILE *);
 
@@ -26,3 +24,4 @@
 extern FILE *skel_out;
 extern int skel__flex_debug;
 extern int skel_lineno;
+void skel_scanner_free (void);
diff --git a/src/scan-skel.l b/src/scan-skel.l
index c84eea1..ed61b5c 100644
--- a/src/scan-skel.l
+++ b/src/scan-skel.l
@@ -1,26 +1,23 @@
 /* Scan Bison Skeletons.                                       -*- C -*-
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
-   Foundation, Inc.
+   Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-%option nodefault noyywrap nounput never-interactive debug
+%option nodefault noyywrap noinput nounput never-interactive debug
 %option prefix="skel_" outfile="lex.yy.c"
 
 %{
@@ -29,8 +26,10 @@
 #undef skel_wrap
 #define skel_wrap() 1
 
-#include "system.h"
+#define FLEX_PREFIX(Id) skel_ ## Id
+#include "flex-scanner.h"
 
+#include <dirname.h>
 #include <error.h>
 #include <quotearg.h>
 
@@ -39,77 +38,60 @@
 #include "files.h"
 #include "scan-skel.h"
 
-/* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
-int skel_lex (void);
-int skel_get_lineno (void);
-FILE *skel_get_in (void);
-FILE *skel_get_out (void);
-int skel_get_leng (void);
-char *skel_get_text (void);
-void skel_set_lineno (int);
-void skel_set_in (FILE *);
-void skel_set_out (FILE *);
-int skel_get_debug (void);
-void skel_set_debug (int);
-int skel_lex_destroy (void);
+#define YY_DECL static int skel_lex (void)
+YY_DECL;
 
 #define QPUTS(String) \
    fputs (quotearg_style (c_quoting_style, String), yyout)
 
-#define BASE_QPUTS(File) \
-   QPUTS (base_name (File))
-
+static void at_directive_perform (int at_directive_argc,
+                                  char *at_directive_argv[],
+                                  char **outnamep, int *out_linenop);
+static void fail_for_at_directive_too_many_args (char const *at_directive_name);
+static void fail_for_at_directive_too_few_args (char const *at_directive_name);
+static void fail_for_invalid_at (char const *at);
 %}
+
+%x SC_AT_DIRECTIVE_ARGS
+%x SC_AT_DIRECTIVE_SKIP_WS
+
 %%
 
 %{
-  int lineno IF_LINT (= 0);
+  int out_lineno PACIFY_CC (= 0);
   char *outname = NULL;
+
+  /* Currently, only the @warn, @complain, @fatal, @warn_at, @complain_at, and
+     @fatal_at directives take multiple arguments, and the last three already
+     can't take more than 7.  at_directive_argv[0] is the directive name.  */
+  #define AT_DIRECTIVE_ARGC_MAX 8
+  int at_directive_argc = 0;
+  char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX];
 %}
 
-"@output ".*\n {
-  char const *file_name = yytext + sizeof "@output " - 1;
-  yytext[yyleng - 1] = '\0';
+"@@" fputc ('@', yyout);
+"@{" fputc ('[', yyout);
+"@}" fputc (']', yyout);
+"@`" continue;  /* Used by b4_cat in ../data/bison.m4.  */
+@\n  continue;
 
-  /* Decode special file names.  They include the directory part,
-     contrary to their "free" occurrences, used for issuing #includes,
-     which must not include the directory part.  */
+"@oline@"  fprintf (yyout, "%d", out_lineno + 1);
+"@ofile@"  QPUTS (outname);
 
-  if (*file_name == '@')
-    {
-      if (strcmp (file_name, "@output_header_name@") == 0)
-	file_name = spec_defines_file;
-      else if (strcmp (file_name, "@output_parser_name@") == 0)
-	file_name = parser_file_name;
-      else
-	fatal ("invalid token in skeleton: %s", yytext);
-    }
-  if (outname)
-    {
-      free (outname);
-      xfclose (yyout);
-    }
-  outname = xstrdup (file_name);
-  yyout = xfopen (outname, "w");
-  lineno = 1;
+@[a-z_]+"(" {
+  yytext[yyleng-1] = '\0';
+  obstack_grow (&obstack_for_string, yytext, yyleng);
+  at_directive_argv[at_directive_argc++] =
+    obstack_finish (&obstack_for_string);
+  BEGIN SC_AT_DIRECTIVE_ARGS;
 }
 
-"@@"	   fputc ('@', yyout);
-"@{"	   fputc ('[', yyout);
-"@}"	   fputc (']', yyout);
-
-"@oline@"  fprintf (yyout, "%d", lineno + 1);
-"@ofile@"  QPUTS (outname);
-"@dir_prefix@" QPUTS (dir_prefix);
-"@output_parser_name@"	BASE_QPUTS (parser_file_name);
-"@output_header_name@"	BASE_QPUTS (spec_defines_file);
-
   /* This pattern must not match more than the previous @ patterns. */
-@[^{}@\n]* fatal ("invalid @ in skeleton: %s", yytext);
-\n	   lineno++; ECHO;
-[^@\n]+	   ECHO;
+@[^@{}`(\n]*  fail_for_invalid_at (yytext);
+\n            out_lineno++; ECHO;
+[^@\n]+       ECHO;
 
-<<EOF>> {
+<INITIAL><<EOF>> {
   if (outname)
     {
       free (outname);
@@ -117,6 +99,54 @@
     }
   return EOF;
 }
+
+<SC_AT_DIRECTIVE_ARGS>
+{
+  [^@]+  STRING_GROW;
+
+  "@@"   obstack_1grow (&obstack_for_string, '@');
+  "@{"   obstack_1grow (&obstack_for_string, '[');
+  "@}"   obstack_1grow (&obstack_for_string, ']');
+  "@`"   continue; /* For starting an argument that begins with whitespace. */
+  @\n    continue;
+
+  @[,)] {
+    if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
+      fail_for_at_directive_too_many_args (at_directive_argv[0]);
+
+    obstack_1grow (&obstack_for_string, '\0');
+    at_directive_argv[at_directive_argc++] =
+      obstack_finish (&obstack_for_string);
+
+    /* Like M4, skip whitespace after a comma.  */
+    if (yytext[1] == ',')
+      BEGIN SC_AT_DIRECTIVE_SKIP_WS;
+    else
+      {
+        at_directive_perform (at_directive_argc, at_directive_argv,
+                              &outname, &out_lineno);
+        obstack_free (&obstack_for_string, at_directive_argv[0]);
+        at_directive_argc = 0;
+        BEGIN INITIAL;
+      }
+  }
+
+  @.?  fail_for_invalid_at (yytext);
+}
+
+<SC_AT_DIRECTIVE_SKIP_WS>
+{
+  [ \t\r\n]    continue;
+  .            { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
+}
+
+<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>
+{
+  <<EOF>> {
+    fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
+  }
+}
+
 %%
 
 /*------------------------.
@@ -126,9 +156,151 @@
 void
 scan_skel (FILE *in)
 {
+  static bool initialized = false;
+  if (!initialized)
+    {
+      initialized = true;
+      obstack_init (&obstack_for_string);
+    }
   skel_in = in;
   skel__flex_debug = trace_flag & trace_skeleton;
   skel_lex ();
+}
+
+void
+skel_scanner_free (void)
+{
+  obstack_free (&obstack_for_string, 0);
   /* Reclaim Flex's buffers.  */
-  yy_delete_buffer (YY_CURRENT_BUFFER);
+  yylex_destroy ();
+}
+
+static void
+at_directive_perform (int at_directive_argc,
+                      char *at_directive_argv[],
+                      char **outnamep, int *out_linenop)
+{
+  if (0 == strcmp (at_directive_argv[0], "@basename"))
+    {
+      if (at_directive_argc > 2)
+        fail_for_at_directive_too_many_args (at_directive_argv[0]);
+      fputs (last_component (at_directive_argv[1]), yyout);
+    }
+  else if (0 == strcmp (at_directive_argv[0], "@warn")
+           || 0 == strcmp (at_directive_argv[0], "@complain")
+           || 0 == strcmp (at_directive_argv[0], "@fatal"))
+    {
+      void (*func)(char const *, ...);
+      switch (at_directive_argv[0][1])
+        {
+          case 'w': func = warn; break;
+          case 'c': func = complain; break;
+          case 'f': func = fatal; break;
+          default: aver (false); break;
+        }
+      switch (at_directive_argc)
+        {
+          case 2:
+            func (_(at_directive_argv[1]));
+            break;
+          case 3:
+            func (_(at_directive_argv[1]), at_directive_argv[2]);
+            break;
+          case 4:
+            func (_(at_directive_argv[1]), at_directive_argv[2],
+                  at_directive_argv[3]);
+            break;
+          case 5:
+            func (_(at_directive_argv[1]), at_directive_argv[2],
+                  at_directive_argv[3], at_directive_argv[4]);
+            break;
+          case 6:
+            func (_(at_directive_argv[1]), at_directive_argv[2],
+                  at_directive_argv[3], at_directive_argv[4],
+                  at_directive_argv[5]);
+            break;
+          default:
+            fail_for_at_directive_too_many_args (at_directive_argv[0]);
+            break;
+        }
+    }
+  else if (0 == strcmp (at_directive_argv[0], "@warn_at")
+           || 0 == strcmp (at_directive_argv[0], "@complain_at")
+           || 0 == strcmp (at_directive_argv[0], "@fatal_at"))
+    {
+      void (*func)(location, char const *, ...);
+      location loc;
+      if (at_directive_argc < 4)
+        fail_for_at_directive_too_few_args (at_directive_argv[0]);
+      switch (at_directive_argv[0][1])
+        {
+          case 'w': func = warn_at; break;
+          case 'c': func = complain_at; break;
+          case 'f': func = fatal_at; break;
+          default: aver (false); break;
+        }
+      boundary_set_from_string (&loc.start, at_directive_argv[1]);
+      boundary_set_from_string (&loc.end, at_directive_argv[2]);
+      switch (at_directive_argc)
+        {
+          case 4:
+            func (loc, _(at_directive_argv[3]));
+            break;
+          case 5:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4]);
+            break;
+          case 6:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4],
+                  at_directive_argv[5]);
+            break;
+          case 7:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4],
+                  at_directive_argv[5], at_directive_argv[6]);
+            break;
+          case 8:
+            func (loc, _(at_directive_argv[3]), at_directive_argv[4],
+                  at_directive_argv[5], at_directive_argv[6],
+                  at_directive_argv[7]);
+            break;
+          default:
+            fail_for_at_directive_too_many_args (at_directive_argv[0]);
+            break;
+        }
+    }
+  else if (0 == strcmp (at_directive_argv[0], "@output"))
+    {
+      if (at_directive_argc > 2)
+        fail_for_at_directive_too_many_args (at_directive_argv[0]);
+      if (*outnamep)
+        {
+          free (*outnamep);
+          xfclose (yyout);
+        }
+      *outnamep = xstrdup (at_directive_argv[1]);
+      output_file_name_check (outnamep);
+      yyout = xfopen (*outnamep, "w");
+      *out_linenop = 1;
+    }
+  else
+    fail_for_invalid_at (at_directive_argv[0]);
+}
+
+static void
+fail_for_at_directive_too_few_args (char const *at_directive_name)
+{
+  fatal (_("too few arguments for %s directive in skeleton"),
+         at_directive_name);
+}
+
+static void
+fail_for_at_directive_too_many_args (char const *at_directive_name)
+{
+  fatal (_("too many arguments for %s directive in skeleton"),
+         at_directive_name);
+}
+
+static void
+fail_for_invalid_at (char const *at)
+{
+  fatal ("invalid @ in skeleton: %s", at);
 }
diff --git a/src/state.c b/src/state.c
index 4eb39f9..666e0cc 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1,24 +1,21 @@
-/* Type definitions for nondeterministic finite state machine for Bison.
+/* Type definitions for the finite state machine for Bison.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
-   Foundation, Inc.
+   Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
@@ -28,6 +25,7 @@
 #include "complain.h"
 #include "gram.h"
 #include "state.h"
+#include "print-xml.h"
 
 
 			/*-------------------.
@@ -61,7 +59,7 @@
   int j;
   for (j = 0; ; j++)
     {
-      assert (j < shifts->num);
+      aver (j < shifts->num);
       if (TRANSITION_SYMBOL (shifts, j) == sym)
 	return shifts->states[j];
     }
@@ -105,7 +103,7 @@
   size_t rules_size = num * sizeof *reds;
   reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
   res->num = num;
-  res->look_ahead_tokens = NULL;
+  res->lookahead_tokens = NULL;
   memcpy (res->rules, reds, rules_size);
   return res;
 }
@@ -135,7 +133,7 @@
   state *res;
   size_t items_size = nitems * sizeof *core;
 
-  assert (nstates < STATE_NUMBER_MAXIMUM);
+  aver (nstates < STATE_NUMBER_MAXIMUM);
 
   res = xmalloc (offsetof (state, items) + items_size);
   res->number = nstates++;
@@ -143,8 +141,10 @@
   res->transitions = NULL;
   res->reductions = NULL;
   res->errs = NULL;
+  res->state_list = NULL;
   res->consistent = 0;
   res->solved_conflicts = NULL;
+  res->solved_conflicts_xml = NULL;
 
   res->nitems = nitems;
   memcpy (res->items, core, items_size);
@@ -154,6 +154,32 @@
   return res;
 }
 
+state *
+state_new_isocore (state const *s)
+{
+  state *res;
+  size_t items_size = s->nitems * sizeof *s->items;
+
+  aver (nstates < STATE_NUMBER_MAXIMUM);
+
+  res = xmalloc (offsetof (state, items) + items_size);
+  res->number = nstates++;
+  res->accessing_symbol = s->accessing_symbol;
+  res->transitions =
+    transitions_new (s->transitions->num, s->transitions->states);
+  res->reductions = reductions_new (s->reductions->num, s->reductions->rules);
+  res->errs = NULL;
+  res->state_list = NULL;
+  res->consistent = s->consistent;
+  res->solved_conflicts = NULL;
+  res->solved_conflicts_xml = NULL;
+
+  res->nitems = s->nitems;
+  memcpy (res->items, s->items, items_size);
+
+  return res;
+}
+
 
 /*---------.
 | Free S.  |
@@ -176,7 +202,7 @@
 void
 state_transitions_set (state *s, int num, state **trans)
 {
-  assert (!s->transitions);
+  aver (!s->transitions);
   s->transitions = transitions_new (num, trans);
 }
 
@@ -188,7 +214,7 @@
 void
 state_reductions_set (state *s, int num, rule **reds)
 {
-  assert (!s->reductions);
+  aver (!s->reductions);
   s->reductions = reductions_new (num, reds);
 }
 
@@ -212,32 +238,32 @@
 void
 state_errs_set (state *s, int num, symbol **tokens)
 {
-  assert (!s->errs);
+  aver (!s->errs);
   s->errs = errs_new (num, tokens);
 }
 
 
 
-/*---------------------------------------------------.
-| Print on OUT all the look-ahead tokens such that S |
-| wants to reduce R.                                 |
-`---------------------------------------------------*/
+/*--------------------------------------------------.
+| Print on OUT all the lookahead tokens such that S |
+| wants to reduce R.                                |
+`--------------------------------------------------*/
 
 void
-state_rule_look_ahead_tokens_print (state *s, rule *r, FILE *out)
+state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out)
 {
   /* Find the reduction we are handling.  */
   reductions *reds = s->reductions;
   int red = state_reduction_find (s, r);
 
   /* Print them if there are.  */
-  if (reds->look_ahead_tokens && red != -1)
+  if (reds->lookahead_tokens && red != -1)
     {
       bitset_iterator biter;
       int k;
       char const *sep = "";
       fprintf (out, "  [");
-      BITSET_FOR_EACH (biter, reds->look_ahead_tokens[red], k, 0)
+      BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
 	{
 	  fprintf (out, "%s%s", sep, symbols[k]->tag);
 	  sep = ", ";
@@ -246,6 +272,29 @@
     }
 }
 
+void
+state_rule_lookahead_tokens_print_xml (state *s, rule *r,
+				       FILE *out, int level)
+{
+  /* Find the reduction we are handling.  */
+  reductions *reds = s->reductions;
+  int red = state_reduction_find (s, r);
+
+  /* Print them if there are.  */
+  if (reds->lookahead_tokens && red != -1)
+    {
+      bitset_iterator biter;
+      int k;
+      xml_puts (out, level, "<lookaheads>");
+      BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
+	{
+	  xml_printf (out, level + 1, "<symbol>%s</symbol>",
+		      xml_escape (symbols[k]->tag));
+	}
+      xml_puts (out, level, "</lookaheads>");
+    }
+}
+
 
 /*---------------------.
 | A state hash table.  |
@@ -329,7 +378,8 @@
 void
 state_hash_insert (state *s)
 {
-  hash_insert (state_table, s);
+  if (!hash_insert (state_table, s))
+    xalloc_die ();
 }
 
 
@@ -352,6 +402,52 @@
   return entry;
 }
 
+
+/*--------------------------------------------------------.
+| Record S and all states reachable from S in REACHABLE.  |
+`--------------------------------------------------------*/
+
+static void
+state_record_reachable_states (state *s, bitset reachable)
+{
+  if (bitset_test (reachable, s->number))
+    return;
+  bitset_set (reachable, s->number);
+  {
+    int i;
+    for (i = 0; i < s->transitions->num; ++i)
+      if (!TRANSITION_IS_DISABLED (s->transitions, i))
+        state_record_reachable_states (s->transitions->states[i], reachable);
+  }
+}
+
+void
+state_remove_unreachable_states (state_number old_to_new[])
+{
+  state_number nstates_reachable = 0;
+  bitset reachable = bitset_create (nstates, BITSET_FIXED);
+  state_record_reachable_states (states[0], reachable);
+  {
+    state_number i;
+    for (i = 0; i < nstates; ++i)
+      {
+        if (bitset_test (reachable, states[i]->number))
+          {
+            states[nstates_reachable] = states[i];
+            states[nstates_reachable]->number = nstates_reachable;
+            old_to_new[i] = nstates_reachable++;
+          }
+        else
+          {
+            state_free (states[i]);
+            old_to_new[i] = nstates;
+          }
+      }
+  }
+  nstates = nstates_reachable;
+  bitset_free (reachable);
+}
+
 /* All the decorated states, indexed by the state number.  */
 state **states = NULL;
 
diff --git a/src/state.h b/src/state.h
index 440cd46..dfdc49d 100644
--- a/src/state.h
+++ b/src/state.h
@@ -1,24 +1,22 @@
-/* Type definitions for nondeterministic finite state machine for Bison.
+/* Type definitions for the finite state machine for Bison.
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2004 Free
-   Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 2000-2004, 2007, 2009-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 /* These type definitions are used to represent a nondeterministic
@@ -44,13 +42,13 @@
    ACCESSING_SYMBOL of the core.
 
    Each core contains a vector of NITEMS items which are the indices
-   in the RITEMS vector of the items that are selected in this state.
+   in the RITEM vector of the items that are selected in this state.
 
-   The two types of actions are shifts/gotos (push the look-ahead token
+   The two types of actions are shifts/gotos (push the lookahead token
    and read another/goto to the state designated by a nterm) and
    reductions (combine the last n things on the stack via a rule,
    replace them with the symbol that the rule derives, and leave the
-   look-ahead token alone).  When the states are generated, these
+   lookahead token alone).  When the states are generated, these
    actions are represented in two other lists.
 
    Each transition structure describes the possible transitions out
@@ -63,9 +61,8 @@
    deletes transitions by having them point to zero.
 
    Each reductions structure describes the possible reductions at the
-   state whose number is in the number field.  The data is a list of
-   nreds rules, represented by their rule numbers.  first_reduction
-   points to the list of these structures.
+   state whose number is in the number field.  rules is an array of
+   num rules.  lookahead_tokens is an array of bitsets, one per rule.
 
    Conflict resolution can decide that certain tokens in certain
    states should explicitly be errors (for implementing %nonassoc).
@@ -185,7 +182,8 @@
 typedef struct
 {
   int num;
-  bitset *look_ahead_tokens;
+  bitset *lookahead_tokens;
+  /* Sorted ascendingly on rule number.  */
   rule *rules[1];
 } reductions;
 
@@ -195,6 +193,8 @@
 | states.  |
 `---------*/
 
+struct state_list;
+
 struct state
 {
   state_number number;
@@ -203,15 +203,22 @@
   reductions *reductions;
   errs *errs;
 
-  /* Nonzero if no look-ahead is needed to decide what to do in state S.  */
+  /* When an includer (such as ielr.c) needs to store states in a list, the
+     includer can define struct state_list as the list node structure and can
+     store in this member a reference to the node containing each state.  */
+  struct state_list *state_list;
+
+  /* If non-zero, then no lookahead sets on reduce actions are needed to
+     decide what to do in state S.  */
   char consistent;
 
   /* If some conflicts were solved thanks to precedence/associativity,
      a human readable description of the resolution.  */
   const char *solved_conflicts;
+  const char *solved_conflicts_xml;
 
-  /* Its items.  Must be last, since ITEMS can be arbitrarily large.
-     */
+  /* Its items.  Must be last, since ITEMS can be arbitrarily large.  Sorted
+     ascendingly on item index in RITEM, which is sorted on rule number.  */
   size_t nitems;
   item_number items[1];
 };
@@ -222,6 +229,7 @@
 /* Create a new state with ACCESSING_SYMBOL for those items.  */
 state *state_new (symbol_number accessing_symbol,
 		  size_t core_size, item_number *core);
+state *state_new_isocore (state const *s);
 
 /* Set the transitions of STATE.  */
 void state_transitions_set (state *s, int num, state **trans);
@@ -234,9 +242,11 @@
 /* Set the errs of STATE.  */
 void state_errs_set (state *s, int num, symbol **errors);
 
-/* Print on OUT all the look-ahead tokens such that this STATE wants to
+/* Print on OUT all the lookahead tokens such that this STATE wants to
    reduce R.  */
-void state_rule_look_ahead_tokens_print (state *s, rule *r, FILE *out);
+void state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out);
+void state_rule_lookahead_tokens_print_xml (state *s, rule *r,
+					    FILE *out, int level);
 
 /* Create/destroy the states hash table.  */
 void state_hash_new (void);
@@ -249,9 +259,16 @@
 /* Insert STATE in the state hash table.  */
 void state_hash_insert (state *s);
 
+/* Remove unreachable states, renumber remaining states, update NSTATES, and
+   write to OLD_TO_NEW a mapping of old state numbers to new state numbers such
+   that the old value of NSTATES is written as the new state number for removed
+   states.  The size of OLD_TO_NEW must be the old value of NSTATES.  */
+void state_remove_unreachable_states (state_number old_to_new[]);
+
 /* All the states, indexed by the state number.  */
 extern state **states;
 
 /* Free all the states.  */
 void states_free (void);
+
 #endif /* !STATE_H_ */
diff --git a/src/symlist.c b/src/symlist.c
index 70db82f..69ac8a1 100644
--- a/src/symlist.c
+++ b/src/symlist.c
@@ -1,23 +1,22 @@
 /* Lists of symbols for Bison
 
-   Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005-2007, 2009-2012 Free Software Foundation,
+   Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
@@ -31,66 +30,130 @@
 `--------------------------------------*/
 
 symbol_list *
-symbol_list_new (symbol *sym, location loc)
+symbol_list_sym_new (symbol *sym, location loc)
 {
   symbol_list *res = xmalloc (sizeof *res);
 
-  res->sym = sym;
-  res->location = loc;
+  res->content_type = SYMLIST_SYMBOL;
+  res->content.sym = sym;
+  res->location = res->sym_loc = loc;
 
   res->midrule = NULL;
+  res->midrule_parent_rule = NULL;
+  res->midrule_parent_rhs_index = 0;
 
-  res->action = NULL;
-  res->used = false;
+  code_props_none_init (&res->action_props);
 
   res->ruleprec = NULL;
   res->dprec = 0;
   res->merger = 0;
 
+  res->named_ref = NULL;
+
   res->next = NULL;
 
   return res;
 }
 
 
-/*------------------.
-| Print this list.  |
-`------------------*/
+/*--------------------------------------------.
+| Create a list containing TYPE_NAME at LOC.  |
+`--------------------------------------------*/
+
+symbol_list *
+symbol_list_type_new (uniqstr type_name, location loc)
+{
+  symbol_list *res = xmalloc (sizeof *res);
+
+  res->content_type = SYMLIST_TYPE;
+  res->content.type_name = type_name;
+  res->location = res->sym_loc = loc;
+  res->named_ref = NULL;
+  res->next = NULL;
+
+  return res;
+}
+
+
+/*----------------------------------------.
+| Create a list containing a <*> at LOC.  |
+`----------------------------------------*/
+
+symbol_list *
+symbol_list_default_tagged_new (location loc)
+{
+  symbol_list *res = xmalloc (sizeof *res);
+
+  res->content_type = SYMLIST_DEFAULT_TAGGED;
+  res->location = res->sym_loc = loc;
+  res->named_ref = NULL;
+  res->next = NULL;
+
+  return res;
+}
+
+
+/*---------------------------------------.
+| Create a list containing a <> at LOC.  |
+`---------------------------------------*/
+
+symbol_list *
+symbol_list_default_tagless_new (location loc)
+{
+  symbol_list *res = xmalloc (sizeof *res);
+
+  res->content_type = SYMLIST_DEFAULT_TAGLESS;
+  res->location = res->sym_loc = loc;
+  res->named_ref = NULL;
+  res->next = NULL;
+
+  return res;
+}
+
+
+/*-----------------------------------------------------------------------.
+| Print this list, for which every content_type must be SYMLIST_SYMBOL.  |
+`-----------------------------------------------------------------------*/
 
 void
-symbol_list_print (const symbol_list *l, FILE *f)
+symbol_list_syms_print (const symbol_list *l, FILE *f)
 {
-  for (/* Nothing. */; l && l->sym; l = l->next)
+  for (/* Nothing. */; l && l->content.sym; l = l->next)
     {
-      symbol_print (l->sym, f);
-      fprintf (stderr, l->used ? " used" : " unused");
-      if (l && l->sym)
+      symbol_print (l->content.sym, f);
+      fprintf (stderr, l->action_props.is_value_used ? " used" : " unused");
+      if (l && l->content.sym)
 	fprintf (f, ", ");
     }
 }
 
 
-/*---------------------------------.
-| Prepend SYM at LOC to the LIST.  |
-`---------------------------------*/
+/*---------------------------.
+| Prepend NODE to the LIST.  |
+`---------------------------*/
 
 symbol_list *
-symbol_list_prepend (symbol_list *list, symbol *sym, location loc)
+symbol_list_prepend (symbol_list *list, symbol_list *node)
 {
-  symbol_list *res = symbol_list_new (sym, loc);
-  res->next = list;
-  return res;
+  node->next = list;
+  return node;
 }
 
 
-/*-------------------------------------------------.
-| Free the LIST, but not the symbols it contains.  |
-`-------------------------------------------------*/
+/*-----------------------------------------------.
+| Free the LIST, but not the items it contains.  |
+`-----------------------------------------------*/
 
 void
 symbol_list_free (symbol_list *list)
 {
-  LIST_FREE (symbol_list, list);
+  symbol_list *node, *next;
+  for (node = list; node; node = next)
+    {
+      next = node->next;
+      named_ref_free (node->named_ref);
+      free (node);
+    }
 }
 
 
@@ -98,19 +161,21 @@
 | Return its length.  |
 `--------------------*/
 
-unsigned int
-symbol_list_length (const symbol_list *l)
+int
+symbol_list_length (symbol_list const *l)
 {
   int res = 0;
-  for (/* Nothing. */; l; l = l->next)
+  for (/* Nothing. */;
+       l && !(l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL);
+       l = l->next)
     ++res;
   return res;
 }
 
 
-/*--------------------------------.
-| Get symbol N in symbol list L.  |
-`--------------------------------*/
+/*------------------------------.
+| Get item N in symbol list L.  |
+`------------------------------*/
 
 symbol_list *
 symbol_list_n_get (symbol_list *l, int n)
@@ -123,7 +188,8 @@
   for (i = 0; i < n; ++i)
     {
       l = l->next;
-      if (l == NULL || l->sym == NULL)
+      if (l == NULL
+          || (l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL))
 	return NULL;
     }
 
@@ -145,18 +211,55 @@
       complain_at (loc, _("invalid $ value: $%d"), n);
       return NULL;
     }
-  return l->sym->type_name;
+  aver (l->content_type == SYMLIST_SYMBOL);
+  return l->content.sym->type_name;
 }
 
-
-/*----------------------------------------.
-| The symbol N in symbol list L is USED.  |
-`----------------------------------------*/
+bool
+symbol_list_null (symbol_list *node)
+{
+  return !node ||
+    (node->content_type == SYMLIST_SYMBOL && !(node->content.sym));
+}
 
 void
-symbol_list_n_used_set (symbol_list *l, int n, bool used)
+symbol_list_destructor_set (symbol_list *node, code_props const *destructor)
 {
-  l = symbol_list_n_get (l, n);
-  if (l)
-    l->used = used;
+  switch (node->content_type)
+    {
+      case SYMLIST_SYMBOL:
+        symbol_destructor_set (node->content.sym, destructor);
+        break;
+      case SYMLIST_TYPE:
+        semantic_type_destructor_set (
+          semantic_type_get (node->content.type_name), destructor);
+        break;
+      case SYMLIST_DEFAULT_TAGGED:
+        default_tagged_destructor_set (destructor);
+        break;
+      case SYMLIST_DEFAULT_TAGLESS:
+        default_tagless_destructor_set (destructor);
+        break;
+    }
+}
+
+void
+symbol_list_printer_set (symbol_list *node, code_props const *printer)
+{
+  switch (node->content_type)
+    {
+      case SYMLIST_SYMBOL:
+        symbol_printer_set (node->content.sym, printer);
+        break;
+      case SYMLIST_TYPE:
+        semantic_type_printer_set (
+          semantic_type_get (node->content.type_name), printer);
+        break;
+      case SYMLIST_DEFAULT_TAGGED:
+        default_tagged_printer_set (printer);
+        break;
+      case SYMLIST_DEFAULT_TAGLESS:
+        default_tagless_printer_set (printer);
+        break;
+    }
 }
diff --git a/src/symlist.h b/src/symlist.h
index 0423d01..63577f7 100644
--- a/src/symlist.h
+++ b/src/symlist.h
@@ -1,83 +1,129 @@
 /* Lists of symbols for Bison
 
-   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005-2007, 2009-2012 Free Software Foundation,
+   Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef SYMLIST_H_
 # define SYMLIST_H_
 
 # include "location.h"
+# include "scan-code.h"
 # include "symtab.h"
+# include "named-ref.h"
 
 /* A list of symbols, used during the parsing to store the rules.  */
 typedef struct symbol_list
 {
-  /* The symbol.  */
-  symbol *sym;
+  /**
+   * Whether this node contains a symbol, a semantic type, a \c <*>, or a
+   * \c <>.
+   */
+  enum {
+    SYMLIST_SYMBOL, SYMLIST_TYPE,
+    SYMLIST_DEFAULT_TAGGED, SYMLIST_DEFAULT_TAGLESS
+  } content_type;
+  union {
+    /**
+     * The symbol or \c NULL iff
+     * <tt>symbol_list::content_type = SYMLIST_SYMBOL</tt>.
+     */
+    symbol *sym;
+    /**
+     * The semantic type iff <tt>symbol_list::content_type = SYMLIST_TYPE</tt>.
+     */
+    uniqstr type_name;
+  } content;
   location location;
 
-  /* If this symbol is the generated lhs for a mid-rule, a pointer to
-     that mid-rule.  */
+  /* Proper location of the symbol, not all the rule */
+  location sym_loc;
+
+  /* If this symbol is the generated lhs for a midrule but this is the rule in
+     whose rhs it appears, MIDRULE = a pointer to that midrule.  */
   struct symbol_list *midrule;
 
-  /* The action is attached to the LHS of a rule. */
-  const char *action;
-  location action_location;
+  /* If this symbol is the generated lhs for a midrule and this is that
+     midrule, MIDRULE_PARENT_RULE = a pointer to the rule in whose rhs it
+     appears, and MIDRULE_PARENT_RHS_INDEX = its rhs index (1-origin) in the
+     parent rule.  */
+  struct symbol_list *midrule_parent_rule;
+  int midrule_parent_rhs_index;
 
-  /* Whether this symbol's value is used in the current action. */
-  bool used;
+  /* The action is attached to the LHS of a rule, but action properties for
+   * each RHS are also stored here.  */
+  code_props action_props;
 
   /* Precedence/associativity.  */
   symbol *ruleprec;
   int dprec;
   int merger;
+  location merger_declaration_location;
+
+  /* Named reference. */
+  named_ref *named_ref;
 
   /* The list.  */
   struct symbol_list *next;
 } symbol_list;
 
 
-/* Create a list containing SYM at LOC.  */
-symbol_list *symbol_list_new (symbol *sym, location loc);
+/** Create a list containing \c sym at \c loc.  */
+symbol_list *symbol_list_sym_new (symbol *sym, location loc);
 
-/* Print it.  */
-void symbol_list_print (const symbol_list *l, FILE *f);
+/** Create a list containing \c type_name at \c loc.  */
+symbol_list *symbol_list_type_new (uniqstr type_name, location loc);
 
-/* Prepend SYM at LOC to the LIST.  */
-symbol_list *symbol_list_prepend (symbol_list *l,
-				  symbol *sym,
-				  location loc);
+/** Create a list containing a \c <*> at \c loc.  */
+symbol_list *symbol_list_default_tagged_new (location loc);
+/** Create a list containing a \c <> at \c loc.  */
+symbol_list *symbol_list_default_tagless_new (location loc);
 
-/* Free the LIST, but not the symbols it contains.  */
-void symbol_list_free (symbol_list *l);
+/** Print this list.
 
-/* Return its length. */
-unsigned int symbol_list_length (const symbol_list *l);
+  \pre For every node \c n in the list, <tt>n->content_type =
+  SYMLIST_SYMBOL</tt>.  */
+void symbol_list_syms_print (const symbol_list *l, FILE *f);
 
-/* Get symbol N in symbol list L.  */
+/** Prepend \c node to \c list.  */
+symbol_list *symbol_list_prepend (symbol_list *list, symbol_list *node);
+
+/** Free \c list, but not the items it contains.  */
+void symbol_list_free (symbol_list *list);
+
+/** Return the length of \c l. */
+int symbol_list_length (symbol_list const *l);
+
+/** Get item \c n in symbol list \c l.  */
 symbol_list *symbol_list_n_get (symbol_list *l, int n);
 
 /* Get the data type (alternative in the union) of the value for
    symbol N in rule RULE.  */
 uniqstr symbol_list_n_type_name_get (symbol_list *l, location loc, int n);
 
-/* The symbol N in symbol list L is USED.  */
-void symbol_list_n_used_set (symbol_list *l, int n, bool used);
+/* Check whether the node is a border element of a rule. */
+bool symbol_list_null (symbol_list *node);
+
+/** Set the \c \%destructor for \c node as \c code at \c loc.  */
+void symbol_list_destructor_set (symbol_list *node,
+                                 code_props const *destructor);
+
+/** Set the \c \%printer for \c node as \c code at \c loc.  */
+void symbol_list_printer_set (symbol_list *node,
+                              code_props const *printer);
 
 #endif /* !SYMLIST_H_ */
diff --git a/src/symtab.c b/src/symtab.c
index ef59c6e..56cfe51 100644
--- a/src/symtab.c
+++ b/src/symtab.c
@@ -1,35 +1,39 @@
 /* Symbol table manager for Bison.
 
-   Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006 Free
-   Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 2000-2002, 2004-2012 Free Software
+   Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
 #include <hash.h>
-#include <quotearg.h>
 
 #include "complain.h"
 #include "gram.h"
 #include "symtab.h"
 
+/*-------------------------------------------------------------------.
+| Symbols sorted by tag.  Allocated by the first invocation of       |
+| symbols_do, after which no more symbols should be created.         |
+`-------------------------------------------------------------------*/
+
+static symbol **symbols_sorted = NULL;
+
 /*------------------------.
 | Distinguished symbols.  |
 `------------------------*/
@@ -41,6 +45,15 @@
 symbol *startsymbol = NULL;
 location startsymbol_location;
 
+/*---------------------------------------.
+| Default %destructor's and %printer's.  |
+`---------------------------------------*/
+
+static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT;
+static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT;
+static code_props default_tagged_printer = CODE_PROPS_NONE_INIT;
+static code_props default_tagless_printer = CODE_PROPS_NONE_INIT;
+
 /*---------------------------------.
 | Create a new symbol, named TAG.  |
 `---------------------------------*/
@@ -51,12 +64,19 @@
   symbol *res = xmalloc (sizeof *res);
 
   uniqstr_assert (tag);
+
+  /* If the tag is not a string (starts with a double quote), check
+     that it is valid for Yacc. */
+  if (tag[0] != '\"' && tag[0] != '\'' && mbschr (tag, '-'))
+    yacc_at (loc, _("POSIX Yacc forbids dashes in symbol names: %s"),
+             tag);
+
   res->tag = tag;
   res->location = loc;
 
   res->type_name = NULL;
-  res->destructor = NULL;
-  res->printer = NULL;
+  code_props_none_init (&res->destructor);
+  code_props_none_init (&res->printer);
 
   res->number = NUMBER_UNDEFINED;
   res->prec = 0;
@@ -74,6 +94,23 @@
   return res;
 }
 
+/*----------------------------------------.
+| Create a new semantic type, named TAG.  |
+`----------------------------------------*/
+
+static semantic_type *
+semantic_type_new (uniqstr tag)
+{
+  semantic_type *res = xmalloc (sizeof *res);
+
+  uniqstr_assert (tag);
+  res->tag = tag;
+  code_props_none_init (&res->destructor);
+  code_props_none_init (&res->printer);
+
+  return res;
+}
+
 
 /*-----------------.
 | Print a symbol.  |
@@ -83,6 +120,10 @@
   if (s->Attr)						\
     fprintf (f, " %s { %s }", #Attr, s->Attr)
 
+#define SYMBOL_CODE_PRINT(Attr)                         \
+  if (s->Attr.code)                                     \
+    fprintf (f, " %s { %s }", #Attr, s->Attr.code)
+
 void
 symbol_print (symbol *s, FILE *f)
 {
@@ -90,14 +131,15 @@
     {
       fprintf (f, "\"%s\"", s->tag);
       SYMBOL_ATTR_PRINT (type_name);
-      SYMBOL_ATTR_PRINT (destructor);
-      SYMBOL_ATTR_PRINT (printer);
+      SYMBOL_CODE_PRINT (destructor);
+      SYMBOL_CODE_PRINT (printer);
     }
   else
     fprintf (f, "<NULL>");
 }
 
 #undef SYMBOL_ATTR_PRINT
+#undef SYMBOL_CODE_PRINT
 
 /*------------------------------------------------------------------.
 | Complain that S's WHAT is redeclared at SECOND, and was first set |
@@ -105,12 +147,26 @@
 `------------------------------------------------------------------*/
 
 static void
-redeclaration (symbol* s, const char *what, location first, location second)
+symbol_redeclaration (symbol *s, const char *what, location first,
+                      location second)
 {
-  complain_at (second, _("%s redeclaration for %s"), what, s->tag);
-  complain_at (first, _("first declaration"));
+  unsigned i = 0;
+  complain_at_indent (second, &i, _("%s redeclaration for %s"), what, s->tag);
+  i += SUB_INDENT;
+  complain_at_indent (first, &i, _("previous declaration"));
 }
 
+static void
+semantic_type_redeclaration (semantic_type *s, const char *what, location first,
+                             location second)
+{
+  unsigned i = 0;
+  complain_at_indent (second, &i, _("%s redeclaration for <%s>"), what, s->tag);
+  i += SUB_INDENT;
+  complain_at_indent (first, &i, _("previous declaration"));
+}
+
+
 
 /*-----------------------------------------------------------------.
 | Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 |
@@ -123,47 +179,123 @@
   if (type_name)
     {
       if (sym->type_name)
-	redeclaration (sym, "%type", sym->type_location, loc);
+	symbol_redeclaration (sym, "%type", sym->type_location, loc);
       uniqstr_assert (type_name);
       sym->type_name = type_name;
       sym->type_location = loc;
     }
 }
 
-
-/*------------------------------------------------------------------.
-| Set the DESTRUCTOR associated with SYM.  Do nothing if passed 0.  |
-`------------------------------------------------------------------*/
+/*-----------------------------------------.
+| Set the DESTRUCTOR associated with SYM.  |
+`-----------------------------------------*/
 
 void
-symbol_destructor_set (symbol *sym, const char *destructor, location loc)
+symbol_destructor_set (symbol *sym, code_props const *destructor)
 {
-  if (destructor)
-    {
-      if (sym->destructor)
-	redeclaration (sym, "%destructor", sym->destructor_location, loc);
-      sym->destructor = destructor;
-      sym->destructor_location = loc;
-    }
+  if (sym->destructor.code)
+    symbol_redeclaration (sym, "%destructor", sym->destructor.location,
+                          destructor->location);
+  sym->destructor = *destructor;
 }
 
-
-/*---------------------------------------------------------------.
-| Set the PRINTER associated with SYM.  Do nothing if passed 0.  |
-`---------------------------------------------------------------*/
+/*------------------------------------------.
+| Set the DESTRUCTOR associated with TYPE.  |
+`------------------------------------------*/
 
 void
-symbol_printer_set (symbol *sym, const char *printer, location loc)
+semantic_type_destructor_set (semantic_type *type,
+                              code_props const *destructor)
 {
-  if (printer)
-    {
-      if (sym->printer)
-	redeclaration (sym, "%printer", sym->destructor_location, loc);
-      sym->printer = printer;
-      sym->printer_location = loc;
-    }
+  if (type->destructor.code)
+    semantic_type_redeclaration (type, "%destructor",
+                                 type->destructor.location,
+                                 destructor->location);
+  type->destructor = *destructor;
 }
 
+/*---------------------------------------.
+| Get the computed %destructor for SYM.  |
+`---------------------------------------*/
+
+code_props const *
+symbol_destructor_get (symbol const *sym)
+{
+  /* Per-symbol %destructor.  */
+  if (sym->destructor.code)
+    return &sym->destructor;
+
+  /* Per-type %destructor.  */
+  if (sym->type_name)
+    {
+      code_props const *destructor =
+        &semantic_type_get (sym->type_name)->destructor;
+      if (destructor->code)
+        return destructor;
+    }
+
+  /* Apply default %destructor's only to user-defined symbols.  */
+  if (sym->tag[0] == '$' || sym == errtoken)
+    return &code_props_none;
+
+  if (sym->type_name)
+    return &default_tagged_destructor;
+  return &default_tagless_destructor;
+}
+
+/*--------------------------------------.
+| Set the PRINTER associated with SYM.  |
+`--------------------------------------*/
+
+void
+symbol_printer_set (symbol *sym, code_props const *printer)
+{
+  if (sym->printer.code)
+    symbol_redeclaration (sym, "%printer",
+                          sym->printer.location, printer->location);
+  sym->printer = *printer;
+}
+
+/*---------------------------------------.
+| Set the PRINTER associated with TYPE.  |
+`---------------------------------------*/
+
+void
+semantic_type_printer_set (semantic_type *type, code_props const *printer)
+{
+  if (type->printer.code)
+    semantic_type_redeclaration (type, "%printer",
+                                 type->printer.location, printer->location);
+  type->printer = *printer;
+}
+
+/*------------------------------------.
+| Get the computed %printer for SYM.  |
+`------------------------------------*/
+
+code_props const *
+symbol_printer_get (symbol const *sym)
+{
+  /* Per-symbol %printer.  */
+  if (sym->printer.code)
+    return &sym->printer;
+
+  /* Per-type %printer.  */
+  if (sym->type_name)
+    {
+      code_props const *printer = &semantic_type_get (sym->type_name)->printer;
+      if (printer->code)
+        return printer;
+    }
+
+  /* Apply the default %printer only to user-defined symbols.  */
+  if (sym->tag[0] == '$' || sym == errtoken)
+    return &code_props_none;
+
+  if (sym->type_name)
+    return &default_tagged_printer;
+  return &default_tagless_printer;
+}
 
 /*-----------------------------------------------------------------.
 | Set the PRECEDENCE associated with SYM.  Does nothing if invoked |
@@ -176,7 +308,8 @@
   if (a != undef_assoc)
     {
       if (sym->prec != 0)
-	redeclaration (sym, assoc_to_string (a), sym->prec_location, loc);
+	symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
+                              loc);
       sym->prec = prec;
       sym->assoc = a;
       sym->prec_location = loc;
@@ -223,21 +356,26 @@
 void
 symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
 {
-  assert (sym->class == token_sym);
+  int *user_token_numberp;
 
-  if (sym->user_token_number != USER_NUMBER_UNDEFINED
-      && sym->user_token_number != user_token_number)
+  if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
+    user_token_numberp = &sym->user_token_number;
+  else
+    user_token_numberp = &sym->alias->user_token_number;
+  if (*user_token_numberp != USER_NUMBER_UNDEFINED
+      && *user_token_numberp != user_token_number)
     complain_at (loc, _("redefining user token number of %s"), sym->tag);
 
-  sym->user_token_number = user_token_number;
+  *user_token_numberp = user_token_number;
   /* User defined $end token? */
   if (user_token_number == 0)
     {
       endtoken = sym;
-      endtoken->number = 0;
       /* It is always mapped to 0, so it was already counted in
 	 NTOKENS.  */
-      --ntokens;
+      if (endtoken->number != NUMBER_UNDEFINED)
+        --ntokens;
+      endtoken->number = 0;
     }
 }
 
@@ -270,34 +408,24 @@
 }
 
 
-/*------------------------------------------------------------------.
-| Declare the new symbol SYM.  Make it an alias of SYMVAL, and type |
-| SYMVAL with SYM's type.                                           |
-`------------------------------------------------------------------*/
-
 void
-symbol_make_alias (symbol *sym, symbol *symval, location loc)
+symbol_make_alias (symbol *sym, symbol *str, location loc)
 {
-  if (symval->alias)
-    warn_at (loc, _("symbol `%s' used more than once as a literal string"),
-	     symval->tag);
+  if (str->alias)
+    warn_at (loc, _("symbol %s used more than once as a literal string"),
+             str->tag);
   else if (sym->alias)
-    warn_at (loc, _("symbol `%s' given more than one literal string"),
-	     sym->tag);
+    warn_at (loc, _("symbol %s given more than one literal string"),
+             sym->tag);
   else
     {
-      symval->class = token_sym;
-      symval->user_token_number = sym->user_token_number;
-      sym->user_token_number = USER_NUMBER_ALIAS;
-      symval->alias = sym;
-      sym->alias = symval;
-      /* sym and symval combined are only one symbol.  */
-      nsyms--;
-      ntokens--;
-      assert (ntokens == sym->number || ntokens == symval->number);
-      sym->number = symval->number =
-	(symval->number < sym->number) ? symval->number : sym->number;
-      symbol_type_set (symval, sym->type_name, loc);
+      str->class = token_sym;
+      str->user_token_number = sym->user_token_number;
+      sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
+      str->alias = sym;
+      sym->alias = str;
+      str->number = sym->number;
+      symbol_type_set (str, sym->type_name, loc);
     }
 }
 
@@ -310,48 +438,47 @@
 static inline void
 symbol_check_alias_consistency (symbol *this)
 {
-  symbol *alias = this;
-  symbol *orig  = this->alias;
+  symbol *sym = this;
+  symbol *str = this->alias;
 
-  /* Check only those that _are_ the aliases.  */
-  if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
+  /* Check only the symbol in the symbol-string pair.  */
+  if (!(this->alias
+        && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
     return;
 
-  if (orig->type_name != alias->type_name)
+  if (str->type_name != sym->type_name)
     {
-      if (orig->type_name)
-	symbol_type_set (alias, orig->type_name, orig->type_location);
+      if (str->type_name)
+	symbol_type_set (sym, str->type_name, str->type_location);
       else
-	symbol_type_set (orig, alias->type_name, alias->type_location);
+	symbol_type_set (str, sym->type_name, sym->type_location);
     }
 
 
-  if (orig->destructor || alias->destructor)
+  if (str->destructor.code || sym->destructor.code)
     {
-      if (orig->destructor)
-	symbol_destructor_set (alias, orig->destructor,
-			       orig->destructor_location);
+      if (str->destructor.code)
+	symbol_destructor_set (sym, &str->destructor);
       else
-	symbol_destructor_set (orig, alias->destructor,
-			       alias->destructor_location);
+	symbol_destructor_set (str, &sym->destructor);
     }
 
-  if (orig->printer || alias->printer)
+  if (str->printer.code || sym->printer.code)
     {
-      if (orig->printer)
-	symbol_printer_set (alias, orig->printer, orig->printer_location);
+      if (str->printer.code)
+	symbol_printer_set (sym, &str->printer);
       else
-	symbol_printer_set (orig, alias->printer, alias->printer_location);
+	symbol_printer_set (str, &sym->printer);
     }
 
-  if (alias->prec || orig->prec)
+  if (sym->prec || str->prec)
     {
-      if (orig->prec)
-	symbol_precedence_set (alias, orig->prec, orig->assoc,
-			       orig->prec_location);
+      if (str->prec)
+	symbol_precedence_set (sym, str->prec, str->assoc,
+			       str->prec_location);
       else
-	symbol_precedence_set (orig, alias->prec, alias->assoc,
-			       alias->prec_location);
+	symbol_precedence_set (str, sym->prec, sym->assoc,
+			       sym->prec_location);
     }
 }
 
@@ -372,31 +499,11 @@
 static inline bool
 symbol_pack (symbol *this)
 {
+  aver (this->number != NUMBER_UNDEFINED);
   if (this->class == nterm_sym)
-    {
-      this->number += ntokens;
-    }
-  else if (this->alias)
-    {
-      /* This symbol and its alias are a single token defn.
-	 Allocate a tokno, and assign to both check agreement of
-	 prec and assoc fields and make both the same */
-      if (this->number == NUMBER_UNDEFINED)
-	{
-	  if (this == endtoken || this->alias == endtoken)
-	    this->number = this->alias->number = 0;
-	  else
-	    {
-	      assert (this->alias->number != NUMBER_UNDEFINED);
-	      this->number = this->alias->number;
-	    }
-	}
-      /* Do not do processing below for USER_NUMBER_ALIASes.  */
-      if (this->user_token_number == USER_NUMBER_ALIAS)
-	return true;
-    }
-  else /* this->class == token_sym */
-    assert (this->number != NUMBER_UNDEFINED);
+    this->number += ntokens;
+  else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
+    return true;
 
   symbols[this->number] = this;
   return true;
@@ -409,7 +516,29 @@
 }
 
 
+static void
+user_token_number_redeclaration (int num, symbol *first, symbol *second)
+{
+  unsigned i = 0;
+  /* User token numbers are not assigned during the parsing, but in a
+     second step, via a traversal of the symbol table sorted on tag.
 
+     However, error messages make more sense if we keep the first
+     declaration first.  */
+  if (location_cmp (first->location, second->location) > 0)
+    {
+      symbol* tmp = first;
+      first = second;
+      second = tmp;
+    }
+  complain_at_indent (second->location, &i,
+                      _("user token number %d redeclaration for %s"),
+                      num, second->tag);
+  i += SUB_INDENT;
+  complain_at_indent (first->location, &i,
+                      _("previous declaration for %s"),
+                      first->tag);
+}
 
 /*--------------------------------------------------.
 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |
@@ -420,14 +549,14 @@
 {
   /* Non-terminal? */
   if (this->class == token_sym
-      && this->user_token_number != USER_NUMBER_ALIAS)
+      && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
     {
       /* A token which translation has already been set? */
       if (token_translations[this->user_token_number] != undeftoken->number)
-	complain_at (this->location,
-		     _("tokens %s and %s both assigned number %d"),
-		     symbols[token_translations[this->user_token_number]]->tag,
-		     this->tag, this->user_token_number);
+	user_token_number_redeclaration
+          (this->user_token_number,
+           symbols[token_translations[this->user_token_number]],
+           this);
 
       token_translations[this->user_token_number] = this->number;
     }
@@ -442,14 +571,15 @@
 }
 
 
-/*----------------------.
-| A symbol hash table.  |
-`----------------------*/
+/*---------------------------------------.
+| Symbol and semantic type hash tables.  |
+`---------------------------------------*/
 
-/* Initial capacity of symbols hash table.  */
+/* Initial capacity of symbol and semantic type hash table.  */
 #define HT_INITIAL_CAPACITY 257
 
 static struct hash_table *symbol_table = NULL;
+static struct hash_table *semantic_type_table = NULL;
 
 static inline bool
 hash_compare_symbol (const symbol *m1, const symbol *m2)
@@ -458,12 +588,25 @@
   return UNIQSTR_EQ (m1->tag, m2->tag);
 }
 
+static inline bool
+hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
+{
+  /* Since names are unique, we can compare the pointers themselves.  */
+  return UNIQSTR_EQ (m1->tag, m2->tag);
+}
+
 static bool
 hash_symbol_comparator (void const *m1, void const *m2)
 {
   return hash_compare_symbol (m1, m2);
 }
 
+static bool
+hash_semantic_type_comparator (void const *m1, void const *m2)
+{
+  return hash_compare_semantic_type (m1, m2);
+}
+
 static inline size_t
 hash_symbol (const symbol *m, size_t tablesize)
 {
@@ -471,12 +614,24 @@
   return ((uintptr_t) m->tag) % tablesize;
 }
 
+static inline size_t
+hash_semantic_type (const semantic_type *m, size_t tablesize)
+{
+  /* Since names are unique, we can hash the pointer itself.  */
+  return ((uintptr_t) m->tag) % tablesize;
+}
+
 static size_t
 hash_symbol_hasher (void const *m, size_t tablesize)
 {
   return hash_symbol (m, tablesize);
 }
 
+static size_t
+hash_semantic_type_hasher (void const *m, size_t tablesize)
+{
+  return hash_semantic_type (m, tablesize);
+}
 
 /*-------------------------------.
 | Create the symbol hash table.  |
@@ -490,6 +645,62 @@
 				  hash_symbol_hasher,
 				  hash_symbol_comparator,
 				  free);
+  semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
+				         NULL,
+				         hash_semantic_type_hasher,
+				         hash_semantic_type_comparator,
+				         free);
+}
+
+
+/*----------------------------------------------------------------.
+| Find the symbol named KEY, and return it.  If it does not exist |
+| yet, create it.                                                 |
+`----------------------------------------------------------------*/
+
+symbol *
+symbol_from_uniqstr (const uniqstr key, location loc)
+{
+  symbol probe;
+  symbol *entry;
+
+  probe.tag = key;
+  entry = hash_lookup (symbol_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      aver (!symbols_sorted);
+      entry = symbol_new (key, loc);
+      if (!hash_insert (symbol_table, entry))
+        xalloc_die ();
+    }
+  return entry;
+}
+
+
+/*-----------------------------------------------------------------------.
+| Find the semantic type named KEY, and return it.  If it does not exist |
+| yet, create it.                                                        |
+`-----------------------------------------------------------------------*/
+
+semantic_type *
+semantic_type_from_uniqstr (const uniqstr key)
+{
+  semantic_type probe;
+  semantic_type *entry;
+
+  probe.tag = key;
+  entry = hash_lookup (semantic_type_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      entry = semantic_type_new (key);
+      if (!hash_insert (semantic_type_table, entry))
+        xalloc_die ();
+    }
+  return entry;
 }
 
 
@@ -501,20 +712,19 @@
 symbol *
 symbol_get (const char *key, location loc)
 {
-  symbol probe;
-  symbol *entry;
+  return symbol_from_uniqstr (uniqstr_new (key), loc);
+}
 
-  key = uniqstr_new (key);
-  probe.tag = key;
-  entry = hash_lookup (symbol_table, &probe);
 
-  if (!entry)
-    {
-      /* First insertion in the hash. */
-      entry = symbol_new (key, loc);
-      hash_insert (symbol_table, entry);
-    }
-  return entry;
+/*-----------------------------------------------------------------------.
+| Find the semantic type named KEY, and return it.  If it does not exist |
+| yet, create it.                                                        |
+`-----------------------------------------------------------------------*/
+
+semantic_type *
+semantic_type_get (const char *key)
+{
+  return semantic_type_from_uniqstr (uniqstr_new (key));
 }
 
 
@@ -532,13 +742,18 @@
 
   symbol *sym;
 
-  sprintf (buf, "@%d", ++dummy_count);
+  sprintf (buf, "$@%d", ++dummy_count);
   sym = symbol_get (buf, loc);
   sym->class = nterm_sym;
   sym->number = nvars++;
   return sym;
 }
 
+bool
+symbol_is_dummy (const symbol *sym)
+{
+  return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
+}
 
 /*-------------------.
 | Free the symbols.  |
@@ -548,7 +763,9 @@
 symbols_free (void)
 {
   hash_free (symbol_table);
+  hash_free (semantic_type_table);
   free (symbols);
+  free (symbols_sorted);
 }
 
 
@@ -557,13 +774,36 @@
 | terminals.                                                     |
 `---------------------------------------------------------------*/
 
+static int
+symbols_cmp (symbol const *a, symbol const *b)
+{
+  return strcmp (a->tag, b->tag);
+}
+
+static int
+symbols_cmp_qsort (void const *a, void const *b)
+{
+  return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
+}
+
 static void
 symbols_do (Hash_processor processor, void *processor_data)
 {
-  hash_do_for_each (symbol_table, processor, processor_data);
+  size_t count = hash_get_n_entries (symbol_table);
+  if (!symbols_sorted)
+    {
+      symbols_sorted = xnmalloc (count, sizeof *symbols_sorted);
+      hash_get_entries (symbol_table, (void**)symbols_sorted, count);
+      qsort (symbols_sorted, count, sizeof *symbols_sorted,
+             symbols_cmp_qsort);
+    }
+  {
+    size_t i;
+    for (i = 0; i < count; ++i)
+      processor (symbols_sorted[i], processor_data);
+  }
 }
 
-
 /*--------------------------------------------------------------.
 | Check that all the symbols are defined.  Report any undefined |
 | symbols and consider them nonterminals.                       |
@@ -639,11 +879,35 @@
 void
 symbols_pack (void)
 {
-  symbols = xcalloc (nsyms, sizeof *symbols);
-
   symbols_do (symbol_check_alias_consistency_processor, NULL);
+
+  symbols = xcalloc (nsyms, sizeof *symbols);
   symbols_do (symbol_pack_processor, NULL);
 
+  /* Aliases leave empty slots in symbols, so remove them.  */
+  {
+    int writei;
+    int readi;
+    int nsyms_old = nsyms;
+    for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
+      {
+        if (symbols[readi] == NULL)
+          {
+            nsyms -= 1;
+            ntokens -= 1;
+          }
+        else
+          {
+            symbols[writei] = symbols[readi];
+            symbols[writei]->number = writei;
+            if (symbols[writei]->alias)
+              symbols[writei]->alias->number = writei;
+            writei += 1;
+          }
+      }
+  }
+  symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
+
   symbols_token_translations_init ();
 
   if (startsymbol->class == unknown_sym)
@@ -655,3 +919,68 @@
 	      _("the start symbol %s is a token"),
 	      startsymbol->tag);
 }
+
+
+/*--------------------------------------------------.
+| Set default tagged/tagless %destructor/%printer.  |
+`--------------------------------------------------*/
+
+void
+default_tagged_destructor_set (code_props const *destructor)
+{
+  if (default_tagged_destructor.code)
+    {
+      unsigned i = 0;
+      complain_at_indent (destructor->location, &i,
+                          _("redeclaration for default tagged %%destructor"));
+      i += SUB_INDENT;
+      complain_at_indent (default_tagged_destructor.location, &i,
+		          _("previous declaration"));
+    }
+  default_tagged_destructor = *destructor;
+}
+
+void
+default_tagless_destructor_set (code_props const *destructor)
+{
+  if (default_tagless_destructor.code)
+    {
+      unsigned i = 0;
+      complain_at_indent (destructor->location, &i,
+                          _("redeclaration for default tagless %%destructor"));
+      i += SUB_INDENT;
+      complain_at_indent (default_tagless_destructor.location, &i,
+                          _("previous declaration"));
+    }
+  default_tagless_destructor = *destructor;
+}
+
+void
+default_tagged_printer_set (code_props const *printer)
+{
+  if (default_tagged_printer.code)
+    {
+      unsigned i = 0;
+      complain_at_indent (printer->location, &i,
+                          _("redeclaration for default tagged %%printer"));
+      i += SUB_INDENT;
+      complain_at_indent (default_tagged_printer.location, &i,
+		          _("previous declaration"));
+    }
+  default_tagged_printer = *printer;
+}
+
+void
+default_tagless_printer_set (code_props const *printer)
+{
+  if (default_tagless_printer.code)
+    {
+      unsigned i = 0;
+      complain_at_indent (printer->location, &i,
+                          _("redeclaration for default tagless %%printer"));
+      i += SUB_INDENT;
+      complain_at_indent (default_tagless_printer.location, &i,
+		          _("previous declaration"));
+    }
+  default_tagless_printer = *printer;
+}
diff --git a/src/symtab.h b/src/symtab.h
index 0f852b7..7d8cf98 100644
--- a/src/symtab.h
+++ b/src/symtab.h
@@ -1,46 +1,50 @@
 /* Definitions for symtab.c and callers, part of Bison.
 
-   Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1992, 2000-2002, 2004-2007, 2009-2012 Free
+   Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/**
+ * \file symtab.h
+ * \brief Manipulating ::symbol.
+ */
 
 #ifndef SYMTAB_H_
 # define SYMTAB_H_
 
 # include "assoc.h"
 # include "location.h"
+# include "scan-code.h"
 # include "uniqstr.h"
 
 /*----------.
 | Symbols.  |
 `----------*/
 
-/* Symbol classes.  */
+/** Symbol classes.  */
 typedef enum
 {
-  unknown_sym,
-  token_sym,		/* terminal symbol */
-  nterm_sym		/* non-terminal */
+  unknown_sym,          /**< Undefined.  */
+  token_sym,		/**< Terminal. */
+  nterm_sym		/**< Non-terminal. */
 } symbol_class;
 
 
-/* Internal token numbers. */
+/** Internal token numbers. */
 typedef int symbol_number;
 #define SYMBOL_NUMBER_MAXIMUM INT_MAX
 
@@ -51,22 +55,36 @@
    symbol_check_alias_consistency.  */
 struct symbol
 {
-  /* The key, name of the symbol.  */
+  /** The key, name of the symbol.  */
   uniqstr tag;
-  /* The location of its first occurrence.  */
+  /** The location of its first occurrence.  */
   location location;
 
-  /* Its %type and associated printer and destructor.  */
+  /** Its \c \%type.
+
+      Beware that this is the type_name as was entered by the user,
+      including silly things such as "]" if she entered "%token <]> t".
+      Therefore, when outputting type_name to M4, be sure to escape it
+      into "@}".  See quoted_output for instance.  */
   uniqstr type_name;
+
+  /** Its \c \%type's location.  */
   location type_location;
 
-  /* Does not own the memory. */
-  const char *destructor;
-  location destructor_location;
+  /** Any \c \%destructor declared specifically for this symbol.
 
-  /* Does not own the memory. */
-  const char *printer;
-  location printer_location;
+      Access this field only through <tt>symbol</tt>'s interface
+      functions.  For example, if <tt>symbol::destructor = NULL</tt>, a
+      default \c \%destructor or a per-type \c \%destructor might be
+      appropriate, and \c symbol_destructor_get will compute the
+      correct one.  */
+  code_props destructor;
+
+  /** Any \c \%printer declared specifically for this symbol.
+
+      Access this field only through <tt>symbol</tt>'s interface functions.
+      \sa symbol::destructor  */
+  code_props printer;
 
   symbol_number number;
   location prec_location;
@@ -74,89 +92,165 @@
   assoc assoc;
   int user_token_number;
 
-  /* Points to the other in the identifier-symbol pair for an alias.
-     Special value USER_NUMBER_ALIAS in the identifier half of the
-     identifier-symbol pair for an alias.  */
+  /* Points to the other in the symbol-string pair for an alias.
+     Special value USER_NUMBER_HAS_STRING_ALIAS in the symbol half of the
+     symbol-string pair for an alias.  */
   symbol *alias;
   symbol_class class;
   bool declared;
 };
 
-/* Undefined user number.  */
+/** Undefined user number.  */
 #define USER_NUMBER_UNDEFINED -1
 
-/* `symbol->user_token_number == USER_NUMBER_ALIAS' means this symbol
-   *has* (not is) a string literal alias.  For instance, `%token foo
+/* `symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
+   this symbol has a literal string alias.  For instance, `%token foo
    "foo"' has `"foo"' numbered regularly, and `foo' numbered as
-   USER_NUMBER_ALIAS.  */
-#define USER_NUMBER_ALIAS -9991
+   USER_NUMBER_HAS_STRING_ALIAS.  */
+#define USER_NUMBER_HAS_STRING_ALIAS -9991
 
 /* Undefined internal token number.  */
 #define NUMBER_UNDEFINED (-1)
 
-/* Print a symbol (for debugging). */
+/** Print a symbol (for debugging). */
 void symbol_print (symbol *s, FILE *f);
 
-/* Fetch (or create) the symbol associated to KEY.  */
+/** Fetch (or create) the symbol associated to KEY.  */
+symbol *symbol_from_uniqstr (const uniqstr key, location loc);
+
+/** Fetch (or create) the symbol associated to KEY.  */
 symbol *symbol_get (const char *key, location loc);
 
-/* Generate a dummy nonterminal, whose name cannot conflict with the
-   user's names.  */
+/** Generate a dummy nonterminal.
+
+   Its name cannot conflict with the user's names.  */
 symbol *dummy_symbol_get (location loc);
 
-/* Declare the new symbol SYM.  Make it an alias of SYMVAL.  */
-void symbol_make_alias (symbol *sym, symbol *symval, location loc);
+/** Is this a dummy nonterminal?  */
+bool symbol_is_dummy (const symbol *sym);
 
-/* Set the TYPE_NAME associated with SYM.  Do nothing if passed 0 as
-   TYPE_NAME.  */
+/**
+ * Make \c str the literal string alias of \c sym.  Copy token number,
+ * symbol number, and type from \c sym to \c str.
+ */
+void symbol_make_alias (symbol *sym, symbol *str, location loc);
+
+/** Set the \c type_name associated with \c sym.
+
+    Do nothing if passed 0 as \c type_name.  */
 void symbol_type_set (symbol *sym, uniqstr type_name, location loc);
 
-/* Set the DESTRUCTOR associated with SYM.  */
-void symbol_destructor_set (symbol *sym, const char *destructor, location loc);
+/** Set the \c destructor associated with \c sym.  */
+void symbol_destructor_set (symbol *sym, code_props const *destructor);
 
-/* Set the PRINTER associated with SYM.  */
-void symbol_printer_set (symbol *sym, const char *printer, location loc);
+/** Get the computed \c \%destructor for \c sym, which was initialized with
+    \c code_props_none_init if there's no \c \%destructor.  */
+code_props const *symbol_destructor_get (symbol const *sym);
 
-/* Set the PRECEDENCE associated with SYM.  Ensure that SYMBOL is a
-   terminal.  Do nothing if invoked with UNDEF_ASSOC as ASSOC.  */
+/** Set the \c printer associated with \c sym.  */
+void symbol_printer_set (symbol *sym, code_props const *printer);
+
+/** Get the computed \c \%printer for \c sym, which was initialized with
+    \c code_props_none_init if there's no \c \%printer.  */
+code_props const *symbol_printer_get (symbol const *sym);
+
+/* Set the \c precedence associated with \c sym.
+
+   Ensure that \a symbol is a terminal.
+   Do nothing if invoked with \c undef_assoc as \c assoc.  */
 void symbol_precedence_set (symbol *sym, int prec, assoc a, location loc);
 
-/* Set the CLASS associated with SYM.  */
+/** Set the \c class associated with \c sym.  */
 void symbol_class_set (symbol *sym, symbol_class class, location loc,
 		       bool declaring);
 
-/* Set the USER_TOKEN_NUMBER associated with SYM.  */
+/** Set the \c user_token_number associated with \c sym.  */
 void symbol_user_token_number_set (symbol *sym, int user_number, location loc);
 
 
-/* Distinguished symbols.  AXIOM is the real start symbol, that used
-   by the automaton.  STARTSYMBOL is the one specified by the user.
-   */
+/** The error token. */
 extern symbol *errtoken;
+/** The token for unknown tokens.  */
 extern symbol *undeftoken;
+/** The end of input token.  */
 extern symbol *endtoken;
+/** The genuine start symbol.
+
+   $accept: start-symbol $end */
 extern symbol *accept;
+
+/** The user start symbol. */
 extern symbol *startsymbol;
+/** The location of the \c \%start declaration.  */
 extern location startsymbol_location;
 
 
-/*---------------.
-| Symbol table.  |
-`---------------*/
+/*-----------------.
+| Semantic types.  |
+`-----------------*/
 
+/** A semantic type and its associated \c \%destructor and \c \%printer.
 
-/* Create the symbol table.  */
+   Access the fields of this struct only through the interface functions in
+   this file.  \sa symbol::destructor  */
+typedef struct {
+  /** The key, name of the semantic type.  */
+  uniqstr tag;
+
+  /** Any \c %destructor declared for this semantic type.  */
+  code_props destructor;
+  /** Any \c %printer declared for this semantic type.  */
+  code_props printer;
+} semantic_type;
+
+/** Fetch (or create) the semantic type associated to KEY.  */
+semantic_type *semantic_type_from_uniqstr (const uniqstr key);
+
+/** Fetch (or create) the semantic type associated to KEY.  */
+semantic_type *semantic_type_get (const char *key);
+
+/** Set the \c destructor associated with \c type.  */
+void semantic_type_destructor_set (semantic_type *type,
+                                   code_props const *destructor);
+
+/** Set the \c printer associated with \c type.  */
+void semantic_type_printer_set (semantic_type *type,
+                                code_props const *printer);
+
+/*----------------------------------.
+| Symbol and semantic type tables.  |
+`----------------------------------*/
+
+/** Create the symbol and semantic type tables.  */
 void symbols_new (void);
 
-/* Free all the memory allocated for symbols.  */
+/** Free all the memory allocated for symbols and semantic types.  */
 void symbols_free (void);
 
-/* Check that all the symbols are defined.  Report any undefined
-   symbols and consider them nonterminals.  */
+/** Check that all the symbols are defined.
+
+    Report any undefined symbols and consider them nonterminals.  */
 void symbols_check_defined (void);
 
-/* Perform various sanity checks, assign symbol numbers, and set up
-   TOKEN_TRANSLATIONS.  */
+/** Sanity checks and #token_translations construction.
+
+   Perform various sanity checks, assign symbol numbers, and set up
+   #token_translations.  */
 void symbols_pack (void);
 
+
+/*---------------------------------------.
+| Default %destructor's and %printer's.  |
+`---------------------------------------*/
+
+/** Set the default \c \%destructor for tagged values.  */
+void default_tagged_destructor_set (code_props const *destructor);
+/** Set the default \c \%destructor for tagless values.  */
+void default_tagless_destructor_set (code_props const *destructor);
+
+/** Set the default \c \%printer for tagged values.  */
+void default_tagged_printer_set (code_props const *printer);
+/** Set the default \c \%printer for tagless values.  */
+void default_tagless_printer_set (code_props const *printer);
+
 #endif /* !SYMTAB_H_ */
diff --git a/src/system.h b/src/system.h
index 6315790..35ff876 100644
--- a/src/system.h
+++ b/src/system.h
@@ -1,12 +1,11 @@
 /* System-dependent definitions for Bison.
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free
-   Software Foundation, Inc.
+   Copyright (C) 2000-2007, 2009-2012 Free Software Foundation, Inc.
 
-   This program is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   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
@@ -14,188 +13,212 @@
    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, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef BISON_SYSTEM_H
-#define BISON_SYSTEM_H
+# define BISON_SYSTEM_H
 
 /* flex 2.5.31 gratutiously defines macros like INT8_MIN.  But this
    runs afoul of pre-C99 compilers that have <inttypes.h> or
    <stdint.h>, which are included below if available.  It also runs
    afoul of pre-C99 compilers that define these macros in <limits.h>.  */
-#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901
-# undef INT8_MIN
-# undef INT16_MIN
-# undef INT32_MIN
-# undef INT8_MAX
-# undef INT16_MAX
-# undef UINT8_MAX
-# undef INT32_MAX
-# undef UINT16_MAX
-# undef UINT32_MAX
-#endif
+# if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901
+#  undef INT8_MIN
+#  undef INT16_MIN
+#  undef INT32_MIN
+#  undef INT8_MAX
+#  undef INT16_MAX
+#  undef UINT8_MAX
+#  undef INT32_MAX
+#  undef UINT16_MAX
+#  undef UINT32_MAX
+# endif
 
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "unlocked-io.h"
-
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#if HAVE_UNISTD_H
+# include <limits.h>
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
 # include <unistd.h>
-#endif
-
-#if HAVE_INTTYPES_H
 # include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
 
-#if ! HAVE_UINTPTR_T
+#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
+#define STREQ(L, R)  (strcmp(L, R) == 0)
+#define STRNEQ(L, R) (!STREQ(L, R))
+
+# ifndef UINTPTR_MAX
 /* This isn't perfect, but it's good enough for Bison, which needs
    only to hash pointers.  */
 typedef size_t uintptr_t;
-#endif
+# endif
 
-#include <verify.h>
-#include <xalloc.h>
+/* Version mismatch. */
+# define EX_MISMATCH 63
 
+/*---------.
+| Gnulib.  |
+`---------*/
 
-/*---------------------.
-| Missing prototypes.  |
-`---------------------*/
-
-#include <stpcpy.h>
-
-/* From lib/basename.c. */
-char *base_name (char const *name);
+# include <unlocked-io.h>
+# include <verify.h>
+# include <xalloc.h>
 
 
 /*-----------------.
 | GCC extensions.  |
 `-----------------*/
 
-/* Use this to suppress gcc's `...may be used before initialized'
-   warnings.  */
-#ifdef lint
-# define IF_LINT(Code) Code
-#else
-# define IF_LINT(Code) /* empty */
-#endif
+/* Use PACIFY_CC to indicate that Code is unimportant to the logic of Bison
+   but that it is necessary for suppressing compiler warnings.  For example,
+   Code might be a variable initializer that's always overwritten before the
+   variable is used.
 
-#ifndef __attribute__
+   PACIFY_CC is intended to be useful only as a comment as it does not alter
+   Code.  It is tempting to redefine PACIFY_CC so that it will suppress Code
+   when configuring without --enable-gcc-warnings.  However, that would mean
+   that, for maintainers, Bison would compile with potentially less warnings
+   and safer logic than it would for users.  Due to the overhead of M4,
+   suppressing Code is unlikely to offer any significant improvement in
+   Bison's performance anyway.  */
+# define PACIFY_CC(Code) Code
+
+# ifndef __attribute__
 /* This feature is available in gcc versions 2.5 and later.  */
-# if (! defined __GNUC__ || __GNUC__ < 2 \
-      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__)
-#  define __attribute__(Spec) /* empty */
+#  if (! defined __GNUC__ || __GNUC__ < 2 \
+       || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+#   define __attribute__(Spec) /* empty */
+#  endif
 # endif
-#endif
 
 /* The __-protected variants of `format' and `printf' attributes
    are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-# define __format__ format
-# define __printf__ printf
-#endif
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __format__ format
+#  define __printf__ printf
+# endif
 
-#ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
-#endif
+# ifndef ATTRIBUTE_NORETURN
+#  define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+# endif
 
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
+# ifndef ATTRIBUTE_UNUSED
+#  define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# endif
+
 
 /*------.
 | NLS.  |
 `------*/
 
-#include <locale.h>
+# include <locale.h>
 
-#include <gettext.h>
-#define _(Msgid)  gettext (Msgid)
-#define N_(Msgid) (Msgid)
-
-
-/*-------------------------------.
-| Fix broken compilation flags.  |
-`-------------------------------*/
-
-#ifndef LOCALEDIR
-# define LOCALEDIR "/usr/local/share/locale"
-#endif
+# include <gettext.h>
+# define _(Msgid)  gettext (Msgid)
+# define N_(Msgid) (Msgid)
 
 
 /*-----------.
 | Booleans.  |
 `-----------*/
 
-#include <stdbool.h>
+# include <stdbool.h>
+
+
+
+/*-------------.
+| Assertions.  |
+`-------------*/
+
+/* In the past, Bison defined aver to simply invoke abort in the case of
+   a failed assertion.  The rationale was that <assert.h>'s assertions
+   were too heavyweight and could be disabled too easily.  See
+   discussions at
+   <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00080.html>
+   <http://lists.gnu.org/archive/html/bison-patches/2006-09/msg00111.html>.
+
+   However, normal assert output can be helpful during development and
+   in bug reports from users.  Moreover, it's not clear now that
+   <assert.h>'s assertions are significantly heavyweight.  Finally, if
+   users want to experiment with disabling assertions, it's debatable
+   whether it's our responsibility to stop them.  See discussion
+   starting at
+   <http://lists.gnu.org/archive/html/bison-patches/2009-09/msg00013.html>.
+
+   For now, we use assert but we call it aver throughout Bison in case
+   we later wish to try another scheme.
+*/
+# include <assert.h>
+# define aver assert
 
 
 /*-----------.
 | Obstacks.  |
 `-----------*/
 
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free  free
-#include <obstack.h>
+# define obstack_chunk_alloc xmalloc
+# define obstack_chunk_free  free
+# include <obstack.h>
 
-#define obstack_sgrow(Obs, Str) \
+# define obstack_sgrow(Obs, Str)                \
   obstack_grow (Obs, Str, strlen (Str))
 
-#define obstack_fgrow1(Obs, Format, Arg1)	\
-do {						\
-  char buf[4096];				\
-  sprintf (buf, Format, Arg1);			\
-  obstack_grow (Obs, buf, strlen (buf));	\
-} while (0)
+/* Output Str escaped for our postprocessing (i.e., escape M4 special
+   characters).
 
-#define obstack_fgrow2(Obs, Format, Arg1, Arg2)	\
-do {						\
-  char buf[4096];				\
-  sprintf (buf, Format, Arg1, Arg2);		\
-  obstack_grow (Obs, buf, strlen (buf));	\
-} while (0)
+   For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][". */
 
-#define obstack_fgrow3(Obs, Format, Arg1, Arg2, Arg3)	\
-do {							\
-  char buf[4096];					\
-  sprintf (buf, Format, Arg1, Arg2, Arg3);		\
-  obstack_grow (Obs, buf, strlen (buf));		\
-} while (0)
+# define obstack_escape(Obs, Str)                       \
+  do {                                                  \
+    char const *p;                                      \
+    for (p = Str; *p; p++)                              \
+      switch (*p)                                       \
+        {                                               \
+        case '$': obstack_sgrow (Obs, "$]["); break;    \
+        case '@': obstack_sgrow (Obs, "@@" ); break;    \
+        case '[': obstack_sgrow (Obs, "@{" ); break;    \
+        case ']': obstack_sgrow (Obs, "@}" ); break;    \
+        default:  obstack_1grow (Obs, *p   ); break;    \
+        }                                               \
+  } while (0)
 
-#define obstack_fgrow4(Obs, Format, Arg1, Arg2, Arg3, Arg4)	\
-do {								\
-  char buf[4096];						\
-  sprintf (buf, Format, Arg1, Arg2, Arg3, Arg4);		\
-  obstack_grow (Obs, buf, strlen (buf));			\
-} while (0)
 
+/* Output Str both quoted for M4 (i.e., embed in [[...]]), and escaped
+   for our postprocessing (i.e., escape M4 special characters).  If
+   Str is empty (or NULL), output "[]" instead of "[[]]" as it make M4
+   programming easier (m4_ifval can be used).
+
+   For instance "[foo]" -> "[[@{foo@}]]", "$$" -> "[[$][$][]]". */
+
+# define obstack_quote(Obs, Str)                \
+  do {                                          \
+    char const* obstack_quote_p = Str;          \
+    if (obstack_quote_p && obstack_quote_p[0])  \
+      {                                         \
+        obstack_sgrow (Obs, "[[");              \
+        obstack_escape (Obs, obstack_quote_p);  \
+        obstack_sgrow (Obs, "]]");              \
+      }                                         \
+    else                                        \
+      obstack_sgrow (Obs, "[]");                \
+  } while (0)
+
+
+/* Append the ending 0, finish Obs, and return the string.  */
+
+# define obstack_finish0(Obs)                           \
+  (obstack_1grow (Obs, '\0'), (char *) obstack_finish (Obs))
 
 
 /*-----------------------------------------.
 | Extensions to use for the output files.  |
 `-----------------------------------------*/
 
-#ifndef OUTPUT_EXT
-# define OUTPUT_EXT ".output"
-#endif
+# ifndef OUTPUT_EXT
+#  define OUTPUT_EXT ".output"
+# endif
 
-#ifndef TAB_EXT
-# define TAB_EXT ".tab"
-#endif
-
-#ifndef DEFAULT_TMPDIR
-# define DEFAULT_TMPDIR "/tmp"
-#endif
+# ifndef TAB_EXT
+#  define TAB_EXT ".tab"
+# endif
 
 
 
@@ -203,20 +226,15 @@
 | Free a linked list.  |
 `---------------------*/
 
-#define LIST_FREE(Type, List)			\
-do {						\
-  Type *_node, *_next;				\
-  for (_node = List; _node; _node = _next)	\
-    {						\
-      _next = _node->next;			\
-      free (_node);				\
-    }						\
-} while (0)
-
-
-/* Assertions.  <assert.h>'s assertions are too heavyweight, and can
-   be disabled too easily, so implement it separately here.  */
-#define assert(x) ((void) ((x) || (abort (), 0)))
+# define LIST_FREE(Type, List)                  \
+  do {                                          \
+    Type *_node, *_next;                        \
+    for (_node = List; _node; _node = _next)    \
+      {                                         \
+        _next = _node->next;                    \
+        free (_node);                           \
+      }                                         \
+  } while (0)
 
 
 /*---------------------------------------------.
diff --git a/src/tables.c b/src/tables.c
index c938139..eb827b7 100644
--- a/src/tables.c
+++ b/src/tables.c
@@ -1,30 +1,27 @@
 /* Output the generated parsing program for Bison.
 
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
-   2005 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 2000-2006, 2009-2012 Free
+   Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
 
 #include <bitsetv.h>
-#include <quotearg.h>
 
 #include "complain.h"
 #include "conflicts.h"
@@ -32,6 +29,7 @@
 #include "getargs.h"
 #include "gram.h"
 #include "lalr.h"
+#include "muscle-tab.h"
 #include "reader.h"
 #include "symtab.h"
 #include "tables.h"
@@ -127,7 +125,7 @@
 base_number *table;
 base_number *check;
 /* The value used in TABLE to denote explicit syntax errors
-   (%nonassoc), a negative infinite.  First defaults to ACTION_NUMBER_MININUM,
+   (%nonassoc), a negative infinite.  First defaults to ACTION_NUMBER_MINIMUM,
    but in order to keep small tables, renumbered as TABLE_ERROR, which
    is the smallest (non error) value minus 1.  */
 base_number table_ninf = 0;
@@ -198,18 +196,18 @@
 	/* Find all reductions for token J, and record all that do not
 	   match ACTROW[J].  */
 	for (i = 0; i < reds->num; i += 1)
-	  if (bitset_test (reds->look_ahead_tokens[i], j)
+	  if (bitset_test (reds->lookahead_tokens[i], j)
 	      && (actrow[j]
 		  != rule_number_as_item_number (reds->rules[i]->number)))
 	    {
-	      assert (0 < conflict_list_free);
+	      aver (0 < conflict_list_free);
 	      conflict_list[conflict_list_cnt] = reds->rules[i]->number + 1;
 	      conflict_list_cnt += 1;
 	      conflict_list_free -= 1;
 	    }
 
 	/* Leave a 0 at the end.  */
-	assert (0 < conflict_list_free);
+	aver (0 < conflict_list_free);
 	conflict_list[conflict_list_cnt] = 0;
 	conflict_list_cnt += 1;
 	conflict_list_free -= 1;
@@ -219,7 +217,7 @@
 
 /*------------------------------------------------------------------.
 | Decide what to do for each type of token if seen as the           |
-| look-ahead in specified state.  The value returned is used as the |
+| lookahead in specified state.  The value returned is used as the  |
 | default action (yydefact) for the state.  In addition, ACTROW is  |
 | filled with what to do for each kind of token, index by symbol    |
 | number, with zero meaning do the default action.  The value       |
@@ -227,7 +225,7 @@
 | situation is an error.  The parser recognizes this value	    |
 | specially.							    |
 |                                                                   |
-| This is where conflicts are resolved.  The loop over look-ahead   |
+| This is where conflicts are resolved.  The loop over lookahead    |
 | rules considered lower-numbered rules last, and the last rule     |
 | considered that likes a token gets to handle it.                  |
 |                                                                   |
@@ -241,7 +239,7 @@
 action_row (state *s)
 {
   int i;
-  rule *default_rule = NULL;
+  rule *default_reduction = NULL;
   reductions *reds = s->reductions;
   transitions *trans = s->transitions;
   errs *errp = s->errs;
@@ -252,17 +250,17 @@
   for (i = 0; i < ntokens; i++)
     actrow[i] = conflrow[i] = 0;
 
-  if (reds->look_ahead_tokens)
+  if (reds->lookahead_tokens)
     {
       int j;
       bitset_iterator biter;
       /* loop over all the rules available here which require
-	 look-ahead (in reverse order to give precedence to the first
+	 lookahead (in reverse order to give precedence to the first
 	 rule) */
       for (i = reds->num - 1; i >= 0; --i)
 	/* and find each token which the rule finds acceptable
 	   to come next */
-	BITSET_FOR_EACH (biter, reds->look_ahead_tokens[i], j, 0)
+	BITSET_FOR_EACH (biter, reds->lookahead_tokens[i], j, 0)
 	{
 	  /* and record this rule as the rule to use if that
 	     token follows.  */
@@ -305,13 +303,24 @@
       actrow[sym->number] = ACTION_NUMBER_MINIMUM;
     }
 
+  /* Turn off default reductions where requested by the user.  See
+     state_lookahead_tokens_count in lalr.c to understand when states are
+     labeled as consistent.  */
+  {
+    char *default_reductions =
+      muscle_percent_define_get ("lr.default-reductions");
+    if (0 != strcmp (default_reductions, "most") && !s->consistent)
+      nodefault = true;
+    free (default_reductions);
+  }
+
   /* Now find the most common reduction and make it the default action
      for this state.  */
 
   if (reds->num >= 1 && !nodefault)
     {
       if (s->consistent)
-	default_rule = reds->rules[0];
+	default_reduction = reds->rules[0];
       else
 	{
 	  int max = 0;
@@ -328,7 +337,7 @@
 	      if (count > max)
 		{
 		  max = count;
-		  default_rule = r;
+		  default_reduction = r;
 		}
 	    }
 
@@ -342,17 +351,18 @@
 	    {
 	      int j;
 	      for (j = 0; j < ntokens; j++)
-		if (actrow[j] == rule_number_as_item_number (default_rule->number)
+		if (actrow[j]
+                    == rule_number_as_item_number (default_reduction->number)
 		    && ! (nondeterministic_parser && conflrow[j]))
 		  actrow[j] = 0;
 	    }
 	}
     }
 
-  /* If have no default rule, the default is an error.
+  /* If have no default reduction, the default is an error.
      So replace any action which says "error" with "use default".  */
 
-  if (!default_rule)
+  if (!default_reduction)
     for (i = 0; i < ntokens; i++)
       if (actrow[i] == ACTION_NUMBER_MINIMUM)
 	actrow[i] = 0;
@@ -360,7 +370,7 @@
   if (conflicted)
     conflict_row (s);
 
-  return default_rule;
+  return default_reduction;
 }
 
 
@@ -410,7 +420,7 @@
 
 /*------------------------------------------------------------------.
 | Figure out the actions for the specified state, indexed by        |
-| look-ahead token type.                                            |
+| lookahead token type.                                             |
 |                                                                   |
 | The YYDEFACT table is output now.  The detailed info is saved for |
 | putting into YYTABLE later.                                       |
@@ -441,8 +451,8 @@
 
   for (i = 0; i < nstates; ++i)
     {
-      rule *default_rule = action_row (states[i]);
-      yydefact[i] = default_rule ? default_rule->number + 1 : 0;
+      rule *default_reduction = action_row (states[i]);
+      yydefact[i] = default_reduction ? default_reduction->number + 1 : 0;
       save_row (i);
 
       /* Now that the parser was computed, we can find which rules are
@@ -673,14 +683,14 @@
   base_number *to = tos[i];
   unsigned int *conflict_to = conflict_tos[i];
 
-  assert (t);
+  aver (t != 0);
 
   for (j = lowzero - from[0]; ; j++)
     {
       int k;
       bool ok = true;
 
-      assert (j < table_size);
+      aver (j < table_size);
 
       for (k = 0; ok && k < t; k++)
 	{
@@ -713,7 +723,7 @@
 	  if (loc > high)
 	    high = loc;
 
-	  assert (BASE_MINIMUM <= j && j <= BASE_MAXIMUM);
+	  aver (BASE_MINIMUM <= j && j <= BASE_MAXIMUM);
 	  return j;
 	}
     }
diff --git a/src/tables.h b/src/tables.h
index 911917f..8b5c1fa 100644
--- a/src/tables.h
+++ b/src/tables.h
@@ -1,22 +1,21 @@
 /* Prepare the LALR and GLR parser tables.
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+   Copyright (C) 2002, 2004, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison 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 2, or (at your option)
-   any later version.
+   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.
 
-   Bison 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.
+   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 Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef TABLES_H_
 # define TABLES_H_
@@ -47,33 +46,13 @@
 
    YYSTOS[S] = the symbol number of the symbol that leads to state S.
 
-   YYDEFACT[S] = default rule to reduce with in state s, when YYTABLE
-   doesn't specify something else to do.  Zero means the default is an
-   error.
-
-   YYDEFGOTO[I] = default state to go to after a reduction of a rule
-   that generates variable NTOKENS + I, except when YYTABLE specifies
-   something else to do.
-
-   YYPACT[S] = index in YYTABLE of the portion describing state S.
-   The look-ahead token's type is used to index that portion to find
-   out what to do.
-
-   If the value in YYTABLE is positive, we shift the token and go to
-   that state.
-
-   If the value is negative, it is minus a rule number to reduce by.
-
-   If the value is zero, the default action from YYDEFACT[S] is used.
-
-   YYPGOTO[I] = the index in YYTABLE of the portion describing what to
-   do after reducing a rule that derives variable I + NTOKENS.  This
-   portion is indexed by the parser state number, S, as of before the
-   text for this nonterminal was read.  The value from YYTABLE is the
-   state to go to if the corresponding value in YYCHECK is S.
+   YYFINAL = the state number of the termination state.
 
    YYTABLE = a vector filled with portions for different uses, found
-   via YYPACT and YYPGOTO.
+   via YYPACT and YYPGOTO, described below.
+
+   YYLAST ( = high) the number of the last element of YYTABLE, i.e.,
+   sizeof (YYTABLE) - 1.
 
    YYCHECK = a vector indexed in parallel with YYTABLE.  It indicates,
    in a roundabout way, the bounds of the portion you are trying to
@@ -85,10 +64,53 @@
    default (from YYDEFACT or YYDEFGOTO) should be used.  Otherwise,
    YYTABLE[P+I] should be used.
 
-   YYFINAL = the state number of the termination state.
+   YYDEFACT[S] = default reduction number in state s.  Performed when
+   YYTABLE doesn't specify something else to do.  Zero means the default
+   is an error.
 
-   YYLAST ( = high) the number of the last element of YYTABLE, i.e.,
-   sizeof (YYTABLE) - 1.  */
+   YYDEFGOTO[I] = default state to go to after a reduction of a rule
+   that generates variable NTOKENS + I, except when YYTABLE specifies
+   something else to do.
+
+   YYPACT[S] = index in YYTABLE of the portion describing state S.
+   The lookahead token's number, I, is used to index that portion of
+   YYTABLE to find out what action to perform.
+
+   If YYPACT[S] == YYPACT_NINF, if YYPACT[S] + I is outside the bounds
+   of YYTABLE (from 0 to YYLAST), or I is outside the bounds for portion
+   S (that is, YYCHECK[YYPACT[S] + I] != I), then the default action
+   (that is, YYDEFACT[S]) should be used instead of YYTABLE.  Otherwise,
+   the value YYTABLE[YYPACT[S] + I] should be used even if
+   YYPACT[S] < 0.
+
+   If the value in YYTABLE is positive, we shift the token and go to
+   that state.
+
+   If the value is negative, it is minus a rule number to reduce by.
+
+   If the value is YYTABLE_NINF, it's a syntax error.
+
+   YYPGOTO[I] = the index in YYTABLE of the portion describing what to
+   do after reducing a rule that derives variable I + NTOKENS.  This
+   portion is indexed by the parser state number, S, as of before the
+   text for this nonterminal was read.
+
+   If YYPGOTO[I] + S is outside the bounds of YYTABLE (from 0 to YYLAST)
+   or if S is outside the bounds of the portion for I (that is,
+   YYCHECK[YYPGOTO[I] + S] != S), then the default state (that is,
+   YYDEFGOTO[I]) should be used instead of YYTABLE.  Otherwise,
+   YYTABLE[YYPGOTO[I] + S] is the state to go to even if YYPGOTO[I] < 0.
+
+   When the above YYPACT, YYPGOTO, and YYCHECK tests determine that a
+   value from YYTABLE should be used, that value is never zero, so it is
+   useless to check for zero.  When those tests indicate that the value
+   from YYDEFACT or YYDEFGOTO should be used instead, the value from
+   YYTABLE *might* be zero, which, as a consequence of the way in which
+   the tables are constructed, also happens to indicate that YYDEFACT or
+   YYDEFGOTO should be used.  However, the YYTABLE value cannot be
+   trusted when the YYDEFACT or YYDEFGOTO value should be used.  In
+   summary, forget about zero values in YYTABLE.
+*/
 
 extern int nvectors;
 
diff --git a/src/uniqstr.c b/src/uniqstr.c
index 8804a80..62d09ca 100644
--- a/src/uniqstr.c
+++ b/src/uniqstr.c
@@ -1,23 +1,21 @@
 /* Keep a unique copy of strings.
 
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002-2005, 2009-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
@@ -25,6 +23,7 @@
 #include <error.h>
 #include <hash.h>
 #include <quotearg.h>
+#include <stdarg.h>
 
 #include "uniqstr.h"
 
@@ -49,11 +48,27 @@
     {
       /* First insertion in the hash. */
       res = xstrdup (str);
-      hash_insert (uniqstrs_table, res);
+      if (!hash_insert (uniqstrs_table, res))
+        xalloc_die ();
     }
   return res;
 }
 
+uniqstr
+uniqstr_vsprintf (char const *format, ...)
+{
+  va_list args;
+  size_t length;
+  va_start (args, format);
+  length = vsnprintf (NULL, 0, format, args);
+  va_end (args);
+
+  char res[length + 1];
+  va_start (args, format);
+  vsprintf (res, format, args);
+  va_end (args);
+  return uniqstr_new (res);
+}
 
 /*------------------------------.
 | Abort if S is not a uniqstr.  |
diff --git a/src/uniqstr.h b/src/uniqstr.h
index ab482be..677ecc4 100644
--- a/src/uniqstr.h
+++ b/src/uniqstr.h
@@ -1,23 +1,21 @@
 /* Keeping a unique copy of strings.
 
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2008-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   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 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef UNIQSTR_H_
 # define UNIQSTR_H_
@@ -31,8 +29,18 @@
 /* Return the uniqstr for STR.  */
 uniqstr uniqstr_new (char const *str);
 
+/* Return a uniqstr built by vsprintf.  In order to simply concatenate
+   strings, use UNIQSTR_CONCAT, which is a convenient wrapper around
+   this function.  */
+uniqstr uniqstr_vsprintf (char const *format, ...)
+  __attribute__ ((__format__ (__printf__, 1, 2)));
+
 /* Two uniqstr values have the same value iff they are the same.  */
-#define UNIQSTR_EQ(USTR1, USTR2) ((USTR1) == (USTR2))
+#define UNIQSTR_EQ(USTR1, USTR2) (!!((USTR1) == (USTR2)))
+
+/* Compare two uniqstr a la strcmp: negative for <, nul for =, and
+   positive for >.  Undefined order, relies on addresses.  */
+#define UNIQSTR_CMP(USTR1, USTR2) ((USTR1) - (USTR2))
 
 /*--------------------------------------.
 | Initializing, destroying, debugging.  |
@@ -50,4 +58,41 @@
 /* Report them all.  */
 void uniqstrs_print (void);
 
+/*----------------.
+| Concatenation.  |
+`----------------*/
+
+/* Concatenate at most 20 strings and return a uniqstr.  The goal of
+   this macro is to make the caller's code a little more succinct
+   without a trivial uniqstr_vsprintf format string to maintain
+   (for example, "%s%s%s") while still benefitting from gcc's type
+   checking.  Unfortunately, because of the missing format string in the
+   macro invocation, the argument number reported by gcc for a bad
+   argument type is 1 too large.  */
+#define UNIQSTR_CONCAT(...)                                            \
+  uniqstr_vsprintf (UNIQSTR_GEN_FORMAT (__VA_ARGS__,                   \
+                                        "%s", "%s", "%s", "%s", "%s",  \
+                                        "%s", "%s", "%s", "%s", "%s",  \
+                                        "%s", "%s", "%s", "%s", "%s",  \
+                                        "%s", "%s", "%s", "%s", "%s"), \
+                    __VA_ARGS__)
+
+#define UNIQSTR_GEN_FORMAT(F1,  F2,  F3,  F4,  F5,  \
+                           F6,  F7,  F8,  F9,  F10, \
+                           F11, F12, F13, F14, F15, \
+                           F16, F17, F18, F19, F20, \
+                           ...)                     \
+  UNIQSTR_GEN_FORMAT_ (__VA_ARGS__,                 \
+                       "", "", "", "", "",          \
+                       "", "", "", "", "",          \
+                       "", "", "", "", "",          \
+                       "", "", "", "", "")
+
+#define UNIQSTR_GEN_FORMAT_(F1,  F2,  F3,  F4,  F5,       \
+                            F6,  F7,  F8,  F9,  F10,      \
+                            F11, F12, F13, F14, F15,      \
+                            F16, F17, F18, F19, F20, ...) \
+  F1  F2  F3  F4  F5  F6  F7  F8  F9  F10                 \
+  F11 F12 F13 F14 F15 F16 F17 F18 F19 F20
+
 #endif /* ! defined UNIQSTR_H_ */
diff --git a/src/vcg.c b/src/vcg.c
deleted file mode 100644
index 25fbb64..0000000
--- a/src/vcg.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/* VCG description handler for Bison.
-
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
-   Foundation, Inc.
-
-   This file is part of Bison, the GNU Compiler Compiler.
-
-   Bison 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 2, or (at your option)
-   any later version.
-
-   Bison 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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
-#include <config.h>
-#include "system.h"
-
-#include <quotearg.h>
-
-#include "vcg.h"
-#include "vcg_defaults.h"
-
-/* Return an unambiguous printable representated, for NAME, suitable
-   for C strings.  Use slot 2 since the user may use slots 0 and 1.
-   */
-
-static char const *
-quote (char const *name)
-{
-  return quotearg_n_style (2, c_quoting_style, name);
-}
-
-
-/* Initialize a graph with the default values. */
-void
-new_graph (graph *g)
-{
-  g->title = G_TITLE;
-  g->label = G_LABEL;
-
-  g->infos[0] = G_INFOS1;
-  g->infos[1] = G_INFOS2;
-  g->infos[2] = G_INFOS3;
-
-  g->color = G_COLOR;
-  g->textcolor = G_TEXTCOLOR;
-  g->bordercolor = G_BORDERCOLOR;
-
-  g->width = G_WIDTH;
-  g->height = G_HEIGHT;
-  g->borderwidth = G_BORDERWIDTH;
-  g->x = G_X;
-  g->y = G_Y;
-  g->folding = G_FOLDING;
-  g->shrink = G_SHRINK;
-  g->stretch = G_STRETCH;
-
-  g->textmode = G_TEXTMODE;
-  g->shape = G_SHAPE;
-
-  g->vertical_order = G_VERTICAL_ORDER;
-  g->horizontal_order = G_HORIZONTAL_ORDER;
-
-  g->xmax = G_XMAX; /* Not output. */
-  g->ymax = G_YMAX; /* Not output. */
-
-  g->xbase = G_XBASE;
-  g->ybase = G_YBASE;
-
-  g->xspace = G_XSPACE;
-  g->yspace = G_YSPACE;
-  g->xlspace = G_XLSPACE; /* Not output. */
-
-  g->xraster = G_XRASTER;
-  g->yraster = G_YRASTER;
-  g->xlraster = G_XLRASTER;
-
-  g->hidden = G_HIDDEN; /* No default value. */
-
-  g->classname = G_CLASSNAME; /* No class name association. */
-
-  g->layout_downfactor = G_LAYOUT_DOWNFACTOR;
-  g->layout_upfactor = G_LAYOUT_UPFACTOR;
-  g->layout_nearfactor = G_LAYOUT_NEARFACTOR;
-  g->layout_splinefactor = G_LAYOUT_SPLINEFACTOR;
-
-  g->late_edge_labels = G_LATE_EDGE_LABELS;
-  g->display_edge_labels = G_DISPLAY_EDGE_LABELS;
-  g->dirty_edge_labels = G_DIRTY_EDGE_LABELS;
-  g->finetuning = G_FINETUNING;
-  g->ignore_singles = G_IGNORE_SINGLES;
-  g->priority_phase = G_PRIORITY_PHASE;
-  g->manhattan_edges = G_MANHATTAN_EDGES;
-  g->smanhattan_edges = G_SMANHATTAN_EDGES;
-  g->near_edges = G_NEAR_EDGES;
-
-  g->orientation = G_ORIENTATION;
-  g->node_alignment = G_NODE_ALIGNMENT;
-  g->port_sharing = G_PORT_SHARING;
-  g->arrow_mode = G_ARROW_MODE;
-  g->treefactor = G_TREEFACTOR;
-  g->spreadlevel = G_SPREADLEVEL;
-  g->crossing_weight = G_CROSSING_WEIGHT;
-  g->crossing_phase2 = G_CROSSING_PHASE2;
-  g->crossing_optimization = G_CROSSING_OPTIMIZATION;
-  g->view = G_VIEW;
-
-  g->edges = G_EDGES;
-  g->nodes = G_NODES;
-  g->splines = G_SPLINES;
-
-  g->bmax = G_BMAX;
-  g->cmin = G_CMIN;
-  g->cmax = G_CMAX;
-  g->pmin = G_PMIN;
-  g->pmax = G_PMAX;
-  g->rmin = G_RMIN;
-  g->rmax = G_RMAX;
-  g->smax = G_SMAX;
-
-  g->node_list = G_NODE_LIST;
-  g->edge_list = G_EDGE_LIST;
-
-  new_edge (&g->edge);
-  new_node (&g->node);
-}
-
-/* Initialize a node with the default values. */
-void
-new_node (node *n)
-{
-  n->title = N_TITLE;
-  n->label = N_LABEL;
-
-  n->locx = N_LOCX; /* Default unspcified. */
-  n->locy = N_LOCY; /* Default unspcified. */
-
-  n->vertical_order = N_VERTICAL_ORDER;	/* Default unspcified. */
-  n->horizontal_order = N_HORIZONTAL_ORDER;	/* Default unspcified. */
-
-  n->width = N_WIDTH; /* We assume that we can't define it now. */
-  n->height = N_HEIGHT; /* Also. */
-
-  n->shrink = N_SHRINK;
-  n->stretch = N_STRETCH;
-
-  n->folding = N_FOLDING; /* No explicit default value. */
-
-  n->shape = N_SHAPE;
-  n->textmode = N_TEXTMODE;
-  n->borderwidth = N_BORDERWIDTH;
-
-  n->color = N_COLOR;
-  n->textcolor = N_TEXTCOLOR;
-  n->bordercolor = N_BORDERCOLOR;
-
-  n->infos[0] = N_INFOS1;
-  n->infos[1] = N_INFOS2;
-  n->infos[2] = N_INFOS3;
-
-  n->next = N_NEXT;
-}
-
-/* Initialize an edge with the default values. */
-void
-new_edge (edge *e)
-{
-  e->type = E_EDGE_TYPE;
-
-  e->sourcename = E_SOURCENAME;
-  e->targetname = E_TARGETNAME;
-  e->label = E_LABEL;
-
-  e->linestyle = E_LINESTYLE;
-  e->thickness = E_THICKNESS;
-
-  e->class = E_CLASS;
-
-  e->color = E_COLOR;
-  e->textcolor = E_TEXTCOLOR;
-  e->arrowcolor = E_ARROWCOLOR;
-  e->backarrowcolor = E_BACKARROWCOLOR;
-
-  e->arrowsize = E_ARROWSIZE;
-  e->backarrowsize = E_BACKARROWSIZE;
-  e->arrowstyle = E_ARROWSTYLE;
-
-  e->backarrowstyle = E_BACKARROWSTYLE;
-
-  e->priority = E_PRIORITY;
-
-  e->anchor = E_ANCHOR;
-
-  e->horizontal_order = E_HORIZONTAL_ORDER;
-
-  e->next = E_NEXT;
-}
-
-/*----------------------------------------------.
-| Get functions.	                        |
-| Return string corresponding to an enum value. |
-`----------------------------------------------*/
-
-static const char *
-get_color_str (enum color color)
-{
-  switch (color)
-    {
-    default:		abort ();
-    case white:		return "white";
-    case blue:		return "blue";
-    case red:		return "red";
-    case green:		return "green";
-    case yellow:	return "yellow";
-    case magenta:	return "magenta";
-    case cyan:		return "cyan";
-    case darkgrey:	return "darkgrey";
-    case darkblue:	return "darkblue";
-    case darkred:	return "darkred";
-    case darkgreen:	return "darkgreen";
-    case darkyellow:	return "darkyellow";
-    case darkmagenta:	return "darkmagenta";
-    case darkcyan:	return "darkcyan";
-    case gold:		return "gold";
-    case lightgrey:	return "lightgrey";
-    case lightblue:	return "lightblue";
-    case lightred:	return "lightred";
-    case lightgreen:	return "lightgreen";
-    case lightyellow:	return "lightyellow";
-    case lightmagenta:	return "lightmagenta";
-    case lightcyan:	return "lightcyan";
-    case lilac:		return "lilac";
-    case turquoise:	return "turquoise";
-    case aquamarine:	return "aquamarine";
-    case khaki:		return "khaki";
-    case purple:	return "purple";
-    case yellowgreen:	return "yellowgreen";
-    case pink:		return "pink";
-    case orange:	return "orange";
-    case orchid:	return "orchid";
-    case black:		return "black";
-    }
-}
-
-static const char *
-get_textmode_str (enum textmode textmode)
-{
-  switch (textmode)
-    {
-    default:		abort ();
-    case centered:	return "center";
-    case left_justify:	return "left_justify";
-    case right_justify:	return "right_justify";
-    }
-}
-
-static const char *
-get_shape_str (enum shape shape)
-{
-  switch (shape)
-    {
-    default:		abort ();
-    case box:		return "box";
-    case rhomb:		return "rhomb";
-    case ellipse:	return "ellipse";
-    case triangle:	return "triangle";
-    }
-}
-
-static const char *
-get_decision_str (enum decision decision)
-{
-  switch (decision)
-    {
-    default:	abort ();
-    case no:	return "no";
-    case yes:	return "yes";
-    }
-}
-
-static const char *
-get_orientation_str (enum orientation orientation)
-{
-  switch (orientation)
-    {
-    default:		abort ();
-    case top_to_bottom:	return "top_to_bottom";
-    case bottom_to_top: return "bottom_to_top";
-    case left_to_right: return "left_to_right";
-    case right_to_left: return "right_to_left";
-    }
-}
-
-static const char *
-get_node_alignment_str (enum alignment alignment)
-{
-  switch (alignment)
-    {
-    default:		abort ();
-    case center:	return "center";
-    case top:		return "top";
-    case bottom:	return "bottom";
-    }
-}
-
-static const char *
-get_arrow_mode_str (enum arrow_mode arrow_mode)
-{
-  switch (arrow_mode)
-    {
-    default:		abort ();
-    case fixed:		return "fixed";
-    case free_a:	return "free";
-    }
-}
-
-static const char *
-get_crossing_type_str (enum crossing_type crossing_type)
-{
-  switch (crossing_type)
-    {
-    default:		abort ();
-    case bary:		return "bary";
-    case median:	return "median";
-    case barymedian:	return "barymedian";
-    case medianbary:	return "medianbary";
-    }
-}
-
-static const char *
-get_view_str (enum view view)
-{
-  /* There is no way with vcg 1.30 to specify a normal view explicitly,
-     so it is an error here if view == normal_view.  */
-  switch (view)
-    {
-    default:		abort ();
-    case cfish:		return "cfish";
-    case pfish:		return "pfish";
-    case fcfish:	return "fcfish";
-    case fpfish:	return "fpfish";
-    }
-}
-
-static const char *
-get_linestyle_str (enum linestyle linestyle)
-{
-  switch (linestyle)
-    {
-    default:		abort ();
-    case continuous:	return "continuous";
-    case dashed:	return "dashed";
-    case dotted:	return "dotted";
-    case invisible:	return "invisible";
-    }
-}
-
-static const char *
-get_arrowstyle_str (enum arrowstyle arrowstyle)
-{
-  switch (arrowstyle)
-    {
-    default:	abort ();
-    case solid:	return "solid";
-    case line:	return "line";
-    case none:	return "none";
-    }
-}
-
-/*------------------------------.
-| Add functions.	        |
-| Edge and nodes into a graph.  |
-`------------------------------*/
-
-void
-add_node (graph *g, node *n)
-{
-  n->next = g->node_list;
-  g->node_list = n;
-}
-
-void
-add_edge (graph *g, edge *e)
-{
-  e->next = g->edge_list;
-  g->edge_list = e;
-}
-
-void
-add_classname (graph *g, int val, const char *name)
-{
-  struct classname *classname = xmalloc (sizeof *classname);
-  classname->no = val;
-  classname->name = name;
-  classname->next = g->classname;
-  g->classname = classname;
-}
-
-void
-add_infoname (graph *g, int integer, const char *str)
-{
-  struct infoname *infoname = xmalloc (sizeof *infoname);
-  infoname->integer = integer;
-  infoname->chars = str;
-  infoname->next = g->infoname;
-  g->infoname = infoname;
-}
-
-/* Build a colorentry struct and add it to the list.  */
-void
-add_colorentry (graph *g, int color_idx, int red_cp,
-		int green_cp, int blue_cp)
-{
-  struct colorentry *ce = xmalloc (sizeof *ce);
-  ce->color_index = color_idx;
-  ce->red_cp = red_cp;
-  ce->green_cp = green_cp;
-  ce->blue_cp = blue_cp;
-  ce->next = g->colorentry;
-  g->colorentry = ce;
-}
-
-/*-------------------------------------.
-| Open and close functions (formatted) |
-`-------------------------------------*/
-
-void
-open_edge (edge *e, FILE *fout)
-{
-  switch (e->type)
-    {
-    case normal_edge:
-      fputs ("\tedge: {\n", fout);
-      break;
-    case back_edge:
-      fputs ("\tbackedge: {\n", fout);
-      break;
-    case near_edge:
-      fputs ("\tnearedge: {\n", fout);
-      break;
-    case bent_near_edge:
-      fputs ("\tbentnearedge: {\n", fout);
-      break;
-    default:
-      fputs ("\tedge: {\n", fout);
-    }
-}
-
-void
-close_edge (FILE *fout)
-{
-  fputs ("\t}\n", fout);
-}
-
-void
-open_node (FILE *fout)
-{
-  fputs ("\tnode: {\n", fout);
-}
-
-void
-close_node (FILE *fout)
-{
-  fputs ("\t}\n", fout);
-}
-
-void
-open_graph (FILE *fout)
-{
-  fputs ("graph: {\n", fout);
-}
-
-void
-close_graph (graph *g, FILE *fout)
-{
-  fputc ('\n', fout);
-
-  /* FIXME: Unallocate nodes and edges if required.  */
-  {
-    node *n;
-
-    for (n = g->node_list; n; n = n->next)
-      {
-	open_node (fout);
-	output_node (n, fout);
-	close_node (fout);
-      }
-  }
-
-  fputc ('\n', fout);
-
-  {
-    edge *e;
-
-    for (e = g->edge_list; e; e = e->next)
-      {
-	open_edge (e, fout);
-	output_edge (e, fout);
-	close_edge (fout);
-      }
-  }
-
-  fputs ("}\n", fout);
-}
-
-/*-------------------------------------------.
-| Output functions (formatted) in file FOUT  |
-`-------------------------------------------*/
-
-void
-output_node (node *n, FILE *fout)
-{
-  if (n->title != N_TITLE)
-    fprintf (fout, "\t\ttitle:\t%s\n", quote (n->title));
-  if (n->label != N_LABEL)
-    fprintf (fout, "\t\tlabel:\t%s\n", quote (n->label));
-
-  if ((n->locx != N_LOCX) && (n->locy != N_LOCY))
-    fprintf (fout, "\t\tloc { x: %d  y: %d }\t\n", n->locx, n->locy);
-
-  if (n->vertical_order != N_VERTICAL_ORDER)
-    fprintf (fout, "\t\tvertical_order:\t%d\n", n->vertical_order);
-  if (n->horizontal_order != N_HORIZONTAL_ORDER)
-    fprintf (fout, "\t\thorizontal_order:\t%d\n", n->horizontal_order);
-
-  if (n->width != N_WIDTH)
-    fprintf (fout, "\t\twidth:\t%d\n", n->width);
-  if (n->height != N_HEIGHT)
-    fprintf (fout, "\t\theight:\t%d\n", n->height);
-
-  if (n->shrink != N_SHRINK)
-    fprintf (fout, "\t\tshrink:\t%d\n", n->shrink);
-  if (n->stretch != N_STRETCH)
-    fprintf (fout, "\t\tstretch:\t%d\n", n->stretch);
-
-  if (n->folding != N_FOLDING)
-    fprintf (fout, "\t\tfolding:\t%d\n", n->folding);
-
-  if (n->textmode != N_TEXTMODE)
-    fprintf (fout, "\t\ttextmode:\t%s\n",
-	     get_textmode_str (n->textmode));
-
-  if (n->shape != N_SHAPE)
-    fprintf (fout, "\t\tshape:\t%s\n", get_shape_str (n->shape));
-
-  if (n->borderwidth != N_BORDERWIDTH)
-    fprintf (fout, "\t\tborderwidth:\t%d\n", n->borderwidth);
-
-  if (n->color != N_COLOR)
-    fprintf (fout, "\t\tcolor:\t%s\n", get_color_str (n->color));
-  if (n->textcolor != N_TEXTCOLOR)
-    fprintf (fout, "\t\ttextcolor:\t%s\n",
-	     get_color_str (n->textcolor));
-  if (n->bordercolor != N_BORDERCOLOR)
-    fprintf (fout, "\t\tbordercolor:\t%s\n",
-	     get_color_str (n->bordercolor));
-
-  {
-    int i;
-    for (i = 0; i < 3; ++i)
-      if (n->infos[i])
-	fprintf (fout, "\t\tinfo%d:\t%s\n",
-		 i, quote (n->infos[i]));
-  }
-}
-
-void
-output_edge (edge *e, FILE *fout)
-{
-  /* FIXME: SOURCENAME and TARGETNAME are mandatory
-     so it has to be fatal not to give these informations.  */
-  if (e->sourcename != E_SOURCENAME)
-    fprintf (fout, "\t\tsourcename:\t%s\n", quote (e->sourcename));
-  if (e->targetname != E_TARGETNAME)
-    fprintf (fout, "\t\ttargetname:\t%s\n", quote (e->targetname));
-
-  if (e->label != E_LABEL)
-    fprintf (fout, "\t\tlabel:\t%s\n", quote (e->label));
-
-  if (e->linestyle != E_LINESTYLE)
-    fprintf (fout, "\t\tlinestyle:\t%s\n", get_linestyle_str (e->linestyle));
-
-  if (e->thickness != E_THICKNESS)
-    fprintf (fout, "\t\tthickness:\t%d\n", e->thickness);
-  if (e->class != E_CLASS)
-    fprintf (fout, "\t\tclass:\t%d\n", e->class);
-
-  if (e->color != E_COLOR)
-    fprintf (fout, "\t\tcolor:\t%s\n", get_color_str (e->color));
-  if (e->color != E_TEXTCOLOR)
-    fprintf (fout, "\t\ttextcolor:\t%s\n",
-	     get_color_str (e->textcolor));
-  if (e->arrowcolor != E_ARROWCOLOR)
-    fprintf (fout, "\t\tarrowcolor:\t%s\n",
-	     get_color_str (e->arrowcolor));
-  if (e->backarrowcolor != E_BACKARROWCOLOR)
-    fprintf (fout, "\t\tbackarrowcolor:\t%s\n",
-	     get_color_str (e->backarrowcolor));
-
-  if (e->arrowsize != E_ARROWSIZE)
-    fprintf (fout, "\t\tarrowsize:\t%d\n", e->arrowsize);
-  if (e->backarrowsize != E_BACKARROWSIZE)
-    fprintf (fout, "\t\tbackarrowsize:\t%d\n", e->backarrowsize);
-
-  if (e->arrowstyle != E_ARROWSTYLE)
-    fprintf (fout, "\t\tarrowstyle:\t%s\n",
-	     get_arrowstyle_str (e->arrowstyle));
-  if (e->backarrowstyle != E_BACKARROWSTYLE)
-    fprintf (fout, "\t\tbackarrowstyle:\t%s\n",
-	     get_arrowstyle_str (e->backarrowstyle));
-
-  if (e->priority != E_PRIORITY)
-    fprintf (fout, "\t\tpriority:\t%d\n", e->priority);
-  if (e->anchor != E_ANCHOR)
-    fprintf (fout, "\t\tanchor:\t%d\n", e->anchor);
-  if (e->horizontal_order != E_HORIZONTAL_ORDER)
-    fprintf (fout, "\t\thorizontal_order:\t%d\n", e->horizontal_order);
-}
-
-void
-output_graph (graph *g, FILE *fout)
-{
-  if (g->title)
-    fprintf (fout, "\ttitle:\t%s\n", quote (g->title));
-  if (g->label)
-    fprintf (fout, "\tlabel:\t%s\n", quote (g->label));
-
-  {
-    int i;
-    for (i = 0; i < 3; ++i)
-      if (g->infos[i])
-	fprintf (fout, "\tinfo%d:\t%s\n", i, quote (g->infos[i]));
-  }
-
-  if (g->color != G_COLOR)
-    fprintf (fout, "\tcolor:\t%s\n", get_color_str (g->color));
-  if (g->textcolor != G_TEXTCOLOR)
-    fprintf (fout, "\ttextcolor:\t%s\n", get_color_str (g->textcolor));
-  if (g->bordercolor != G_BORDERCOLOR)
-    fprintf (fout, "\tbordercolor:\t%s\n",
-	     get_color_str (g->bordercolor));
-
-  if (g->width != G_WIDTH)
-    fprintf (fout, "\twidth:\t%d\n", g->width);
-  if (g->height != G_HEIGHT)
-    fprintf (fout, "\theight:\t%d\n", g->height);
-  if (g->borderwidth != G_BORDERWIDTH)
-    fprintf (fout, "\tborderwidth:\t%d\n", g->borderwidth);
-
-  if (g->x != G_X)
-    fprintf (fout, "\tx:\t%d\n", g->x);
-  if (g->y != G_Y)
-    fprintf (fout, "\ty:\t%d\n", g->y);
-
-  if (g->folding != G_FOLDING)
-    fprintf (fout, "\tfolding:\t%d\n", g->folding);
-
-  if (g->shrink != G_SHRINK)
-    fprintf (fout, "\tshrink:\t%d\n", g->shrink);
-  if (g->stretch != G_STRETCH)
-    fprintf (fout, "\tstretch:\t%d\n", g->stretch);
-
-  if (g->textmode != G_TEXTMODE)
-    fprintf (fout, "\ttextmode:\t%s\n",
-	     get_textmode_str (g->textmode));
-
-  if (g->shape != G_SHAPE)
-    fprintf (fout, "\tshape:\t%s\n", get_shape_str (g->shape));
-
-  if (g->vertical_order != G_VERTICAL_ORDER)
-    fprintf (fout, "\tvertical_order:\t%d\n", g->vertical_order);
-  if (g->horizontal_order != G_HORIZONTAL_ORDER)
-    fprintf (fout, "\thorizontal_order:\t%d\n", g->horizontal_order);
-
-  if (g->xmax != G_XMAX)
-    fprintf (fout, "\txmax:\t%d\n", g->xmax);
-  if (g->ymax != G_YMAX)
-    fprintf (fout, "\tymax:\t%d\n", g->ymax);
-
-  if (g->xbase != G_XBASE)
-    fprintf (fout, "\txbase:\t%d\n", g->xbase);
-  if (g->ybase != G_YBASE)
-    fprintf (fout, "\tybase:\t%d\n", g->ybase);
-
-  if (g->xspace != G_XSPACE)
-    fprintf (fout, "\txspace:\t%d\n", g->xspace);
-  if (g->yspace != G_YSPACE)
-    fprintf (fout, "\tyspace:\t%d\n", g->yspace);
-  if (g->xlspace != G_XLSPACE)
-    fprintf (fout, "\txlspace:\t%d\n", g->xlspace);
-
-  if (g->xraster != G_XRASTER)
-    fprintf (fout, "\txraster:\t%d\n", g->xraster);
-  if (g->yraster != G_YRASTER)
-    fprintf (fout, "\tyraster:\t%d\n", g->yraster);
-  if (g->xlraster != G_XLRASTER)
-    fprintf (fout, "\txlraster:\t%d\n", g->xlraster);
-
-  if (g->hidden != G_HIDDEN)
-    fprintf (fout, "\thidden:\t%d\n", g->hidden);
-
-  /* FIXME: Unallocate struct list if required.
-     Maybe with a little function.  */
-  if (g->classname != G_CLASSNAME)
-    {
-      struct classname *ite;
-
-      for (ite = g->classname; ite; ite = ite->next)
-	fprintf (fout, "\tclassname %d :\t%s\n", ite->no, ite->name);
-    }
-
-  if (g->infoname != G_INFONAME)
-    {
-      struct infoname *ite;
-
-      for (ite = g->infoname; ite; ite = ite->next)
-	fprintf (fout, "\tinfoname %d :\t%s\n", ite->integer, ite->chars);
-    }
-
-  if (g->colorentry != G_COLORENTRY)
-    {
-      struct colorentry *ite;
-
-      for (ite = g->colorentry; ite; ite = ite->next)
-	{
-	  fprintf (fout, "\tcolorentry %d :\t%d %d %d\n",
-		   ite->color_index,
-		   ite->red_cp,
-		   ite->green_cp,
-		   ite->blue_cp);
-	}
-    }
-
-  if (g->layout_downfactor != G_LAYOUT_DOWNFACTOR)
-    fprintf (fout, "\tlayout_downfactor:\t%d\n", g->layout_downfactor);
-  if (g->layout_upfactor != G_LAYOUT_UPFACTOR)
-    fprintf (fout, "\tlayout_upfactor:\t%d\n", g->layout_upfactor);
-  if (g->layout_nearfactor != G_LAYOUT_NEARFACTOR)
-    fprintf (fout, "\tlayout_nearfactor:\t%d\n", g->layout_nearfactor);
-  if (g->layout_splinefactor != G_LAYOUT_SPLINEFACTOR)
-    fprintf (fout, "\tlayout_splinefactor:\t%d\n",
-	     g->layout_splinefactor);
-
-  if (g->late_edge_labels != G_LATE_EDGE_LABELS)
-    fprintf (fout, "\tlate_edge_labels:\t%s\n",
-	     get_decision_str (g->late_edge_labels));
-  if (g->display_edge_labels != G_DISPLAY_EDGE_LABELS)
-    fprintf (fout, "\tdisplay_edge_labels:\t%s\n",
-	     get_decision_str (g->display_edge_labels));
-  if (g->dirty_edge_labels != G_DIRTY_EDGE_LABELS)
-    fprintf (fout, "\tdirty_edge_labels:\t%s\n",
-	     get_decision_str (g->dirty_edge_labels));
-  if (g->finetuning != G_FINETUNING)
-    fprintf (fout, "\tfinetuning:\t%s\n",
-	     get_decision_str (g->finetuning));
-  if (g->ignore_singles != G_IGNORE_SINGLES)
-    fprintf (fout, "\tignore_singles:\t%s\n",
-	     get_decision_str (g->ignore_singles));
-  if (g->priority_phase != G_PRIORITY_PHASE)
-    fprintf (fout, "\tpriority_phase:\t%s\n",
-	     get_decision_str (g->priority_phase));
-  if (g->manhattan_edges != G_MANHATTAN_EDGES)
-    fprintf (fout,
-	     "\tmanhattan_edges:\t%s\n",
-	     get_decision_str (g->manhattan_edges));
-  if (g->smanhattan_edges != G_SMANHATTAN_EDGES)
-    fprintf (fout,
-	     "\tsmanhattan_edges:\t%s\n",
-	     get_decision_str (g->smanhattan_edges));
-  if (g->near_edges != G_NEAR_EDGES)
-    fprintf (fout, "\tnear_edges:\t%s\n",
-	     get_decision_str (g->near_edges));
-
-  if (g->orientation != G_ORIENTATION)
-    fprintf (fout, "\torientation:\t%s\n",
-	     get_orientation_str (g->orientation));
-
-  if (g->node_alignment != G_NODE_ALIGNMENT)
-    fprintf (fout, "\tnode_alignment:\t%s\n",
-	     get_node_alignment_str (g->node_alignment));
-
-  if (g->port_sharing != G_PORT_SHARING)
-    fprintf (fout, "\tport_sharing:\t%s\n",
-	     get_decision_str (g->port_sharing));
-
-  if (g->arrow_mode != G_ARROW_MODE)
-    fprintf (fout, "\tarrow_mode:\t%s\n",
-	     get_arrow_mode_str (g->arrow_mode));
-
-  if (g->treefactor != G_TREEFACTOR)
-    fprintf (fout, "\ttreefactor:\t%f\n", g->treefactor);
-  if (g->spreadlevel != G_SPREADLEVEL)
-    fprintf (fout, "\tspreadlevel:\t%d\n", g->spreadlevel);
-
-  if (g->crossing_weight != G_CROSSING_WEIGHT)
-    fprintf (fout, "\tcrossing_weight:\t%s\n",
-	     get_crossing_type_str (g->crossing_weight));
-  if (g->crossing_phase2 != G_CROSSING_PHASE2)
-    fprintf (fout, "\tcrossing_phase2:\t%s\n",
-	     get_decision_str (g->crossing_phase2));
-  if (g->crossing_optimization != G_CROSSING_OPTIMIZATION)
-    fprintf (fout, "\tcrossing_optimization:\t%s\n",
-	     get_decision_str (g->crossing_optimization));
-
-  if (g->view != normal_view)
-    fprintf (fout, "\tview:\t%s\n", get_view_str (g->view));
-
-  if (g->edges != G_EDGES)
-    fprintf (fout, "\tedges:\t%s\n", get_decision_str (g->edges));
-
-  if (g->nodes != G_NODES)
-    fprintf (fout,"\tnodes:\t%s\n", get_decision_str (g->nodes));
-
-  if (g->splines != G_SPLINES)
-    fprintf (fout, "\tsplines:\t%s\n", get_decision_str (g->splines));
-
-  if (g->bmax != G_BMAX)
-    fprintf (fout, "\tbmax:\t%d\n", g->bmax);
-  if (g->cmin != G_CMIN)
-    fprintf (fout, "\tcmin:\t%d\n", g->cmin);
-  if (g->cmax != G_CMAX)
-    fprintf (fout, "\tcmax:\t%d\n", g->cmax);
-  if (g->pmin != G_PMIN)
-    fprintf (fout, "\tpmin:\t%d\n", g->pmin);
-  if (g->pmax != G_PMAX)
-    fprintf (fout, "\tpmax:\t%d\n", g->pmax);
-  if (g->rmin != G_RMIN)
-    fprintf (fout, "\trmin:\t%d\n", g->rmin);
-  if (g->rmax != G_RMAX)
-    fprintf (fout, "\trmax:\t%d\n", g->rmax);
-  if (g->smax != G_SMAX)
-    fprintf (fout, "\tsmax:\t%d\n", g->smax);
-}
diff --git a/src/vcg.h b/src/vcg.h
deleted file mode 100644
index ed35603..0000000
--- a/src/vcg.h
+++ /dev/null
@@ -1,963 +0,0 @@
-/* VCG description handler for Bison.
-
-   Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
-
-   This file is part of Bison, the GNU Compiler Compiler.
-
-   Bison 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 2, or (at your option)
-   any later version.
-
-   Bison 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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
-#ifndef VCG_H_
-# define VCG_H_
-
-/* VCG color map. The 32 prime predefined colors. */
-enum color
-{
-  white		= 0,
-  blue,
-  red,
-  green		= 3,
-  yellow,
-  magenta,
-  cyan		= 6,
-  darkgrey,
-  darkblue,
-  darkred	= 9,
-  darkgreen,
-  darkyellow,
-  darkmagenta	= 12,
-  darkcyan,
-  gold,
-  lightgrey	= 15,
-  lightblue,
-  lightred,
-  lightgreen	= 18,
-  lightyellow,
-  lightmagenta,
-  lightcyan	= 21,
-  lilac,
-  turquoise,
-  aquamarine	= 24,
-  khaki,
-  purple,
-  yellowgreen	= 27,
-  pink,
-  orange,
-  orchid,
-  black		= 31
-};
-
-/* VCG textmode. Specify the adjustement of the text within the border of a summary node. */
-enum textmode
-{
-  centered,
-  left_justify,
-  right_justify
-};
-
-/* VCG shapes. Used for nodes shapes. */
-enum shape
-{
-  box,
-  rhomb,
-  ellipse,
-  triangle
-};
-
-/* Structure for colorentries.  */
-struct colorentry
-{
-  int color_index;
-  int red_cp;
-  int green_cp;
-  int blue_cp;
-  struct colorentry *next;
-};
-
-/* Structure to construct lists of classnames. */
-struct classname
-{
-  int no; /* Class number */
-  const char *name; /* Name associated to the class no. */
-  struct classname *next; /* next name class association. */
-};
-
-/* Structure is in infoname.  */
-struct infoname
-{
-  int integer;
-  char const *chars;
-  struct infoname *next;
-};
-
-/* VCG decision yes/no. */
-enum decision
-{
-  yes,
-  no
-};
-
-/* VCG graph orientation. */
-enum orientation
-{
-  top_to_bottom,
-  bottom_to_top,
-  left_to_right,
-  right_to_left
-};
-
-/* VCG alignment for node alignement. */
-enum alignment
-{
-  center,
-  top,
-  bottom
-};
-
-/* VCG arrow mode. */
-enum arrow_mode
-{
-  fixed,
-  free_a
-};
-
-/* VCG crossing weight type. */
-enum crossing_type
-{
-  bary,
-  median,
-  barymedian,
-  medianbary
-};
-
-/* VCG views. */
-enum view
-{
-  normal_view,
-  cfish,
-  pfish,
-  fcfish,
-  fpfish
-};
-
-/*------------------------------------------------------.
-| Node attributs list. structure that describes a node. |
-`------------------------------------------------------*/
-
-struct node
-{
-  /* Title the unique string identifying the node. This attribute is
-     mandatory. */
-  const char *title;
-
-  /* Label the text displayed inside the node. If no label is specified
-     then the title of the node will be used. Note that this text may
-     contain control characters like NEWLINE that influences the size of
-     the node. */
-  const char *label;
-
-  /* loc is the location as x, y position relatively to the system of
-     coordinates of the graph. Locations are specified in the form
-     loc: - x: xpos y: ypos "". The locations of nodes are only valid,
-     if the whole graph is fully specified with locations and no part is
-     folded. The layout algorithm of the tool calculates appropriate x, y
-     positions, if at least one node that must be drawn (i.e., is not
-     hidden by folding or edge classes) does not have fixed specified
-     locations.
-     Default is none. */
-  int locx;
-  int locy;
-
-  /* vertical order is the level position (rank) of the node. We can also
-     specify level: int. Level specifications are only valid, if the
-     layout is calculated, i.e. if at least one node does not have a
-     fixed location specification. The layout algorithm partitioned all
-     nodes into levels 0...maxlevel. Nodes at the level 0 are on the
-     upper corner. The algorithm is able to calculate appropriate levels
-     for the nodes automatically, if no fixed levels are given.
-     Specifications of levels are additional constraints, that may be
-     ignored, if they are in conflict with near edge specifications.
-     Default values are unspecified. */
-  int vertical_order;
-
-  /* horizontal order is the horizontal position of the node within a
-     level. The nodes which are specified with horizontal positions are
-     ordered according to these positions within the levels. The nodes
-     which do not have this attribute are inserted into this ordering by
-     the crossing reduction mechanism. Note that connected components are
-     handled separately, thus it is not possible to intermix such
-     components by specifying a horizontal order. If the algorithm for
-     downward laid out trees is used, the horizontal order influences
-     only the order of the child nodes at a node, but not the order of
-     the whole level.
-     Default is unspecified. */
-  int horizontal_order;
-
-  /* width, height is the width and height of a node including the border.
-     If no value (in pixels) is given then width and height are
-     calculated from the size of the label.
-     Default are width and height of the label. */
-  int width;
-  int height;
-
-  /* shrink, stretch gives the shrinking and stretching factor of the
-     node. The values of the attributes width, height, borderwidth and
-     the size of the label text is scaled by ((stretch=shrink) \Lambda
-     100) percent. Note that the actual scale value is determined by the
-     scale value of a node relatively to a scale value of the graph,
-     i.e. if (stretch,shrink) = (2,1) for the graph and (stretch,shrink)
-     = (2,1) for the node of the graph, then the node is scaled by the
-     factor 4 compared to the normal size. The scale value can also be
-     specified by scaling: float.
-     Default are 1,1. */
-  int shrink;
-  int stretch;
-
-  /* folding specifies the default folding of the nodes. The folding k
-     (with k ? 0) means that the graph part that is reachable via edges
-     of a class less or equal to k is folded and displayed as one node.
-     There are commands to unfold such summary nodes, see section 5. If
-     no folding is specified for a node, then the node may be folded if
-     it is in the region of another node that starts the folding. If
-     folding 0 is specified, then the node is never folded. In this case
-     the folding stops at the predecessors of this node, if it is
-     reachable from another folding node. The summary node inherits some
-     attributes from the original node which starts the folding (all
-     color attributes, textmode and label, but not the location). A
-     folded region may contain folded regions with smaller folding class
-     values (nested foldings). If there is more than one node that start
-     the folding of the same region (this implies that the folding class
-     values are equal) then the attributes are inherited by one of these
-     nodes nondeterministically. If foldnode attributes are specified,
-     then the summary node attributes are inherited from these attributes.
-     Default is none. */
-  int folding;
-
-  /* shape specifies the visual appearance of a node: box, rhomb, ellipse,
-     and triangle. The drawing of ellipses is much slower than the drawing
-     of the other shapes.
-     Default is box. */
-  enum shape shape;
-
-  /* textmode specifies the adjustment of the text within the border of a
-     node. The possibilities are center, left.justify and right.justify.
-     Default is center. */
-  enum textmode textmode;
-
-  /* borderwidth specifies the thickness of the node's border in pixels.
-     color is the background color of the node. If none is given, the
-     node is white. For the possibilities, see the attribute color for
-     graphs.
-     Default is 2. */
-  int borderwidth;
-
-  /* node color.
-     Default is white or transparent, */
-  enum color color;
-
-  /* textcolor is the color for the label text. bordercolor is the color
-     of the border. Default color is the textcolor. info1, info2, info3
-     combines additional text labels with a node or a folded graph. info1,
-     Default is black. */
-  enum color textcolor;
-
-  /* info2, info3 can be selected from the menu. The corresponding text
-     labels can be shown by mouse clicks on nodes.
-     Default are null strings. */
-  const char *infos[3];
-
-  /* Node border color.
-     Default is textcolor. */
-  enum color bordercolor;
-
-  /* Next node node... */
-  struct node *next;
-};
-
-/* typedef alias. */
-typedef struct node node;
-
-/*-------------------------------------------------------.
-| Edge attributs list. Structure that describes an edge. |
-`-------------------------------------------------------*/
-
-/* VCG Edge type. */
-enum edge_type
-{
-  normal_edge,
-  back_edge,
-  near_edge,
-  bent_near_edge
-};
-
-/* Structs enum definitions for edges. */
-enum linestyle
-{
-  continuous,
-  dashed,
-  dotted,
-  invisible
-};
-
-enum arrowstyle
-{
-  solid,
-  line,
-  none
-};
-
-/* The struct edge itself. */
-struct edge
-{
-
-  /* Edge type.
-     Default is normal edge. */
-  enum edge_type type;
-
-  /* Sourcename is the title of the source node of the edge.
-     Default: none. */
-  const char *sourcename; /* Mandatory. */
-
-  /* Targetname is the title of the target node of the edge.
-     Default: none. */
-  const char *targetname; /* Mandatory. */
-
-  /* Label specifies the label of the edge. It is drawn if
-     display.edge.labels is set to yes.
-     Default: no label. */
-  const char *label;
-
-  /* Linestyle specifies the style the edge is drawn. Possibilities are:
-     ffl continuous a solid line is drawn ( -- ) ffl dashed the edge
-     consists of single dashes ( - - - ) ffl dotted the edge is made of
-     single dots ( \Delta  \Delta  \Delta  ) ffl invisible the edge is not
-     drawn. The attributes of its shape (color, thickness) are ignored.
-     To draw a dashed or dotted line needs more time than solid lines.
-     Default is continuous. */
-  enum linestyle linestyle;
-
-  /* Thickness is the thickness of an edge.
-     Default is 2. */
-  int thickness;
-
-  /* Class specifies the folding class of the edge. Nodes reachable by
-     edges of a class less or equal to a constant k specify folding
-     regions of k. See the node attribute folding and the folding commands.
-     Default is 1. */
-  int class;
-
-  /* color is the color of the edge.
-     Default is black. */
-  enum color color;
-
-  /* textcolor is the color of the label of the edge. arrowcolor,
-     backarrowcolor is the color of the arrow head and of the backarrow
-     head. priority The positions of the nodes are mainly determined by
-     the incoming and outgoing edges. One can think of rubberbands instead
-     of edges that pull a node into its position. The priority of an edges
-     corresponds to the strength of the rubberband.
-     Default is color. */
-  enum color textcolor;
-
-  /* Arrow color.
-     Default is color. */
-  enum color arrowcolor;
-
-  /* BackArrow color.
-     Default is color. */
-  enum color backarrowcolor;
-
-  /* arrowsize, backarrowsize The arrow head is a right-angled, isosceles
-     triangle and the cathetuses have length arrowsize.
-     Default is 10. */
-  int arrowsize;
-
-  /* Backarrow size
-     Default is 0. */
-  int backarrowsize;
-
-  /* arrowstyle, backarrowstyle Each edge has two arrow heads: the one
-     appears at the target node (the normal arrow head), the other appears
-     at the source node (the backarrow head). Normal edges only have the
-     normal solid arrow head, while the backarrow head is not drawn, i.e.
-     it is none. Arrowstyle is the style of the normal arrow head, and
-     backarrowstyle is the style of the backarrow head. Styles are none,
-     i.e. no arrow head, solid, and line.
-     Default is solid. */
-  enum arrowstyle arrowstyle;
-
-  /* Default is none. */
-  enum arrowstyle backarrowstyle;
-
-  /* Default is 1. */
-  int priority;
-
-  /* Anchor. An anchor point describes the vertical position in a node
-     where an edge goes out. This is useful, if node labels are several
-     lines long, and outgoing edges are related to label lines. (E.g.,
-     this allows a nice visualization of structs containing pointers as
-     fields.).
-     Default is none. */
-  int anchor;
-
-  /* Horizontal order is the horizontal position the edge. This is of
-     interest only if the edge crosses several levels because it specifies
-     the point where the edge crosses the level. within a level. The nodes
-     which are specified with horizontal positions are ordered according
-     to these positions within a level. The horizontal position of a long
-     edge that crosses the level specifies between which two node of that
-     level the edge has to be drawn. Other edges which do not have this
-     attribute are inserted into this ordering by the crossing reduction
-     mechanism. Note that connected components are handled separately,
-     thus it is not possible to intermix such components by specifying a
-     horizontal order.
-     Default is unspcified. */
-  int horizontal_order;
-
-  /*
-  ** Next edge node...
-  */
-  struct edge *next;
-
-};
-
-/*
-** typedef alias.
-*/
-typedef struct edge edge;
-
-/*--------------------------------------------------------.
-| Graph attributs list. Structure that describes a graph. |
-`--------------------------------------------------------*/
-
-struct graph
-{
-  /* Graph title or name.
-     Title specifies the name (a string) associated with the graph. The
-     default name of a subgraph is the name of the outer graph, and the
-     name of the outmost graph is the name of the specification input
-     file. The name of a graph is used to identify this graph, e.g., if
-     we want to express that an edge points to a subgraph. Such edges
-     point to the root of the graph, i.e. the first node of the graph or
-     the root of the first subgraph in the graph, if the subgraph is
-     visualized explicitly.
-     By default, it's the name of the vcg graph file description. */
-  const char *title;
-
-  /* Graph label.
-     Label the text displayed inside the node, when the graph is folded
-     to a node. If no label is specified then the title of the graph will
-     be used. Note that this text may contain control characters like
-     NEWLINE that influences the size of the node.
-     By default, it takes the title value */
-  const char *label;
-
-  /* Any informations.
-     Info1, info2, info3 combines additional text labels with a node or a
-     folded graph. info1, info2, info3 can be selected from the menu
-     interactively. The corresponding text labels can be shown by mouse
-     clicks on nodes.
-     Default values are empty strings (here NULL pointers) */
-  const char *infos[3];
-
-  /* Background color and summary node colors
-     Color specifies the background color for the outermost graph, or the
-     color of the summary node for subgraphs. Colors are given in the enum
-     declared above. If more than these default colors are needed, a
-     color map with maximal 256 entries can be used. The first 32 entries
-     correspond to the colors just listed. A color of the color map can
-     selected by the color map index, an integer, for instance red has
-     index 2, green has index 3, etc.
-     Default is white for background and white or transparent for summary
-     nodes. */
-  enum color color;
-
-  /* Textcolor.
-     need explanations ???
-     default is black for summary nodes. */
-  enum color textcolor;
-
-  /* Bordercolor is the color of the summary node's border. Default color
-     is the textcolor. width, height are width and height of the
-     displayed part of the window of the outermost graph in pixels, or
-     width and height of the summary node of inner subgraphs.
-     Default is the default of the textcolor. */
-  enum color bordercolor;
-
-  /* Width, height are width and height of the displayed part of the
-     window of the outermost graph in pixels, or width and height of the
-     summary node of inner subgraphs.
-     Default value is 100. */
-  int width;
-  int height;
-
-  /* Specify the thickness if summary node's border in pixels.
-     default value is 2. */
-  int borderwidth;
-
-  /* x, y are the x-position and y-position of the graph's window in
-     pixels, relatively to the root screen, if it is the outermost graph.
-     The origin of the window is upper, left hand. For inner subgraphs,
-     it is the position of the folded summary node. The position can also
-     be specified in the form loc: fx:int y:intg.
-     The default value is 0. */
-  int x;
-  int y;
-
-  /* folding of a subgraph is 1, if the subgraph is fused, and 0, if the
-     subgraph is visualized explicitly. There are commands to unfold such
-     summary nodes.
-     Default value is 0 */
-  int folding;
-
-  /* Shrink, stretch gives the shrinking and stretching factor for the
-     graph's representation (default is 1, 1). ((stretch=shrink) \Lambda
-     100) is the scaling of the graph in percentage, e.g.,
-     (stretch,shrink) = (1,1) or (2,2) or (3,3) : : : is normal size,
-     (stretch,shrink) = (1,2) is half size, (stretch,shrink) = (2,1) is
-     double size. For subgraphs, it is also the scaling factor of the
-     summary node. The scaling factor can also be specified by scaling:
-     float (here, scaling 1.0 means normal size). */
-  int shrink;
-  int stretch;
-
-  /* textmode specifies the adjustment of the text within the border of a
-     summary node. The possibilities are center, left.justify and
-     right.justify.
-     Default value is center.*/
-  enum textmode textmode;
-
-  /* Shape can be specified for subgraphs only. It is the shape of the
-     subgraph summary node that appears if the subgraph is folded: box,
-     rhomb, ellipse, and triangle. vertical order is the level position
-     (rank) of the summary node of an inner subgraph, if this subgraph is
-     folded. We can also specify level: int. The level is only
-     recognized, if an automatical layout is calculated. horizontal order
-     is the horizontal position of the summary node within a level. The
-     nodes which are specified with horizontal positions are ordered
-     according to these positions within the levels. The nodes which do
-     not have this attribute are inserted into this ordering by the
-     crossing reduction mechanism. Note that connected
-     components are handled separately, thus it is not possible to
-     intermix such components by specifying a horizontal order. If the
-     algorithm for downward laid out trees is used, the horizontal order
-     influences only the order of the child nodes at a node, but not the
-     order of the whole level.
-     Default is box, other: rhomb, ellipse, triangle. */
-  enum shape shape;
-
-  /* Vertical order is the level position (rank) of the summary node of an
-     inner subgraph, if this subgraph is folded. We can also specify
-     level: int. The level is only recognized, if an automatical layout is
-     calculated.  */
-  int vertical_order;
-
-  /* Horizontal order is the horizontal position of the summary node within
-     a level. The nodes which are specified with horizontal positions are
-     ordered according to these positions within the levels. The nodes which
-     do not have this attribute are inserted into this ordering by the
-     crossing reduction mechanism. Note that connected components are
-     handled separately, thus it is not possible to intermix such components
-     by specifying a horizontal order. If the algorithm for downward laid
-     out trees is used, the horizontal order influences only the order of
-     the child nodes at a node, but not the order of the whole level.  */
-  int horizontal_order;
-
-  /* xmax, ymax specify the maximal size of the virtual window that is
-     used to display the graph. This is usually larger than the displayed
-     part, thus the width and height of the displayed part cannot be
-     greater than xmax and ymax. Only those parts of the graph are drawn
-     that are inside the virtual window. The virtual window can be moved
-     over the potential infinite system of coordinates by special
-     positioning commands.
-     Defaults are 90 and 90. */
-  int xmax;
-  int ymax;
-
-  /* xy-base: specify the upper left corner coordinates of the graph
-     relatively to the root window.
-     Defaults are 5, 5. */
-  int xbase;
-  int ybase;
-
-  /* xspace, yspace the minimum horizontal and vertical distance between
-     nodes. xlspace is the horizontal distance between lines at the
-     points where they cross the levels. (At these points, dummy nodes
-     are used. In fact, this is the horizontal distance between dummy
-     nodes.) It is recommended to set xlspace to a larger value, if
-     splines are used to draw edges, to prevent sharp bendings.
-     Default are 20 and 70. */
-  int xspace;
-  int yspace;
-
-  /* The horizontal space between lines at the point where they cross
-     the levels.
-     defaults value is 1/2 xspace (polygone) and 4/5 xspace (splines)*/
-  int xlspace;
-
-  /* xraster, yraster specifies the raster distance for the position of
-     the nodes. The center of a node is aligned to this raster. xlraster
-     is the horizontal raster for the positions of the line control
-     points (the dummy nodes). It should be a divisor of xraster.
-     defaults are 1,1. */
-  int xraster;
-  int yraster;
-
-  /* xlraster is the horizontal raster for the positions of the line
-     control points (the dummy nodes). It should be a divisor of xraster.
-     defaults is 1. */
-  int xlraster;
-
-  /* hidden specifies the classes of edges that are hidden.
-     Edges that are within such a class are not laid out nor drawn.
-     Nodes that are only reachable (forward or backward) by edges of an
-     hidden class are not drawn. However, nodes that are not reachable
-     at all are drawn. (But see attribute ignore.singles.) Specification
-     of classes of hidden edges allows to hide parts of a graph, e.g.,
-     annotations of a syntax tree. This attribute is only allowed at the
-     outermost level. More than one settings are possible to specify
-     exactly the set of classes that are hidden. Note the important
-     difference between hiding of edges and the edge line style invisible.
-     Hidden edges are not existent in the layout. Edges with line style
-     invisible are existent in the layout; they need space and may
-     produce crossings and influence the layout, but you cannot see
-     them.
-     No default value. */
-  int hidden;
-
-  /* Classname allows to introduce names for the edge classes. The names
-     are used in the menus. infoname allows to introduce names for the
-     additional text labels. The names are used in the menus.
-     defaults are 1,2,3...
-     By default, no class names. */
-  struct classname *classname;
-
-  /* Infoname allows to introduce names for the additional text labels.
-     The names are used in the menus.
-     Infoname is given by an integer and a string.
-     The default value is NULL.  */
-  struct infoname *infoname;
-
-  /* Colorentry allows to fill the color map. A color is a triplet of integer
-     values for the red/green/blue-part. Each integer is between 0 (off) and
-     255 (on), e.g., 0 0 0 is black and 255 255 255 is white. For instance
-     colorentry 75 : 70 130 180 sets the map entry 75 to steel blue. This
-     color can be used by specifying just the number 75.
-     Default id NULL.  */
-  struct colorentry *colorentry;
-
-  /* Layout downfactor, layout upfactor, layout nearfactor The layout
-     algorithm partitions the set of edges into edges pointing upward,
-     edges pointing downward, and edges pointing sidewards. The last type
-     of edges is also called near edges. If the layout.downfactor is
-     large compared to the layout.upfactor and the layout.nearfactor,
-     then the positions of the nodes is mainly determined by the edges
-     pointing downwards. If the layout.upfactor is large compared to the
-     layout.downfactor and the layout.nearfactor, then the positions of
-     the nodes is mainly determined by the edges pointing upwards. If the
-     layout.nearfactor is large, then the positions of the nodes is
-     mainly determined by the edges pointing sidewards. These attributes
-     have no effect, if the method for downward laid out trees is used.
-     Default is normal. */
-  int layout_downfactor;
-  int layout_upfactor;
-  int layout_nearfactor;
-  /* Layout splinefactor determines the bending at splines. The factor
-     100 indicates a very sharp bending, a factor 1 indicates a very flat
-     bending. Useful values are 30 : : : 80. */
-  int layout_splinefactor;
-
-  /* Late edge labels yes means that the graph is first partitioned and
-     then, labels are introduced. The default algorithm first creates
-     labels and then partitions the graph, which yield a more compact
-     layout, but may have more crossings.
-     Default is no. */
-  enum decision late_edge_labels;
-
-  /* Display edge labels yes means display labels and no means don't
-     display edge labels.
-     Default vaule is no. */
-  enum decision display_edge_labels;
-
-  /* Dirty edge labels yes enforces a fast layout of edge labels, which
-     may very ugly because several labels may be drawn at the same place.
-     Dirty edge labels cannot be used if splines are used.
-     Default is no.
-  */
-  enum decision dirty_edge_labels;
-
-  /* Finetuning no switches the fine tuning phase of the graph layout
-     algorithm off, while it is on as default. The fine tuning phase
-     tries to give all edges the same length.
-     Default is yes. */
-  enum decision finetuning;
-
-  /* Ignore singles yes hides all nodes which would appear single and
-     unconnected from the remaining graph. Such nodes have no edge at all
-     and are sometimes very ugly. Default is to show all nodes.
-     Default is no. */
-  enum decision ignore_singles;
-
-  /* priority phase yes replaces the normal pendulum method by a
-     specialized method: It forces straight long edges with 90 degree,
-     just as the straight phase. In fact, the straight phase is a fine
-     tune phase of the priority method. This phase is also recommended,
-     if an orthogonal layout is selected (see manhattan.edges).
-     Default is no. */
-  enum decision priority_phase;
-
-  /* manhattan edges yes switches the orthogonal layout on. Orthogonal
-     layout (or manhattan layout) means that all edges consist of line
-     segments with gradient 0 or 90 degree. Vertical edge segments might
-     by shared by several edges, while horizontal edge segments are never
-     shared. This results in very aesthetical layouts just for flowcharts.
-     If the orthogonal layout is used, then the priority phase and
-     straight phase should be used. Thus, these both phases are switched
-     on, too, unless priority layout and straight line tuning are
-     switched off explicitly.
-     Default is no. */
-  enum decision manhattan_edges;
-
-  /* Smanhattan edges yes switches a specialized orthogonal layout on:
-     Here, all horizontal edge segments between two levels share the same
-     horizontal line, i.e. not only vertical edge segments are shared,
-     but horizontal edge segments are shared by several edges, too. This
-     looks nice for trees but might be too confusing in general, because
-     the location of an edge might be ambiguously.
-     Default is no. */
-  enum decision smanhattan_edges;
-
-  /* Near edges no suppresses near edges and bent near edges in the
-     graph layout.
-     Default is yes. */
-  enum decision near_edges;
-
-  /* Orientation specifies the orientation of the graph: top.to.bottom,
-     bottom.to.top, left.to.right or right.to.left. Note: the normal
-     orientation is top.to.bottom. All explanations here are given
-     relatively to the normal orientation, i.e., e.g., if the orientation
-     is left to right, the attribute xlspace is not the horizontal but
-     the vertical distance between lines, etc.
-     Default is to_to_bottom. */
-  enum orientation orientation;
-
-  /* Node alignment specified the vertical alignment of nodes at the
-     horizontal reference line of the levels. If top is specified, the
-     tops of all nodes of a level have the same y-coordinate; on bottom,
-     the bottoms have the same y-coordinate, on center the nodes are
-     centered at the levels.
-     Default is center. */
-  enum alignment node_alignment;
-
-  /* Port sharing no suppresses the sharing of ports of edges at the
-     nodes. Normally, if multiple edges are adjacent to the same node,
-     and the arrow head of all these edges has the same visual appearance
-     (color, size, etc.), then these edges may share a port at a node,
-     i.e. only one arrow head is draw, and all edges are incoming into
-     this arrow head. This allows to have many edges adjacent to one node
-     without getting confused by too many arrow heads. If no port sharing
-     is used, each edge has its own port, i.e. its own place where it is
-     adjacent to the node.
-     Default is yes. */
-  enum decision port_sharing;
-
-  /* Arrow mode fixed (default) should be used, if port sharing is used,
-     because then, only a fixed set of rotations for the arrow heads are
-     used. If the arrow mode is free, then each arrow head is rotated
-     individually to each edge. But this can yield to a black spot, where
-     nothing is recognizable, if port sharing is used, since all these
-     qdifferently rotated arrow heads are drawn at the same place. If the
-     arrow mode is fixed, then the arrow head is rotated only in steps of
-     45 degree, and only one arrow head occurs at each port.
-     Default is fixed. */
-  enum arrow_mode arrow_mode;
-
-  /* Treefactor The algorithm tree for downward laid out trees tries to
-     produce a medium dense, balanced tree-like layout. If the tree
-     factor is greater than 0.5, the tree edges are spread, i.e. they
-     get a larger gradient. This may improve the readability of the tree.
-     Note: it is not obvious whether spreading results in a more dense or
-     wide layout. For a tree, there is a tree factor such that the whole
-     tree is minimal wide.
-     Default is 0.5. */
-  float treefactor;
-
-  /* Spreadlevel This parameter only influences the algorithm tree, too.
-     For large, balanced trees, spreading of the uppermost nodes would
-     enlarge the width of the tree too much, such that the tree does not
-     fit anymore in a window. Thus, the spreadlevel specifies the minimal
-     level (rank) where nodes are spread. Nodes of levels upper than
-     spreadlevel are not spread.
-     Default is 1. */
-  int spreadlevel;
-
-  /* Crossing weight specifies the weight that is used for the crossing
-     reduction: bary (default), median, barymedian or medianbary. We
-     cannot give a general recommendation, which is the best method. For
-     graphs with very large average degree of edges (number of incoming
-     and outgoing edges at a node), the weight bary is the fastest
-     method. With the weights barymedian and medianbary, equal weights of
-     different nodes are not very probable, thus the crossing reduction
-     phase 2 might be very fast.
-     Default is bary. */
-  enum crossing_type crossing_weight;
-
-  /* Crossing phase2 is the most time consuming phase of the crossing
-     reduction. In this phase, the nodes that happen to have equal
-     crossing weights are permuted. By specifying no, this phase is
-     suppressed.
-     Default is yes. */
-  enum decision crossing_phase2;
-
-  /* Crossing optimization is a postprocessing phase after the normal
-     crossing reduction: we try to optimize locally, by exchanging pairs
-     of nodes to reduce the crossings. Although this phase is not very
-     time consuming, it can be suppressed by specifying no.
-     Default is yes. */
-  enum decision crossing_optimization;
-
-  /* View allows to select the fisheye views. Because
-     of the fixed size of the window that shows the graph, we normally
-     can only see a small amount of a large graph. If we shrink the graph
-     such that it fits into the window, we cannot recognize any detail
-     anymore. Fisheye views are coordinate transformations: the view onto
-     the graph is distort, to overcome this usage deficiency. The polar
-     fisheye is easy to explain: assume a projection of the plane that
-     contains the graph picture onto a spheric ball. If we now look onto
-     this ball in 3 D, we have a polar fisheye view. There is a focus
-     point which is magnified such that we see all details. Parts of the
-     plane that are far away from the focus point are demagnified very
-     much. Cartesian fisheye have a similar effect; only the formula for
-     the coordinate transformation is different. Selecting cfish means
-     the cartesian fisheye is used which demagnifies such that the whole
-     graph is visible (self adaptable cartesian fisheye). With fcfish,
-     the cartesian fisheye shows the region of a fixed radius around the
-     focus point (fixed radius cartesian fisheye). This region might be
-     smaller than the whole graph, but the demagnification needed to show
-     this region in the window is also not so large, thus more details
-     are recognizable. With pfish the self adaptable polar fisheye is
-     selected that shows the whole graph, and with fpfish the fixed
-     radius polar fisheye is selected.
-     Default is normal view.  */
-  enum view view;
-
-  /* Edges no suppresses the drawing of edges.
-     Default is yes. */
-  enum decision edges;
-
-  /* Nodes no suppresses the drawing of nodes.
-     Default is yes. */
-  enum decision nodes;
-
-  /* Splines specifies whether splines are used to draw edges (yes or no).
-     As default, polygon segments are used to draw edges, because this is
-     much faster. Note that the spline drawing routine is not fully
-     validated, and is very slow. Its use is mainly to prepare high
-     quality PostScript output for very small graphs.
-     Default is no. */
-  enum decision splines;
-
-  /* Bmax set the maximal number of iterations that are done for the
-     reduction of edge bendings.
-   Default is 100. */
-  int bmax;
-
-  /* Cmin set the minimal number of iterations that are done for the
-     crossing reduction with the crossing weights. The normal method
-     stops if two consecutive checks does not reduce the number of
-     crossings anymore. However, this increasing of the number of
-     crossings might be locally, such that after some more iterations,
-     the crossing number might decrease much more.
-     Default is 0. */
-  int cmin;
-
-  /* Cmax set the maximal number of interactions for crossing reduction.
-     This is helpful for speeding up the layout process.
-     Default is -1, which represents infinity.  */
-  int cmax;
-
-  /* Pmin set the minimal number of iterations that is done with the
-     pendulum method. Similar to the crossing reduction, this method
-     stops if the `imbalancement weight' does not decreases anymore.
-     However, the increasing of the imbalancement weight might be locally,
-     such that after some more iterations, the imbalancement weight might
-     decrease much more.
-     Default is 0. */
-  int pmin;
-
-  /* Pmax set the maximal number of iterations of the pendulum method.
-     This is helpful for speedup the layout process.
-     Default is 100. */
-  int pmax;
-
-  /* Rmin set the minimal number of iterations that is done with the
-     rubberband method. This is similar as for the pendulum method.
-     Default is 0. */
-  int rmin;
-
-  /* Rmax set the maximal number of iterations of the rubberband method.
-     This is helpful for speedup the layout process.
-     Default is 100. */
-  int rmax;
-
-  /* Smax set the maximal number of iterations of the straight line
-     recognition phase (useful only, if the straight line recognition
-     phase is switched on, see attribute straight.phase).
-     Default is 100. */
-  int smax;
-
-  /* Generic values.
-   */
-  node node;
-  edge edge;
-
-  /* List of nodes declared.
-     Pointer. */
-  node *node_list;
-
-  /* List of edges declared.
-     Pointer. */
-  edge *edge_list;
-
-};
-
-/* Graph typedefs. */
-typedef struct graph graph;
-
-void new_graph (graph *g);
-void new_node (node *n);
-void new_edge (edge *e);
-
-void add_node (graph *g, node *n);
-void add_edge (graph *g, edge *e);
-
-void add_colorentry (graph *g, int color_idx, int red_cp,
-		     int green_cp, int blue_cp);
-void add_classname (graph *g, int val, const char *name);
-void add_infoname (graph *g, int val, const char *name);
-
-void open_node (FILE *fout);
-void output_node (node *n, FILE *fout);
-void close_node (FILE *fout);
-
-void open_edge (edge *e, FILE *fout);
-void output_edge (edge *e, FILE *fout);
-void close_edge (FILE *fout);
-
-void open_graph (FILE *fout);
-void output_graph (graph *g, FILE *fout);
-void close_graph (graph *g, FILE *fout);
-
-#endif /* VCG_H_ */
diff --git a/src/vcg_defaults.h b/src/vcg_defaults.h
deleted file mode 100644
index 78e24b5..0000000
--- a/src/vcg_defaults.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* VCG description handler for Bison.
-
-   Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
-
-   This file is part of Bison, the GNU Compiler Compiler.
-
-   Bison 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 2, or (at your option)
-   any later version.
-
-   Bison 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 Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
-#ifndef VCG_DEFAULTS_H_
-# define VCG_DEFAULTS_H_
-
-/* Graph defaults. */
-# define G_TITLE		NULL
-# define G_LABEL		NULL
-# define G_INFOS1		NULL
-# define G_INFOS2		NULL
-# define G_INFOS3		NULL
-
-# define G_COLOR		white
-# define G_TEXTCOLOR		black
-# define G_BORDERCOLOR		G_TEXTCOLOR
-
-# define G_WIDTH		100
-# define G_HEIGHT		100
-# define G_BORDERWIDTH		2
-
-# define G_X			0
-# define G_Y			0
-
-# define G_FOLDING		0
-
-# define G_SHRINK		1
-# define G_STRETCH		1
-
-# define G_TEXTMODE		centered
-# define G_SHAPE		box
-
-# define G_VERTICAL_ORDER	0	/* Unspecified for subgraphs.  */
-# define G_HORIZONTAL_ORDER	0	/* Unspecified for subgraphs.  */
-
-# define G_XMAX			90	/* Not output.  */
-# define G_YMAX			90	/* Not output.  */
-
-# define G_XBASE		5
-# define G_YBASE		5
-
-# define G_XSPACE		20
-# define G_YSPACE		70
-# define G_XLSPACE		(G_XSPACE / 2)	/* Not output */
-
-# define G_XRASTER		1
-# define G_YRASTER		1
-# define G_XLRASTER		1
-
-# define G_HIDDEN		(-1)	/* No default value.  */
-
-# define G_CLASSNAME		NULL	/* No class name association.  */
-# define G_INFONAME		NULL
-# define G_COLORENTRY		NULL
-
-# define G_LAYOUTALGORITHM	normal
-# define G_LAYOUT_DOWNFACTOR	1
-# define G_LAYOUT_UPFACTOR	1
-# define G_LAYOUT_NEARFACTOR	1
-# define G_LAYOUT_SPLINEFACTOR	70
-
-# define G_LATE_EDGE_LABELS	no
-# define G_DISPLAY_EDGE_LABELS	no
-# define G_DIRTY_EDGE_LABELS	no
-# define G_FINETUNING		yes
-# define G_IGNORE_SINGLES	no
-# define G_LONG_STRAIGHT_PHASE	no
-# define G_PRIORITY_PHASE	no
-# define G_MANHATTAN_EDGES	no
-# define G_SMANHATTAN_EDGES	no
-# define G_NEAR_EDGES		yes
-
-# define G_ORIENTATION		top_to_bottom
-# define G_NODE_ALIGNMENT	center
-# define G_PORT_SHARING		yes
-# define G_ARROW_MODE		fixed
-# define G_TREEFACTOR		0.5
-# define G_SPREADLEVEL		1
-# define G_CROSSING_WEIGHT	bary
-# define G_CROSSING_PHASE2	yes
-# define G_CROSSING_OPTIMIZATION	yes
-# define G_VIEW			normal_view
-
-# define G_EDGES		yes
-# define G_NODES		yes
-# define G_SPLINES		no
-
-# define G_BMAX			100
-# define G_CMIN			0
-# define G_CMAX			(-1)	/* Infinity */
-# define G_PMIN			0
-# define G_PMAX			100
-# define G_RMIN			0
-# define G_RMAX			100
-# define G_SMAX			100
-
-# define G_NODE_LIST		NULL
-# define G_EDGE_LIST		NULL
-
-/* Nodes defaults. */
-# define N_TITLE		NULL
-# define N_LABEL		NULL
-
-# define N_LOCX			(-1)	/* Default unspcified */
-# define N_LOCY			(-1)	/* Default unspcified */
-
-# define N_VERTICAL_ORDER	(-1)	/* Default unspcified */
-# define N_HORIZONTAL_ORDER	(-1)	/* Default unspcified */
-
-# define N_WIDTH		(-1)	/* We assume that we can't define it now. */
-# define N_HEIGHT		(-1)	/* also. */
-
-# define N_SHRINK		1
-# define N_STRETCH		1
-
-# define N_FOLDING		(-1)	/* no explicit default value. */
-
-# define N_SHAPE		box
-# define N_TEXTMODE		centered
-# define N_BORDERWIDTH		2
-
-# define N_COLOR		white
-# define N_TEXTCOLOR		black
-# define N_BORDERCOLOR		N_TEXTCOLOR
-
-# define N_INFOS1		NULL
-# define N_INFOS2		NULL
-# define N_INFOS3		NULL
-
-# define N_NEXT			NULL
-
-/* Edge defaults. */
-# define E_EDGE_TYPE		normal_edge
-
-# define E_SOURCENAME		NULL	/* Mandatory. */
-# define E_TARGETNAME		NULL	/* Mandatory. */
-# define E_LABEL		NULL
-
-# define E_LINESTYLE		continuous
-# define E_THICKNESS		2
-
-# define E_CLASS		1
-
-# define E_COLOR		black
-# define E_TEXTCOLOR		E_COLOR
-# define E_ARROWCOLOR		E_COLOR
-# define E_BACKARROWCOLOR	E_COLOR
-
-# define E_ARROWSIZE		10
-# define E_BACKARROWSIZE	0
-
-# define E_ARROWSTYLE		solid
-# define E_BACKARROWSTYLE	none
-
-# define E_PRIORITY		1
-
-# define E_ANCHOR		(-1)
-
-# define E_HORIZONTAL_ORDER	(-1)
-
-# define E_NEXT			NULL
-
-#endif /* not VCG_DEFAULTS_H_ */
diff --git a/src/yacc b/src/yacc
deleted file mode 100755
index eda226d..0000000
--- a/src/yacc
+++ /dev/null
@@ -1,2 +0,0 @@
-#! /bin/sh
-exec /home/phanna/src/bison/bin/bison -y "$@"