aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/bison/src
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-05-17 12:00:42 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-05-17 12:10:14 +0300
commit2bd98b5c8ddd404f62db9f74144a763de01341cc (patch)
tree93040aaeb1b7076ec9e3de486128f99b44316e7f /contrib/tools/bison/src
parent3d339ed1c60a04d959a40aaa931e1792a1a9cabb (diff)
downloadydb-2bd98b5c8ddd404f62db9f74144a763de01341cc.tar.gz
Sync contrib/tools/bison layout with upstream
59379f119eb5f2fd036edea64923ff53b96c9028
Diffstat (limited to 'contrib/tools/bison/src')
-rw-r--r--contrib/tools/bison/src/AnnotationList.c808
-rw-r--r--contrib/tools/bison/src/AnnotationList.h182
-rw-r--r--contrib/tools/bison/src/InadequacyList.c79
-rw-r--r--contrib/tools/bison/src/InadequacyList.h156
-rw-r--r--contrib/tools/bison/src/LR0.c375
-rw-r--r--contrib/tools/bison/src/LR0.h28
-rw-r--r--contrib/tools/bison/src/Sbitset.c80
-rw-r--r--contrib/tools/bison/src/Sbitset.h92
-rw-r--r--contrib/tools/bison/src/assoc.c50
-rw-r--r--contrib/tools/bison/src/assoc.h35
-rw-r--r--contrib/tools/bison/src/closure.c246
-rw-r--r--contrib/tools/bison/src/closure.h57
-rw-r--r--contrib/tools/bison/src/complain.c379
-rw-r--r--contrib/tools/bison/src/complain.h144
-rw-r--r--contrib/tools/bison/src/conflicts.c629
-rw-r--r--contrib/tools/bison/src/conflicts.h47
-rw-r--r--contrib/tools/bison/src/derives.c120
-rw-r--r--contrib/tools/bison/src/derives.h35
-rw-r--r--contrib/tools/bison/src/files.c420
-rw-r--r--contrib/tools/bison/src/files.h72
-rw-r--r--contrib/tools/bison/src/flex-scanner.h90
-rw-r--r--contrib/tools/bison/src/getargs.c741
-rw-r--r--contrib/tools/bison/src/getargs.h141
-rw-r--r--contrib/tools/bison/src/gram.c310
-rw-r--r--contrib/tools/bison/src/gram.h273
-rw-r--r--contrib/tools/bison/src/graphviz.c218
-rw-r--r--contrib/tools/bison/src/graphviz.h71
-rw-r--r--contrib/tools/bison/src/ielr.c1200
-rw-r--r--contrib/tools/bison/src/ielr.h46
-rw-r--r--contrib/tools/bison/src/lalr.c500
-rw-r--r--contrib/tools/bison/src/lalr.h106
-rw-r--r--contrib/tools/bison/src/location.c232
-rw-r--r--contrib/tools/bison/src/location.h131
-rw-r--r--contrib/tools/bison/src/main.c226
-rw-r--r--contrib/tools/bison/src/muscle-tab.c775
-rw-r--r--contrib/tools/bison/src/muscle-tab.h218
-rw-r--r--contrib/tools/bison/src/named-ref.c46
-rw-r--r--contrib/tools/bison/src/named-ref.h46
-rw-r--r--contrib/tools/bison/src/nullable.c142
-rw-r--r--contrib/tools/bison/src/nullable.h32
-rw-r--r--contrib/tools/bison/src/output.c740
-rw-r--r--contrib/tools/bison/src/output.h30
-rw-r--r--contrib/tools/bison/src/parse-gram.c3106
-rw-r--r--contrib/tools/bison/src/parse-gram.h190
-rw-r--r--contrib/tools/bison/src/print-xml.c545
-rw-r--r--contrib/tools/bison/src/print-xml.h30
-rw-r--r--contrib/tools/bison/src/print.c529
-rw-r--r--contrib/tools/bison/src/print.h25
-rw-r--r--contrib/tools/bison/src/print_graph.c193
-rw-r--r--contrib/tools/bison/src/print_graph.h25
-rw-r--r--contrib/tools/bison/src/reader.c796
-rw-r--r--contrib/tools/bison/src/reader.h73
-rw-r--r--contrib/tools/bison/src/reduce.c466
-rw-r--r--contrib/tools/bison/src/reduce.h32
-rw-r--r--contrib/tools/bison/src/relation.c183
-rw-r--r--contrib/tools/bison/src/relation.h49
-rw-r--r--contrib/tools/bison/src/scan-code-c.c3
-rw-r--r--contrib/tools/bison/src/scan-code.c2990
-rw-r--r--contrib/tools/bison/src/scan-code.h196
-rw-r--r--contrib/tools/bison/src/scan-gram-c.c3
-rw-r--r--contrib/tools/bison/src/scan-gram.c4018
-rw-r--r--contrib/tools/bison/src/scan-gram.h38
-rw-r--r--contrib/tools/bison/src/scan-skel-c.c3
-rw-r--r--contrib/tools/bison/src/scan-skel.c2435
-rw-r--r--contrib/tools/bison/src/scan-skel.h27
-rw-r--r--contrib/tools/bison/src/state.c466
-rw-r--r--contrib/tools/bison/src/state.h274
-rw-r--r--contrib/tools/bison/src/symlist.c239
-rw-r--r--contrib/tools/bison/src/symlist.h133
-rw-r--r--contrib/tools/bison/src/symtab.c1178
-rw-r--r--contrib/tools/bison/src/symtab.h338
-rw-r--r--contrib/tools/bison/src/system.h261
-rw-r--r--contrib/tools/bison/src/tables.c863
-rw-r--r--contrib/tools/bison/src/tables.h141
-rw-r--r--contrib/tools/bison/src/uniqstr.c184
-rw-r--r--contrib/tools/bison/src/uniqstr.h103
76 files changed, 30483 insertions, 0 deletions
diff --git a/contrib/tools/bison/src/AnnotationList.c b/contrib/tools/bison/src/AnnotationList.c
new file mode 100644
index 0000000000..b5781766a4
--- /dev/null
+++ b/contrib/tools/bison/src/AnnotationList.c
@@ -0,0 +1,808 @@
+/* IELR's inadequacy annotation list.
+
+ Copyright (C) 2009-2013 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;
+ bitset *lookaheads;
+ for (predecessor = predecessors[s->number]; *predecessor; ++predecessor)
+ {
+ AnnotationList *annotation_node =
+ AnnotationList__alloc_on_obstack (
+ self->inadequacyNode->contributionCount, annotations_obstackp);
+ bool potential_contribution = false;
+ annotation_node->inadequacyNode = self->inadequacyNode;
+ 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/contrib/tools/bison/src/AnnotationList.h b/contrib/tools/bison/src/AnnotationList.h
new file mode 100644
index 0000000000..5abaa2e79b
--- /dev/null
+++ b/contrib/tools/bison/src/AnnotationList.h
@@ -0,0 +1,182 @@
+/* IELR's inadequacy annotation list.
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/InadequacyList.c b/contrib/tools/bison/src/InadequacyList.c
new file mode 100644
index 0000000000..9510b40d91
--- /dev/null
+++ b/contrib/tools/bison/src/InadequacyList.c
@@ -0,0 +1,79 @@
+/* IELR's inadequacy list.
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/InadequacyList.h b/contrib/tools/bison/src/InadequacyList.h
new file mode 100644
index 0000000000..d293b9b6c6
--- /dev/null
+++ b/contrib/tools/bison/src/InadequacyList.h
@@ -0,0 +1,156 @@
+/* IELR's inadequacy list.
+
+ Copyright (C) 2009-2013 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</tt> 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/contrib/tools/bison/src/LR0.c b/contrib/tools/bison/src/LR0.c
new file mode 100644
index 0000000000..f6a9537e4c
--- /dev/null
+++ b/contrib/tools/bison/src/LR0.c
@@ -0,0 +1,375 @@
+/* Generate the LR(0) parser states for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 2000-2002, 2004-2013 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/>. */
+
+
+/* See comments in state.h for the data structures that represent it.
+ The entry point is generate_states. */
+
+#include <config.h>
+#include "system.h"
+
+#include <bitset.h>
+
+#include "LR0.h"
+#include "closure.h"
+#include "complain.h"
+#include "getargs.h"
+#include "gram.h"
+#include "lalr.h"
+#include "reader.h"
+#include "reduce.h"
+#include "state.h"
+#include "symtab.h"
+
+typedef struct state_list
+{
+ struct state_list *next;
+ state *state;
+} state_list;
+
+static state_list *first_state = NULL;
+static state_list *last_state = NULL;
+
+
+/*------------------------------------------------------------------.
+| A state was just discovered from another state. Queue it for |
+| later examination, in order to find its transitions. Return it. |
+`------------------------------------------------------------------*/
+
+static state *
+state_list_append (symbol_number sym, size_t core_size, item_number *core)
+{
+ state_list *node = xmalloc (sizeof *node);
+ state *s = state_new (sym, core_size, core);
+
+ if (trace_flag & trace_automaton)
+ fprintf (stderr, "state_list_append (state = %d, symbol = %d (%s))\n",
+ nstates, sym, symbols[sym]->tag);
+
+ node->next = NULL;
+ node->state = s;
+
+ if (!first_state)
+ first_state = node;
+ if (last_state)
+ last_state->next = node;
+ last_state = node;
+
+ return s;
+}
+
+static int nshifts;
+static symbol_number *shift_symbol;
+
+static rule **redset;
+static state **shiftset;
+
+static item_number **kernel_base;
+static int *kernel_size;
+static item_number *kernel_items;
+
+
+static void
+allocate_itemsets (void)
+{
+ symbol_number i;
+ rule_number r;
+ item_number *rhsp;
+
+ /* Count the number of occurrences of all the symbols in RITEMS.
+ Note that useless productions (hence useless nonterminals) are
+ browsed too, hence we need to allocate room for _all_ the
+ symbols. */
+ size_t count = 0;
+ size_t *symbol_count = xcalloc (nsyms + nuseless_nonterminals,
+ sizeof *symbol_count);
+
+ for (r = 0; r < nrules; ++r)
+ for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
+ {
+ count++;
+ symbol_count[*rhsp]++;
+ }
+
+ /* See comments before new_itemsets. All the vectors of items
+ live inside KERNEL_ITEMS. The number of active items after
+ some symbol S cannot be more than the number of times that S
+ appears as an item, which is SYMBOL_COUNT[S].
+ We allocate that much space for each symbol. */
+
+ kernel_base = xnmalloc (nsyms, sizeof *kernel_base);
+ kernel_items = xnmalloc (count, sizeof *kernel_items);
+
+ count = 0;
+ for (i = 0; i < nsyms; i++)
+ {
+ kernel_base[i] = kernel_items + count;
+ count += symbol_count[i];
+ }
+
+ free (symbol_count);
+ kernel_size = xnmalloc (nsyms, sizeof *kernel_size);
+}
+
+
+static void
+allocate_storage (void)
+{
+ allocate_itemsets ();
+
+ shiftset = xnmalloc (nsyms, sizeof *shiftset);
+ redset = xnmalloc (nrules, sizeof *redset);
+ state_hash_new ();
+ shift_symbol = xnmalloc (nsyms, sizeof *shift_symbol);
+}
+
+
+static void
+free_storage (void)
+{
+ free (shift_symbol);
+ free (redset);
+ free (shiftset);
+ free (kernel_base);
+ free (kernel_size);
+ free (kernel_items);
+ state_hash_free ();
+}
+
+
+
+
+/*---------------------------------------------------------------.
+| Find which symbols can be shifted in S, and for each one |
+| record which items would be active after that shift. Uses the |
+| contents of itemset. |
+| |
+| shift_symbol is set to a vector of the symbols that can be |
+| 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
+new_itemsets (state *s)
+{
+ size_t i;
+
+ if (trace_flag & trace_automaton)
+ fprintf (stderr, "Entering new_itemsets, state = %d\n", s->number);
+
+ memset (kernel_size, 0, nsyms * sizeof *kernel_size);
+
+ nshifts = 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])
+ {
+ shift_symbol[nshifts] = sym;
+ nshifts++;
+ }
+
+ kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
+ kernel_size[sym]++;
+ }
+}
+
+
+
+/*--------------------------------------------------------------.
+| Find the state we would get to (from the current state) by |
+| shifting SYM. Create a new state if no equivalent one exists |
+| already. Used by append_states. |
+`--------------------------------------------------------------*/
+
+static state *
+get_state (symbol_number sym, size_t core_size, item_number *core)
+{
+ state *s;
+
+ if (trace_flag & trace_automaton)
+ fprintf (stderr, "Entering get_state, symbol = %d (%s)\n",
+ sym, symbols[sym]->tag);
+
+ s = state_hash_lookup (core_size, core);
+ if (!s)
+ s = state_list_append (sym, core_size, core);
+
+ if (trace_flag & trace_automaton)
+ fprintf (stderr, "Exiting get_state => %d\n", s->number);
+
+ return s;
+}
+
+/*---------------------------------------------------------------.
+| Use the information computed by new_itemsets to find the state |
+| numbers reached by each shift transition from S. |
+| |
+| SHIFTSET is set up as a vector of those states. |
+`---------------------------------------------------------------*/
+
+static void
+append_states (state *s)
+{
+ int i;
+
+ if (trace_flag & trace_automaton)
+ fprintf (stderr, "Entering append_states, state = %d\n", s->number);
+
+ /* First sort shift_symbol into increasing order. */
+
+ for (i = 1; i < nshifts; i++)
+ {
+ symbol_number sym = shift_symbol[i];
+ int j;
+ for (j = i; 0 < j && sym < shift_symbol[j - 1]; j--)
+ shift_symbol[j] = shift_symbol[j - 1];
+ shift_symbol[j] = sym;
+ }
+
+ for (i = 0; i < nshifts; i++)
+ {
+ symbol_number sym = shift_symbol[i];
+ shiftset[i] = get_state (sym, kernel_size[sym], kernel_base[sym]);
+ }
+}
+
+
+/*----------------------------------------------------------------.
+| Find which rules can be used for reduction transitions from the |
+| current state and make a reductions structure for the state to |
+| record their rule numbers. |
+`----------------------------------------------------------------*/
+
+static void
+save_reductions (state *s)
+{
+ int count = 0;
+ size_t i;
+
+ /* Find and count the active items that represent ends of rules. */
+ for (i = 0; i < nitemset; ++i)
+ {
+ item_number item = ritem[itemset[i]];
+ if (item_number_is_rule_number (item))
+ {
+ rule_number r = item_number_as_rule_number (item);
+ redset[count++] = &rules[r];
+ if (r == 0)
+ {
+ /* This is "reduce 0", i.e., accept. */
+ aver (!final_state);
+ final_state = s;
+ }
+ }
+ }
+
+ /* Make a reductions structure and copy the data into it. */
+ state_reductions_set (s, count, redset);
+}
+
+
+/*---------------.
+| Build STATES. |
+`---------------*/
+
+static void
+set_states (void)
+{
+ states = xcalloc (nstates, sizeof *states);
+
+ while (first_state)
+ {
+ state_list *this = first_state;
+
+ /* Pessimization, but simplification of the code: make sure all
+ the states have valid transitions and reductions members,
+ even if reduced to 0. It is too soon for errs, which are
+ computed later, but set_conflicts. */
+ state *s = this->state;
+ if (!s->transitions)
+ state_transitions_set (s, 0, 0);
+ if (!s->reductions)
+ state_reductions_set (s, 0, 0);
+
+ states[s->number] = s;
+
+ first_state = this->next;
+ free (this);
+ }
+ first_state = NULL;
+ last_state = NULL;
+}
+
+
+/*-------------------------------------------------------------------.
+| Compute the LR(0) parser states (see state.h for details) from the |
+| grammar. |
+`-------------------------------------------------------------------*/
+
+void
+generate_states (void)
+{
+ item_number initial_core = 0;
+ state_list *list = NULL;
+ allocate_storage ();
+ new_closure (nritems);
+
+ /* Create the initial state. The 0 at the lhs is the index of the
+ item of this initial rule. */
+ state_list_append (0, 1, &initial_core);
+
+ /* States are queued when they are created; process them all. */
+ for (list = first_state; list; list = list->next)
+ {
+ state *s = list->state;
+ if (trace_flag & trace_automaton)
+ fprintf (stderr, "Processing state %d (reached by %s)\n",
+ s->number,
+ symbols[s->accessing_symbol]->tag);
+ /* 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);
+ /* Find the itemsets of the states that shifts can reach. */
+ new_itemsets (s);
+ /* Find or create the core structures for those states. */
+ append_states (s);
+
+ /* Create the shifts structures for the shifts to those states,
+ now that the state numbers transitioning to are known. */
+ state_transitions_set (s, nshifts, shiftset);
+ }
+
+ /* discard various storage */
+ free_closure ();
+ free_storage ();
+
+ /* Set up STATES. */
+ set_states ();
+}
diff --git a/contrib/tools/bison/src/LR0.h b/contrib/tools/bison/src/LR0.h
new file mode 100644
index 0000000000..976bcb26ee
--- /dev/null
+++ b/contrib/tools/bison/src/LR0.h
@@ -0,0 +1,28 @@
+/* Generate the LR(0) parser states for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 2000-2002, 2009-2013 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 LR0_H_
+# define LR0_H_
+
+# include "state.h"
+
+void generate_states (void);
+
+#endif /* !LR0_H_ */
diff --git a/contrib/tools/bison/src/Sbitset.c b/contrib/tools/bison/src/Sbitset.c
new file mode 100644
index 0000000000..bb278b55db
--- /dev/null
+++ b/contrib/tools/bison/src/Sbitset.c
@@ -0,0 +1,80 @@
+/* A simple, memory-efficient bitset implementation.
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/Sbitset.h b/contrib/tools/bison/src/Sbitset.h
new file mode 100644
index 0000000000..bcb329ad39
--- /dev/null
+++ b/contrib/tools/bison/src/Sbitset.h
@@ -0,0 +1,92 @@
+/* A simple, memory-efficient bitset implementation.
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/assoc.c b/contrib/tools/bison/src/assoc.c
new file mode 100644
index 0000000000..d2eec31574
--- /dev/null
+++ b/contrib/tools/bison/src/assoc.c
@@ -0,0 +1,50 @@
+/* Associativity information.
+
+ Copyright (C) 2002, 2005-2006, 2008-2013 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 "assoc.h"
+
+
+const char *
+assoc_to_string (assoc a)
+{
+ switch (a)
+ {
+ default:
+ abort ();
+
+ case undef_assoc:
+ return "undefined associativity";
+
+ case right_assoc:
+ return "%right";
+
+ case left_assoc:
+ return "%left";
+
+ case non_assoc:
+ return "%nonassoc";
+
+ case precedence_assoc:
+ return "%precedence";
+ }
+}
diff --git a/contrib/tools/bison/src/assoc.h b/contrib/tools/bison/src/assoc.h
new file mode 100644
index 0000000000..b9475b5d12
--- /dev/null
+++ b/contrib/tools/bison/src/assoc.h
@@ -0,0 +1,35 @@
+/* Associativity information.
+
+ Copyright (C) 2002, 2006, 2008-2013 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 ASSOC_H_
+# define ASSOC_H_
+
+/* Associativity values for tokens and rules. */
+typedef enum
+{
+ undef_assoc, /** Not defined. */
+ right_assoc, /** %right */
+ left_assoc, /** %left */
+ non_assoc, /** %nonassoc */
+ precedence_assoc /** %precedence */
+} assoc;
+
+char const *assoc_to_string (assoc a);
+
+#endif /* !ASSOC_H_ */
diff --git a/contrib/tools/bison/src/closure.c b/contrib/tools/bison/src/closure.c
new file mode 100644
index 0000000000..45e8311022
--- /dev/null
+++ b/contrib/tools/bison/src/closure.c
@@ -0,0 +1,246 @@
+/* Closures for Bison
+
+ Copyright (C) 1984, 1989, 2000-2002, 2004-2005, 2007, 2009-2013 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 <bitset.h>
+#include <bitsetv-print.h>
+#include <bitsetv.h>
+
+#include "closure.h"
+#include "derives.h"
+#include "getargs.h"
+#include "gram.h"
+#include "reader.h"
+#include "symtab.h"
+
+/* NITEMSET is the size of the array ITEMSET. */
+item_number *itemset;
+size_t nitemset;
+
+static bitset ruleset;
+
+/* internal data. See comments before set_fderives and set_firsts. */
+static bitsetv fderives = NULL;
+static bitsetv firsts = NULL;
+
+/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
+#define FDERIVES(Var) fderives[(Var) - ntokens]
+#define FIRSTS(Var) firsts[(Var) - ntokens]
+
+
+/*-----------------.
+| Debugging code. |
+`-----------------*/
+
+static void
+print_closure (char const *title, item_number const *array, size_t size)
+{
+ size_t i;
+ fprintf (stderr, "Closure: %s\n", title);
+ for (i = 0; i < size; ++i)
+ {
+ item_number *rp;
+ fprintf (stderr, " %2d: .", array[i]);
+ for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
+ fprintf (stderr, " %s", symbols[*rp]->tag);
+ fprintf (stderr, " (rule %d)\n", -*rp - 1);
+ }
+ fputs ("\n\n", stderr);
+}
+
+
+static void
+print_firsts (void)
+{
+ symbol_number i, j;
+
+ fprintf (stderr, "FIRSTS\n");
+ for (i = ntokens; i < nsyms; i++)
+ {
+ bitset_iterator iter;
+ fprintf (stderr, " %s firsts\n", symbols[i]->tag);
+ BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
+ fprintf (stderr, " %s\n", symbols[j + ntokens]->tag);
+ }
+ fprintf (stderr, "\n\n");
+}
+
+
+static void
+print_fderives (void)
+{
+ int i;
+ rule_number r;
+
+ fprintf (stderr, "FDERIVES\n");
+ for (i = ntokens; i < nsyms; i++)
+ {
+ bitset_iterator iter;
+ fprintf (stderr, " %s derives\n", symbols[i]->tag);
+ BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
+ {
+ fprintf (stderr, " %3d ", r);
+ rule_rhs_print (&rules[r], stderr);
+ fprintf (stderr, "\n");
+ }
+ }
+ fprintf (stderr, "\n\n");
+}
+
+/*------------------------------------------------------------------.
+| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
+| items can represent the beginning of the input corresponding to |
+| which other items. |
+| |
+| For example, if some rule expands symbol 5 into the sequence of |
+| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
+| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
+| (5)) is set. |
+`------------------------------------------------------------------*/
+
+static void
+set_firsts (void)
+{
+ symbol_number i, j;
+
+ firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
+
+ for (i = ntokens; i < nsyms; i++)
+ for (j = 0; derives[i - ntokens][j]; ++j)
+ {
+ item_number sym = derives[i - ntokens][j]->rhs[0];
+ if (ISVAR (sym))
+ bitset_set (FIRSTS (i), sym - ntokens);
+ }
+
+ if (trace_flag & trace_sets)
+ bitsetv_matrix_dump (stderr, "RTC: Firsts Input", firsts);
+ bitsetv_reflexive_transitive_closure (firsts);
+ if (trace_flag & trace_sets)
+ bitsetv_matrix_dump (stderr, "RTC: Firsts Output", firsts);
+
+ if (trace_flag & trace_sets)
+ print_firsts ();
+}
+
+/*-------------------------------------------------------------------.
+| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
+| rules can help derive the beginning of the data for each |
+| nonterminal. |
+| |
+| For example, if symbol 5 can be derived as the sequence of symbols |
+| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
+| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
+`-------------------------------------------------------------------*/
+
+static void
+set_fderives (void)
+{
+ symbol_number i, j;
+ rule_number k;
+
+ fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
+
+ set_firsts ();
+
+ for (i = ntokens; i < nsyms; ++i)
+ for (j = ntokens; j < nsyms; ++j)
+ if (bitset_test (FIRSTS (i), j - ntokens))
+ for (k = 0; derives[j - ntokens][k]; ++k)
+ bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
+
+ if (trace_flag & trace_sets)
+ print_fderives ();
+
+ bitsetv_free (firsts);
+}
+
+
+
+void
+new_closure (unsigned int n)
+{
+ itemset = xnmalloc (n, sizeof *itemset);
+
+ ruleset = bitset_create (nrules, BITSET_FIXED);
+
+ set_fderives ();
+}
+
+
+
+void
+closure (item_number const *core, size_t n)
+{
+ /* Index over CORE. */
+ size_t c;
+
+ /* A bit index over RULESET. */
+ rule_number ruleno;
+
+ bitset_iterator iter;
+
+ if (trace_flag & trace_sets)
+ print_closure ("input", core, n);
+
+ bitset_zero (ruleset);
+
+ for (c = 0; c < n; ++c)
+ if (ISVAR (ritem[core[c]]))
+ bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
+
+ /* 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[nitemset] = core[c];
+ nitemset++;
+ c++;
+ }
+ itemset[nitemset] = itemno;
+ nitemset++;
+ };
+
+ while (c < n)
+ {
+ itemset[nitemset] = core[c];
+ nitemset++;
+ c++;
+ }
+
+ if (trace_flag & trace_sets)
+ print_closure ("output", itemset, nitemset);
+}
+
+
+void
+free_closure (void)
+{
+ free (itemset);
+ bitset_free (ruleset);
+ bitsetv_free (fderives);
+}
diff --git a/contrib/tools/bison/src/closure.h b/contrib/tools/bison/src/closure.h
new file mode 100644
index 0000000000..ad4a3ba96b
--- /dev/null
+++ b/contrib/tools/bison/src/closure.h
@@ -0,0 +1,57 @@
+/* Subroutines for bison
+
+ Copyright (C) 1984, 1989, 2000-2002, 2007, 2009-2013 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 CLOSURE_H_
+# define CLOSURE_H_
+
+# include "gram.h"
+
+/* Allocates the itemset and ruleset vectors, and precomputes useful
+ data so that closure can be called. n is the number of elements to
+ allocate for itemset. */
+
+void new_closure (unsigned int n);
+
+
+/* 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.
+
+ RULESET contains a bit for each rule. CLOSURE sets the bits for
+ all rules which could potentially describe the next input to be
+ read.
+
+ 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. */
+
+void closure (item_number const *items, size_t n);
+
+
+/* Frees ITEMSET, RULESET and internal data. */
+
+void free_closure (void);
+
+extern item_number *itemset;
+extern size_t nitemset;
+
+#endif /* !CLOSURE_H_ */
diff --git a/contrib/tools/bison/src/complain.c b/contrib/tools/bison/src/complain.c
new file mode 100644
index 0000000000..fdc4b5426b
--- /dev/null
+++ b/contrib/tools/bison/src/complain.c
@@ -0,0 +1,379 @@
+/* Declaration for error-reporting function for Bison.
+
+ Copyright (C) 2000-2002, 2004-2006, 2009-2013 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/>. */
+
+/* Based on error.c and error.h,
+ written by David MacKenzie <djm@gnu.ai.mit.edu>. */
+
+#include <config.h>
+#include "system.h"
+
+#include <argmatch.h>
+#include <stdarg.h>
+#include <progname.h>
+
+#include "complain.h"
+#include "files.h"
+#include "getargs.h"
+#include "quote.h"
+
+err_status complaint_status = status_none;
+
+bool warnings_are_errors = false;
+
+/** Diagnostics severity. */
+typedef enum
+ {
+ severity_disabled = 0,
+ severity_unset = 1,
+ severity_warning = 2,
+ severity_error = 3,
+ severity_fatal = 4
+ } severity;
+
+
+/** For each warning type, its severity. */
+static severity warnings_flag[warnings_size];
+
+static unsigned *indent_ptr = 0;
+
+/*------------------------.
+| --warnings's handling. |
+`------------------------*/
+
+static const char * const warnings_args[] =
+{
+ "none",
+ "midrule-values",
+ "yacc",
+ "conflicts-sr",
+ "conflicts-rr",
+ "deprecated",
+ "empty-rule",
+ "precedence",
+ "other",
+ "all",
+ "error",
+ "everything",
+ 0
+};
+
+static const int warnings_types[] =
+{
+ Wnone,
+ Wmidrule_values,
+ Wyacc,
+ Wconflicts_sr,
+ Wconflicts_rr,
+ Wdeprecated,
+ Wempty_rule,
+ Wprecedence,
+ Wother,
+ Wall,
+ Werror,
+ Weverything
+};
+
+ARGMATCH_VERIFY (warnings_args, warnings_types);
+
+void
+warning_argmatch (char const *arg, size_t no, size_t err)
+{
+ int value = XARGMATCH ("--warning", arg + no + err,
+ warnings_args, warnings_types);
+
+ /* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
+ if (!value)
+ {
+ value = Weverything;
+ no = !no;
+ }
+
+ if (no)
+ {
+ size_t b;
+ for (b = 0; b < warnings_size; ++b)
+ if (value & 1 << b)
+ {
+ if (err)
+ {
+ /* -Wno-error=foo: if foo enabled as an error,
+ make it a warning. */
+ if (warnings_flag[b] == severity_error)
+ warnings_flag[b] = severity_warning;
+ }
+ else
+ /* -Wno-foo. */
+ warnings_flag[b] = severity_disabled;
+ }
+ }
+ else
+ {
+ size_t b;
+ for (b = 0; b < warnings_size; ++b)
+ if (value & 1 << b)
+ /* -Wfoo and -Werror=foo. */
+ warnings_flag[b] = err ? severity_error : severity_warning;
+ }
+}
+
+/** Decode a comma-separated list of arguments from -W.
+ *
+ * \param args comma separated list of effective subarguments to decode.
+ * If 0, then activate all the flags.
+ */
+
+void
+warnings_argmatch (char *args)
+{
+ if (args)
+ for (args = strtok (args, ","); args; args = strtok (NULL, ","))
+ if (STREQ (args, "error"))
+ warnings_are_errors = true;
+ else if (STREQ (args, "no-error"))
+ {
+ warnings_are_errors = false;
+ warning_argmatch ("no-error=everything", 3, 6);
+ }
+ else
+ {
+ size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
+ size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
+
+ warning_argmatch (args, no, err);
+ }
+ else
+ warning_argmatch ("all", 0, 0);
+}
+
+
+/*-----------.
+| complain. |
+`-----------*/
+
+void
+complain_init (void)
+{
+ warnings warnings_default =
+ Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
+
+ size_t b;
+ for (b = 0; b < warnings_size; ++b)
+ warnings_flag[b] = (1 << b & warnings_default
+ ? severity_warning
+ : severity_unset);
+}
+
+static severity
+warning_severity (warnings flags)
+{
+ if (flags & fatal)
+ return severity_fatal;
+ else if (flags & complaint)
+ return severity_error;
+ else
+ {
+ severity res = severity_disabled;
+ size_t b;
+ for (b = 0; b < warnings_size; ++b)
+ if (flags & 1 << b)
+ res = res < warnings_flag[b] ? warnings_flag[b] : res;
+ if (res == severity_warning && warnings_are_errors)
+ res = severity_error;
+ return res;
+ }
+}
+
+bool
+warning_is_unset (warnings flags)
+{
+ size_t b;
+ for (b = 0; b < warnings_size; ++b)
+ if (flags & 1 << b && warnings_flag[b] != severity_unset)
+ return false;
+ return true;
+}
+
+/** Display a "[-Wyacc]" like message on \a f. */
+
+static void
+warnings_print_categories (warnings warn_flags, FILE *f)
+{
+ /* Display only the first match, the second is "-Wall". */
+ size_t i;
+ for (i = 0; warnings_args[i]; ++i)
+ if (warn_flags & warnings_types[i])
+ {
+ severity s = warning_severity (warnings_types[i]);
+ fprintf (f, " [-W%s%s]",
+ s == severity_error ? "error=" : "",
+ warnings_args[i]);
+ return;
+ }
+}
+
+/** Report an error message.
+ *
+ * \param loc the location, defaulting to the current file,
+ * or the program name.
+ * \param flags the category for this message.
+ * \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 (const location *loc, warnings flags, const char *prefix,
+ const char *message, va_list args)
+{
+ unsigned pos = 0;
+
+ if (loc)
+ pos += location_print (*loc, stderr);
+ else
+ pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
+ pos += fprintf (stderr, ": ");
+
+ if (indent_ptr)
+ {
+ if (*indent_ptr)
+ prefix = NULL;
+ 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);
+ if (! (flags & silent))
+ warnings_print_categories (flags, stderr);
+ {
+ 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 && !(flags & no_caret))
+ location_caret (*loc, stderr);
+ }
+ }
+ fflush (stderr);
+}
+
+/** Raise a complaint. That can be a fatal error, an error or just a
+ warning. */
+
+static void
+complains (const location *loc, warnings flags, const char *message,
+ va_list args)
+{
+ severity s = warning_severity (flags);
+ if ((flags & complaint) && complaint_status < status_complaint)
+ complaint_status = status_complaint;
+
+ if (severity_warning <= s)
+ {
+ const char* prefix =
+ s == severity_fatal ? _("fatal error")
+ : s == severity_error ? _("error")
+ : _("warning");
+ if (severity_error <= s && ! complaint_status)
+ complaint_status = status_warning_as_error;
+ error_message (loc, flags, prefix, message, args);
+ }
+
+ if (flags & fatal)
+ exit (EXIT_FAILURE);
+}
+
+void
+complain (location const *loc, warnings flags, const char *message, ...)
+{
+ va_list args;
+ va_start (args, message);
+ complains (loc, flags, message, args);
+ va_end (args);
+}
+
+void
+complain_indent (location const *loc, warnings flags, unsigned *indent,
+ const char *message, ...)
+{
+ va_list args;
+ indent_ptr = indent;
+ va_start (args, message);
+ complains (loc, flags, message, args);
+ va_end (args);
+}
+
+void
+complain_args (location const *loc, warnings w, unsigned *indent,
+ int argc, char *argv[])
+{
+ switch (argc)
+ {
+ case 1:
+ complain_indent (loc, w, indent, "%s", _(argv[0]));
+ break;
+ case 2:
+ complain_indent (loc, w, indent, _(argv[0]), argv[1]);
+ break;
+ case 3:
+ complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2]);
+ break;
+ case 4:
+ complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2], argv[3]);
+ break;
+ case 5:
+ complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2], argv[3],
+ argv[4]);
+ break;
+ default:
+ complain (loc, fatal, "too many arguments for complains");
+ break;
+ }
+}
+
+void
+deprecated_directive (location const *loc, char const *old, char const *upd)
+{
+ if (feature_flag & feature_caret)
+ complain (loc, Wdeprecated,
+ _("deprecated directive, use %s"),
+ quote_n (1, upd));
+ else
+ complain (loc, Wdeprecated,
+ _("deprecated directive: %s, use %s"),
+ quote (old), quote_n (1, upd));
+}
+
+void
+duplicate_directive (char const *directive,
+ location first, location second)
+{
+ unsigned i = 0;
+ complain (&second, complaint, _("only one %s allowed per rule"), directive);
+ i += SUB_INDENT;
+ complain_indent (&first, complaint, &i, _("previous declaration"));
+}
diff --git a/contrib/tools/bison/src/complain.h b/contrib/tools/bison/src/complain.h
new file mode 100644
index 0000000000..0d81503df7
--- /dev/null
+++ b/contrib/tools/bison/src/complain.h
@@ -0,0 +1,144 @@
+/* Declaration for error-reporting function for Bison.
+
+ Copyright (C) 2000-2002, 2006, 2009-2013 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/>. */
+
+#ifndef COMPLAIN_H_
+# define COMPLAIN_H_ 1
+
+# include "location.h"
+
+/* Sub-messages indent. */
+# define SUB_INDENT (4)
+
+/*-------------.
+| --warnings. |
+`-------------*/
+
+/** The bits assigned to each warning type. */
+typedef enum
+ {
+ warning_midrule_values, /**< Unset or unused midrule values. */
+ warning_yacc, /**< POSIXME. */
+ warning_conflicts_sr, /**< S/R conflicts. */
+ warning_conflicts_rr, /**< R/R conflicts. */
+ warning_empty_rule, /**< Implicitly empty rules. */
+ warning_deprecated, /**< Obsolete constructs. */
+ warning_precedence, /**< Useless precedence and associativity. */
+ warning_other, /**< All other warnings. */
+
+ warnings_size /**< The number of warnings. Must be last. */
+ } warning_bit;
+
+/** Whether -Werror was set. */
+extern bool warnings_are_errors;
+
+/** Decode a single argument from -W.
+ *
+ * \param arg the subarguments to decode.
+ * If null, then activate all the flags.
+ * \param no length of the potential "no-" prefix.
+ * Can be 0 or 3. If 3, negate the action of the subargument.
+ * \param err length of a potential "error=".
+ * Can be 0 or 6. If 6, treat the subargument as a CATEGORY.
+ *
+ * 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.
+ */
+void warning_argmatch (char const *arg, size_t no, size_t err);
+
+/** Decode a comma-separated list of arguments from -W.
+ *
+ * \param args comma separated list of effective subarguments to decode.
+ * If 0, then activate all the flags.
+ */
+void warnings_argmatch (char *args);
+
+
+/*-----------.
+| complain. |
+`-----------*/
+
+/** Initialize this module. */
+void complain_init (void);
+
+typedef enum
+ {
+ /**< Issue no warnings. */
+ Wnone = 0,
+
+ Wmidrule_values = 1 << warning_midrule_values,
+ Wyacc = 1 << warning_yacc,
+ Wconflicts_sr = 1 << warning_conflicts_sr,
+ Wconflicts_rr = 1 << warning_conflicts_rr,
+ Wdeprecated = 1 << warning_deprecated,
+ Wempty_rule = 1 << warning_empty_rule,
+ Wprecedence = 1 << warning_precedence,
+ Wother = 1 << warning_other,
+
+ Werror = 1 << 10, /** This bit is no longer used. */
+
+ complaint = 1 << 11, /**< All complaints. */
+ fatal = 1 << 12, /**< All fatal errors. */
+ silent = 1 << 13, /**< Do not display the warning type. */
+ no_caret = 1 << 14, /**< Do not display caret location. */
+
+ /**< All above warnings. */
+ Weverything = ~complaint & ~fatal & ~silent,
+ Wall = Weverything & ~Wyacc
+ } warnings;
+
+/** Whether the warnings of \a flags are all unset.
+ (Never enabled, never disabled). */
+bool warning_is_unset (warnings flags);
+
+/** Make a complaint, with maybe a location. */
+void complain (location const *loc, warnings flags, char const *message, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+
+/** Likewise, but with an \a argc/argv interface. */
+void complain_args (location const *loc, warnings w, unsigned *indent,
+ int argc, char *arg[]);
+
+/** Make a complaint with location and some indentation. */
+void complain_indent (location const *loc, warnings flags, unsigned *indent,
+ char const *message, ...)
+ __attribute__ ((__format__ (__printf__, 4, 5)));
+
+
+/** Report an obsolete syntax, suggest the updated one. */
+void deprecated_directive (location const *loc,
+ char const *obsolete, char const *updated);
+
+/** Report a repeated directive for a rule. */
+void duplicate_directive (char const *directive,
+ location first, location second);
+
+/** Warnings treated as errors shouldn't stop the execution as regular errors
+ should (because due to their nature, it is safe to go on). Thus, there are
+ three possible execution statuses. */
+typedef enum
+ {
+ status_none,
+ status_warning_as_error,
+ status_complaint
+ } err_status;
+
+/** Whether an error was reported. */
+extern err_status complaint_status;
+
+#endif /* !COMPLAIN_H_ */
diff --git a/contrib/tools/bison/src/conflicts.c b/contrib/tools/bison/src/conflicts.c
new file mode 100644
index 0000000000..1840473620
--- /dev/null
+++ b/contrib/tools/bison/src/conflicts.c
@@ -0,0 +1,629 @@
+/* Find and resolve or report lookahead conflicts for bison,
+
+ Copyright (C) 1984, 1989, 1992, 2000-2013 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 <bitset.h>
+
+#include "LR0.h"
+#include "complain.h"
+#include "conflicts.h"
+#include "files.h"
+#include "getargs.h"
+#include "gram.h"
+#include "lalr.h"
+#include "print-xml.h"
+#include "reader.h"
+#include "state.h"
+#include "symtab.h"
+
+/* -1 stands for not specified. */
+int expected_sr_conflicts = -1;
+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 lookahead_set;
+
+
+
+enum conflict_resolution
+ {
+ shift_resolution,
+ reduce_resolution,
+ left_resolution,
+ right_resolution,
+ nonassoc_resolution
+ };
+
+
+/*----------------------------------------------------------------.
+| Explain how an SR conflict between TOKEN and RULE was resolved: |
+| RESOLUTION. |
+`----------------------------------------------------------------*/
+
+static inline void
+log_resolution (rule *r, symbol_number token,
+ enum conflict_resolution resolution)
+{
+ if (report_flag & report_solved_conflicts)
+ {
+ /* The description of the resolution. */
+ switch (resolution)
+ {
+ case shift_resolution:
+ case right_resolution:
+ 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_printf (&solved_conflicts_obstack,
+ _(" Conflict between rule %d and token %s"
+ " resolved as reduce"),
+ r->number,
+ symbols[token]->tag);
+ break;
+
+ case nonassoc_resolution:
+ obstack_printf (&solved_conflicts_obstack,
+ _(" Conflict between rule %d and token %s"
+ " resolved as an error"),
+ r->number,
+ symbols[token]->tag);
+ break;
+ }
+
+ /* The reason. */
+ switch (resolution)
+ {
+ case shift_resolution:
+ obstack_printf (&solved_conflicts_obstack,
+ " (%s < %s)",
+ r->prec->tag,
+ symbols[token]->tag);
+ break;
+
+ case reduce_resolution:
+ obstack_printf (&solved_conflicts_obstack,
+ " (%s < %s)",
+ symbols[token]->tag,
+ r->prec->tag);
+ break;
+
+ case left_resolution:
+ obstack_printf (&solved_conflicts_obstack,
+ " (%%left %s)",
+ symbols[token]->tag);
+ break;
+
+ case right_resolution:
+ obstack_printf (&solved_conflicts_obstack,
+ " (%%right %s)",
+ symbols[token]->tag);
+ break;
+
+ case nonassoc_resolution:
+ 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 or as an error (%nonassoc). |
+`------------------------------------------------------------------*/
+
+static void
+flush_shift (state *s, int token)
+{
+ transitions *trans = s->transitions;
+ int i;
+
+ bitset_reset (lookahead_set, token);
+ for (i = 0; i < trans->num; i++)
+ if (!TRANSITION_IS_DISABLED (trans, i)
+ && TRANSITION_SYMBOL (trans, i) == token)
+ TRANSITION_DISABLE (trans, i);
+}
+
+
+/*--------------------------------------------------------------------.
+| 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 lookahead_tokens, int token)
+{
+ bitset_reset (lookahead_tokens, token);
+}
+
+
+/*------------------------------------------------------------------.
+| Attempt to resolve shift-reduce conflict for one rule by means of |
+| precedence declarations. It has already been checked that the |
+| 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 lookahead bitset to consider. |
+| |
+| ERRORS and NERRS can be used to store discovered explicit |
+| errors. |
+`------------------------------------------------------------------*/
+
+static void
+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 lookahead_tokens = reds->lookahead_tokens[ruleno];
+
+ for (i = 0; i < ntokens; i++)
+ if (bitset_test (lookahead_tokens, i)
+ && bitset_test (lookahead_set, i)
+ && symbols[i]->prec)
+ {
+ /* Shift-reduce conflict occurs for token number i
+ and it has a precedence.
+ The precedence of shifting is that of token i. */
+ if (symbols[i]->prec < redprec)
+ {
+ register_precedence (redrule->prec->number, i);
+ log_resolution (redrule, i, reduce_resolution);
+ flush_shift (s, i);
+ }
+ else if (symbols[i]->prec > redprec)
+ {
+ register_precedence (i, redrule->prec->number);
+ log_resolution (redrule, i, shift_resolution);
+ flush_reduce (lookahead_tokens, i);
+ }
+ else
+ /* Matching precedence levels.
+ For non-defined associativity, keep both: unexpected
+ associativity conflict.
+ For left associativity, keep only the reduction.
+ For right associativity, keep only the shift.
+ For nonassociativity, keep neither. */
+
+ switch (symbols[i]->assoc)
+ {
+ case undef_assoc:
+ abort ();
+
+ case precedence_assoc:
+ break;
+
+ case right_assoc:
+ register_assoc (i, redrule->prec->number);
+ log_resolution (redrule, i, right_resolution);
+ flush_reduce (lookahead_tokens, i);
+ break;
+
+ case left_assoc:
+ register_assoc (i, redrule->prec->number);
+ log_resolution (redrule, i, left_resolution);
+ flush_shift (s, i);
+ break;
+
+ case non_assoc:
+ register_assoc (i, redrule->prec->number);
+ log_resolution (redrule, i, nonassoc_resolution);
+ flush_shift (s, i);
+ flush_reduce (lookahead_tokens, i);
+ /* Record an explicit error for this token. */
+ errors[(*nerrs)++] = symbols[i];
+ break;
+ }
+ }
+}
+
+
+/*-------------------------------------------------------------------.
+| 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 |
+| lookahead tokens on which S raises a syntax error (%nonassoc). |
+`-------------------------------------------------------------------*/
+
+static void
+set_conflicts (state *s, symbol **errors)
+{
+ int i;
+ transitions *trans = s->transitions;
+ reductions *reds = s->reductions;
+ int nerrs = 0;
+
+ if (s->consistent)
+ return;
+
+ bitset_zero (lookahead_set);
+
+ FOR_EACH_SHIFT (trans, i)
+ bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
+
+ /* 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->lookahead_tokens[i], lookahead_set))
+ resolve_sr_conflict (s, i, errors, &nerrs);
+
+ 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))
+ s->solved_conflicts = obstack_finish0 (&solved_conflicts_obstack);
+ if (obstack_object_size (&solved_conflicts_xml_obstack))
+ s->solved_conflicts_xml = obstack_finish0 (&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->lookahead_tokens[i], lookahead_set))
+ conflicts[s->number] = 1;
+ bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
+ }
+}
+
+
+/*----------------------------------------------------------------.
+| Solve all the S/R conflicts using the precedence/associativity, |
+| and flag as inconsistent the states that still have conflicts. |
+`----------------------------------------------------------------*/
+
+void
+conflicts_solve (void)
+{
+ state_number i;
+ /* 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);
+ lookahead_set = bitset_create (ntokens, BITSET_FIXED);
+ obstack_init (&solved_conflicts_obstack);
+ obstack_init (&solved_conflicts_xml_obstack);
+
+ for (i = 0; i < nstates; i++)
+ {
+ set_conflicts (states[i], errors);
+
+ /* For uniformity of the code, make sure all the states have a valid
+ 'errs' member. */
+ if (!states[i]->errs)
+ states[i]->errs = errs_new (0, 0);
+ }
+
+ free (errors);
+}
+
+
+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. |
+`---------------------------------------------*/
+
+static size_t
+count_state_sr_conflicts (state *s)
+{
+ int i;
+ transitions *trans = s->transitions;
+ reductions *reds = s->reductions;
+
+ if (!trans)
+ return 0;
+
+ 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 (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
+
+ bitset_and (lookahead_set, lookahead_set, shift_set);
+
+ return bitset_count (lookahead_set);
+}
+
+/*---------------------------------------------.
+| The total number of shift/reduce conflicts. |
+`---------------------------------------------*/
+
+static size_t
+count_sr_conflicts (void)
+{
+ size_t res = 0;
+ state_number i;
+
+ /* Conflicts by state. */
+ for (i = 0; i < nstates; i++)
+ if (conflicts[i])
+ res += count_state_sr_conflicts (states[i]);
+ return res;
+}
+
+
+
+/*----------------------------------------------------------------.
+| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
+| count one conflict for each token that has any reduce/reduce |
+| conflicts. Otherwise, count one conflict for each pair of |
+| conflicting reductions. |
+`----------------------------------------------------------------*/
+
+static size_t
+count_state_rr_conflicts (state *s, bool one_per_token)
+{
+ int i;
+ reductions *reds = s->reductions;
+ size_t res = 0;
+
+ for (i = 0; i < ntokens; i++)
+ {
+ int count = 0;
+ int j;
+ for (j = 0; j < reds->num; ++j)
+ count += bitset_test (reds->lookahead_tokens[j], i);
+ if (count >= 2)
+ res += one_per_token ? 1 : count-1;
+ }
+
+ return res;
+}
+
+static size_t
+count_rr_conflicts (bool one_per_token)
+{
+ size_t res = 0;
+ state_number i;
+
+ /* Conflicts by state. */
+ for (i = 0; i < nstates; i++)
+ if (conflicts[i])
+ res += count_state_rr_conflicts (states[i], one_per_token);
+ return res;
+}
+
+
+/*-----------------------------------------------------------.
+| Output the detailed description of states with conflicts. |
+`-----------------------------------------------------------*/
+
+void
+conflicts_output (FILE *out)
+{
+ bool printed_sth = false;
+ state_number i;
+ for (i = 0; i < nstates; i++)
+ {
+ state *s = states[i];
+ if (conflicts[i])
+ {
+ int src = count_state_sr_conflicts (s);
+ int rrc = count_state_rr_conflicts (s, true);
+ fprintf (out, _("State %d "), i);
+ if (src && rrc)
+ fprintf (out,
+ _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
+ src, rrc);
+ else if (src)
+ fprintf (out, _("conflicts: %d shift/reduce\n"), src);
+ else if (rrc)
+ fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
+ printed_sth = true;
+ }
+ }
+ if (printed_sth)
+ fputs ("\n\n", out);
+}
+
+/*--------------------------------------------------------.
+| 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 lookahead as one |
+| conflict. |
+`--------------------------------------------------------*/
+
+int
+conflicts_total_count (void)
+{
+ return count_sr_conflicts () + count_rr_conflicts (false);
+}
+
+
+/*------------------------------------------.
+| Reporting the total number of conflicts. |
+`------------------------------------------*/
+
+void
+conflicts_print (void)
+{
+ if (! glr_parser && expected_rr_conflicts != -1)
+ {
+ complain (NULL, Wother, _("%%expect-rr applies only to GLR parsers"));
+ expected_rr_conflicts = -1;
+ }
+
+ /* Screams for factoring, but almost useless because of the
+ different strings to translate. */
+ {
+ int total = count_sr_conflicts ();
+ /* If %expect is not used, but %expect-rr is, then expect 0 sr. */
+ int expected =
+ (expected_sr_conflicts == -1 && expected_rr_conflicts != -1)
+ ? 0
+ : expected_sr_conflicts;
+ if (expected != -1)
+ {
+ if (expected != total)
+ complain (NULL, complaint,
+ _("shift/reduce conflicts: %d found, %d expected"),
+ total, expected);
+ }
+ else if (total)
+ complain (NULL, Wconflicts_sr,
+ ngettext ("%d shift/reduce conflict",
+ "%d shift/reduce conflicts",
+ total),
+ total);
+ }
+
+ {
+ int total = count_rr_conflicts (true);
+ /* If %expect-rr is not used, but %expect is, then expect 0 rr. */
+ int expected =
+ (expected_rr_conflicts == -1 && expected_sr_conflicts != -1)
+ ? 0
+ : expected_rr_conflicts;
+ if (expected != -1)
+ {
+ if (expected != total)
+ complain (NULL, complaint,
+ _("reduce/reduce conflicts: %d found, %d expected"),
+ total, expected);
+ }
+ else if (total)
+ complain (NULL, Wconflicts_rr,
+ ngettext ("%d reduce/reduce conflict",
+ "%d reduce/reduce conflicts",
+ total),
+ total);
+ }
+}
+
+
+void
+conflicts_free (void)
+{
+ free (conflicts);
+ bitset_free (shift_set);
+ bitset_free (lookahead_set);
+ obstack_free (&solved_conflicts_obstack, NULL);
+ obstack_free (&solved_conflicts_xml_obstack, NULL);
+}
diff --git a/contrib/tools/bison/src/conflicts.h b/contrib/tools/bison/src/conflicts.h
new file mode 100644
index 0000000000..5df5787162
--- /dev/null
+++ b/contrib/tools/bison/src/conflicts.h
@@ -0,0 +1,47 @@
+/* Find and resolve or report lookahead conflicts for bison,
+
+ Copyright (C) 2000-2002, 2004, 2007, 2009-2013 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 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);
+void conflicts_free (void);
+
+/* Were there conflicts? */
+extern int expected_sr_conflicts;
+extern int expected_rr_conflicts;
+#endif /* !CONFLICTS_H_ */
diff --git a/contrib/tools/bison/src/derives.c b/contrib/tools/bison/src/derives.c
new file mode 100644
index 0000000000..c834f0b0d0
--- /dev/null
+++ b/contrib/tools/bison/src/derives.c
@@ -0,0 +1,120 @@
+/* Match rules with nonterminals for bison,
+
+ Copyright (C) 1984, 1989, 2000-2003, 2005, 2009-2013 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 "getargs.h"
+
+#include "derives.h"
+#include "gram.h"
+#include "reader.h"
+#include "symtab.h"
+
+/* Linked list of rule numbers. */
+typedef struct rule_list
+{
+ struct rule_list *next;
+ rule *value;
+} rule_list;
+
+rule ***derives;
+
+static void
+print_derives (void)
+{
+ int i;
+
+ fputs ("DERIVES\n", stderr);
+
+ for (i = ntokens; i < nsyms; i++)
+ {
+ rule **rp;
+ fprintf (stderr, " %s derives\n", symbols[i]->tag);
+ for (rp = derives[i - ntokens]; *rp; ++rp)
+ {
+ fprintf (stderr, " %3d ", (*rp)->user_number);
+ rule_rhs_print (*rp, stderr);
+ fprintf (stderr, "\n");
+ }
+ }
+
+ fputs ("\n\n", stderr);
+}
+
+
+void
+derives_compute (void)
+{
+ symbol_number i;
+ rule_number r;
+ rule **q;
+
+ /* DSET[NTERM - NTOKENS] -- A linked list of the numbers of the rules
+ whose LHS is NTERM. */
+ rule_list **dset = xcalloc (nvars, sizeof *dset);
+
+ /* DELTS[RULE] -- There are NRULES rule number to attach to nterms.
+ Instead of performing NRULES allocations for each, have an array
+ indexed by rule numbers. */
+ rule_list *delts = xnmalloc (nrules, sizeof *delts);
+
+ for (r = nrules - 1; r >= 0; --r)
+ {
+ symbol_number lhs = rules[r].lhs->number;
+ rule_list *p = &delts[r];
+ /* A new LHS is found. */
+ p->next = dset[lhs - ntokens];
+ p->value = &rules[r];
+ dset[lhs - ntokens] = p;
+ }
+
+ /* DSET contains what we need under the form of a linked list. Make
+ it a single array. */
+
+ derives = xnmalloc (nvars, sizeof *derives);
+ q = xnmalloc (nvars + nrules, sizeof *q);
+
+ for (i = ntokens; i < nsyms; i++)
+ {
+ rule_list *p = dset[i - ntokens];
+ derives[i - ntokens] = q;
+ while (p)
+ {
+ *q++ = p->value;
+ p = p->next;
+ }
+ *q++ = NULL;
+ }
+
+ if (trace_flag & trace_sets)
+ print_derives ();
+
+ free (dset);
+ free (delts);
+}
+
+
+void
+derives_free (void)
+{
+ free (derives[0]);
+ free (derives);
+}
diff --git a/contrib/tools/bison/src/derives.h b/contrib/tools/bison/src/derives.h
new file mode 100644
index 0000000000..ea8dff7231
--- /dev/null
+++ b/contrib/tools/bison/src/derives.h
@@ -0,0 +1,35 @@
+/* Match rules with nonterminals for bison,
+
+ Copyright (C) 1984, 1989, 2000-2002, 2009-2013 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 DERIVES_H_
+# define DERIVES_H_
+
+# include "gram.h"
+
+/* DERIVES[SYMBOL - NTOKENS] points to a vector of the rules that
+ SYMBOL derives, terminated with NULL. */
+extern rule ***derives;
+
+/* Compute DERIVES. */
+
+void derives_compute (void);
+void derives_free (void);
+
+#endif /* !DERIVES_H_ */
diff --git a/contrib/tools/bison/src/files.c b/contrib/tools/bison/src/files.c
new file mode 100644
index 0000000000..3b219229bc
--- /dev/null
+++ b/contrib/tools/bison/src/files.c
@@ -0,0 +1,420 @@
+/* Open and close files for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 2000-2013 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 <error.h>
+#include <dirname.h>
+#include <get-errno.h>
+#include <quote.h>
+#include <quotearg.h>
+#include <stdio-safer.h>
+#include <xstrndup.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "complain.h"
+#include "files.h"
+#include "getargs.h"
+#include "gram.h"
+
+/* 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
+ %directive vs --option leaves precedence to the options by deciding
+ that if a %directive sets a variable which is really set (i.e., not
+ NULL), then the %directive is ignored. As a result, %name-prefix,
+ for instance, will not be honored. */
+
+char const *spec_outfile = NULL; /* for -o. */
+char const *spec_file_prefix = NULL; /* for -b. */
+char const *spec_name_prefix = NULL; /* for -p. */
+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;
+
+/* If --output=dir/foo.c was specified,
+ DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
+
+ If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
+ ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
+
+ If --output was not specified but --file-prefix=dir/foo was specified,
+ ALL_BUT_EXT = 'foo.tab' and ALL_BUT_TAB_EXT = 'foo'.
+
+ If neither --output nor --file was specified but the input grammar
+ is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'foo'.
+
+ If neither --output nor --file was specified, DIR_PREFIX is the
+ empty string (meaning the current directory); otherwise it is
+ 'dir/'. */
+
+char *all_but_ext;
+static char *all_but_tab_ext;
+char *dir_prefix;
+
+/* C source file extension (the parser source). */
+static char *src_extension = NULL;
+/* Header file extension (if option '`-d'' is specified). */
+static char *header_extension = NULL;
+
+/*-----------------------------------------------------------------.
+| Return a newly allocated string composed of the concatenation of |
+| STR1, and STR2. |
+`-----------------------------------------------------------------*/
+
+#if defined _win_ || defined _WIN64 || defined _WIN32 || defined __WIN32__
+char *stpcpy(char *dst, const char *src);
+#endif
+
+static char *
+concat2 (char const *str1, char const *str2)
+{
+ size_t len = strlen (str1) + strlen (str2);
+ char *res = xmalloc (len + 1);
+ char *cp;
+ cp = stpcpy (res, str1);
+ cp = stpcpy (cp, str2);
+ return res;
+}
+
+/*-----------------------------------------------------------------.
+| Try to open file NAME with mode MODE, and print an error message |
+| if fails. |
+`-----------------------------------------------------------------*/
+
+FILE *
+xfopen (const char *name, const char *mode)
+{
+ FILE *ptr;
+
+ ptr = fopen_safer (name, mode);
+ if (!ptr)
+ error (EXIT_FAILURE, get_errno (),
+ _("%s: cannot open"), quotearg_colon (name));
+
+ return ptr;
+}
+
+/*-------------------------------------------------------------.
+| Try to close file PTR, and print an error message if fails. |
+`-------------------------------------------------------------*/
+
+void
+xfclose (FILE *ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ if (ferror (ptr))
+ error (EXIT_FAILURE, 0, _("input/output error"));
+
+ if (fclose (ptr) != 0)
+ error (EXIT_FAILURE, get_errno (), _("cannot close file"));
+}
+
+
+FILE *
+xfdopen (int fd, char const *mode)
+{
+ FILE *res = fdopen (fd, mode);
+ if (! res)
+ error (EXIT_FAILURE, get_errno (),
+ /* On a separate line to please the "unmarked_diagnostics"
+ syntax-check. */
+ "fdopen");
+ return res;
+}
+
+/*------------------------------------------------------------------.
+| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
+`------------------------------------------------------------------*/
+
+/* Compute extensions from the grammar file extension. */
+static void
+compute_exts_from_gf (const char *ext)
+{
+ if (STREQ (ext, ".y"))
+ {
+ src_extension = xstrdup (language->src_extension);
+ /* header_extension = xstrdup (language->header_extension); */
+ header_extension = xstrdup(".h");
+ }
+ 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');
+ */
+ header_extension = xstrdup(".h");
+ }
+}
+
+/* Compute extensions from the given c source file extension. */
+static void
+compute_exts_from_src (const char *ext)
+{
+ /* We use this function when the user specifies `-o' or `--output',
+ so the extenions must be computed unconditionally from the file name
+ given by this option. */
+ src_extension = xstrdup (ext);
+ /*
+ header_extension = xstrdup (ext);
+ tr (header_extension, 'c', 'h');
+ tr (header_extension, 'C', 'H');
+ */
+ header_extension = xstrdup(".h");
+}
+
+
+/* Decompose FILE_NAME in four parts: *BASE, *TAB, and *EXT, the fourth
+ part, (the directory) is ranging from FILE_NAME to the char before
+ *BASE, so we don't need an additional parameter.
+
+ *EXT points to the last period in the basename, or NULL if none.
+
+ If there is no *EXT, *TAB is NULL. Otherwise, *TAB points to
+ '.tab' or '_tab' if present right before *EXT, or is NULL. *TAB
+ cannot be equal to *BASE.
+
+ None are allocated, they are simply pointers to parts of FILE_NAME.
+ Examples:
+
+ '/tmp/foo.tab.c' -> *BASE = 'foo.tab.c', *TAB = '.tab.c', *EXT =
+ '.c'
+
+ 'foo.c' -> *BASE = 'foo.c', *TAB = NULL, *EXT = '.c'
+
+ 'tab.c' -> *BASE = 'tab.c', *TAB = NULL, *EXT = '.c'
+
+ '.tab.c' -> *BASE = '.tab.c', *TAB = NULL, *EXT = '.c'
+
+ 'foo.tab' -> *BASE = 'foo.tab', *TAB = NULL, *EXT = '.tab'
+
+ 'foo_tab' -> *BASE = 'foo_tab', *TAB = NULL, *EXT = NULL
+
+ 'foo' -> *BASE = 'foo', *TAB = NULL, *EXT = NULL. */
+
+static void
+file_name_split (const char *file_name,
+ const char **base, const char **tab, const char **ext)
+{
+ *base = last_component (file_name);
+
+ /* Look for the extension, i.e., look for the last dot. */
+ *ext = strrchr (*base, '.');
+ *tab = NULL;
+
+ /* If there is an extension, check if there is a '.tab' part right
+ before. */
+ if (*ext)
+ {
+ size_t baselen = *ext - *base;
+ size_t dottablen = sizeof (TAB_EXT) - 1;
+ if (dottablen < baselen
+ && STRPREFIX_LIT (TAB_EXT, *ext - dottablen))
+ *tab = *ext - dottablen;
+ }
+}
+
+
+static void
+compute_file_name_parts (void)
+{
+ const char *base, *tab, *ext;
+
+ /* Compute ALL_BUT_EXT and ALL_BUT_TAB_EXT from SPEC_OUTFILE
+ or GRAMMAR_FILE.
+
+ The precise -o name will be used for FTABLE. For other output
+ files, remove the ".c" or ".tab.c" suffix. */
+ if (spec_outfile)
+ {
+ file_name_split (spec_outfile, &base, &tab, &ext);
+ dir_prefix = xstrndup (spec_outfile, base - spec_outfile);
+
+ /* ALL_BUT_EXT goes up the EXT, excluding it. */
+ all_but_ext =
+ xstrndup (spec_outfile,
+ (strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
+
+ /* ALL_BUT_TAB_EXT goes up to TAB, excluding it. */
+ all_but_tab_ext =
+ xstrndup (spec_outfile,
+ (strlen (spec_outfile)
+ - (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
+
+ if (ext)
+ compute_exts_from_src (ext);
+ }
+ else
+ {
+ file_name_split (grammar_file, &base, &tab, &ext);
+
+ if (spec_file_prefix)
+ {
+ /* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = 'foo'. */
+ 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 = 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 = xstrdup ("");
+ all_but_tab_ext =
+ xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
+ }
+
+ 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)
+ compute_exts_from_gf (ext);
+ }
+}
+
+
+/* Compute the output file names. Warn if we detect conflicting
+ outputs to the same file. */
+
+void
+compute_output_file_names (void)
+{
+ compute_file_name_parts ();
+
+ /* If not yet done. */
+ if (!src_extension)
+ src_extension = xstrdup (".c");
+ if (!header_extension)
+ header_extension = xstrdup (".h");
+
+ 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);
+ }
+
+ if (graph_flag)
+ {
+ if (! 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)
+ {
+ if (!spec_verbose_file)
+ spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
+ output_file_name_check (&spec_verbose_file);
+ }
+
+ free (all_but_tab_ext);
+ free (src_extension);
+ free (header_extension);
+}
+
+void
+output_file_name_check (char **file_name)
+{
+ bool conflict = false;
+ if (STREQ (*file_name, grammar_file))
+ {
+ complain (NULL, complaint, _("refusing to overwrite the input file %s"),
+ quote (*file_name));
+ conflict = true;
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < file_names_count; i++)
+ if (STREQ (file_names[i], *file_name))
+ {
+ complain (NULL, Wother, _("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/contrib/tools/bison/src/files.h b/contrib/tools/bison/src/files.h
new file mode 100644
index 0000000000..ebe5037c7a
--- /dev/null
+++ b/contrib/tools/bison/src/files.h
@@ -0,0 +1,72 @@
+/* File names and variables for bison,
+
+ Copyright (C) 1984, 1989, 2000-2002, 2006-2007, 2009-2013 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 FILES_H_
+# define FILES_H_
+
+# include "uniqstr.h"
+
+/* File name specified with -o for the output file, or 0 if no -o. */
+extern char const *spec_outfile;
+
+/* File name for the parser (i.e., the one above, or its default.) */
+extern char *parser_file_name;
+
+/* Symbol prefix specified with -p, or 0 if no -p. */
+extern const char *spec_name_prefix;
+
+/* File name prefix specified with -b, or 0 if no -b. */
+extern char const *spec_file_prefix;
+
+/* --verbose. */
+extern char *spec_verbose_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 *spec_defines_file;
+
+/* Directory prefix of output file names. */
+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,
+ and therefore GCC warns about a name clash. */
+extern uniqstr grammar_file;
+
+/* 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, char const *mode);
+void xfclose (FILE *ptr);
+FILE *xfdopen (int fd, char const *mode);
+
+#endif /* !FILES_H_ */
diff --git a/contrib/tools/bison/src/flex-scanner.h b/contrib/tools/bison/src/flex-scanner.h
new file mode 100644
index 0000000000..03c9ec64fd
--- /dev/null
+++ b/contrib/tools/bison/src/flex-scanner.h
@@ -0,0 +1,90 @@
+/* Common parts between scan-code.l, scan-gram.l, and scan-skel.l.
+
+ Copyright (C) 2006, 2009-2013 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
+
+#include <obstack.h>
+
+/* 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 \
+ (last_string = obstack_finish0 (&obstack_for_string))
+
+# define STRING_FREE \
+ obstack_free (&obstack_for_string, last_string)
+
+#endif
diff --git a/contrib/tools/bison/src/getargs.c b/contrib/tools/bison/src/getargs.c
new file mode 100644
index 0000000000..d63bc7f9f5
--- /dev/null
+++ b/contrib/tools/bison/src/getargs.c
@@ -0,0 +1,741 @@
+/* Parse command line arguments for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 2000-2013 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 "output.h"
+
+#include <argmatch.h>
+#include <c-strcase.h>
+#include <configmake.h>
+#include <error.h>
+#include <getopt.h>
+#include <progname.h>
+
+#include "complain.h"
+#include "files.h"
+#include "getargs.h"
+#include "muscle-tab.h"
+#include "quote.h"
+#include "uniqstr.h"
+
+bool defines_flag;
+bool graph_flag;
+bool xml_flag;
+bool no_lines_flag;
+bool token_table_flag;
+bool yacc_flag; /* for -y */
+
+bool nondeterministic_parser = false;
+bool glr_parser = false;
+
+int feature_flag = feature_caret;
+int report_flag = report_none;
+int trace_flag = trace_none;
+
+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* m4_path = NULL;
+
+/** Decode an option's key.
+ *
+ * \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 arg the subarguments to decode.
+ * If null, then activate all the flags.
+ * \param no length of the potential "no-" prefix.
+ * Can be 0 or 3. If 3, negate the action of the subargument.
+ *
+ * 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
+flag_argmatch (const char *option,
+ const char * const keys[], const int values[],
+ int all, int *flags, char *arg, size_t no)
+{
+ int value = XARGMATCH (option, arg + no, keys, values);
+
+ /* -rnone == -rno-all, and -rno-none == -rall. */
+ if (!value)
+ {
+ value = all;
+ no = !no;
+ }
+
+ if (no)
+ *flags &= ~value;
+ else
+ *flags |= value;
+}
+
+/** 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.
+ */
+static void
+flags_argmatch (const char *option,
+ const char * const keys[], const int values[],
+ int all, int *flags, char *args)
+{
+ if (args)
+ for (args = strtok (args, ","); args; args = strtok (NULL, ","))
+ {
+ size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
+ flag_argmatch (option, keys,
+ values, all, flags, args, no);
+ }
+ else
+ *flags |= all;
+}
+
+
+/** Decode a set of sub arguments.
+ *
+ * \param FlagName the flag familly to update.
+ * \param Args the effective sub arguments to decode.
+ * \param All the "all" value.
+ *
+ * \arg FlagName_args the list of keys.
+ * \arg FlagName_types the list of values.
+ * \arg FlagName_flag the flag to update.
+ */
+#define FLAGS_ARGMATCH(FlagName, Args, All) \
+ flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
+ 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);
+
+
+/*---------------------.
+| --trace's handling. |
+`---------------------*/
+
+static const char * const trace_args[] =
+{
+ "none - no traces",
+ "scan - grammar scanner traces",
+ "parse - grammar parser traces",
+ "automaton - construction of the automaton",
+ "bitsets - use of bitsets",
+ "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
+};
+
+static const int trace_types[] =
+{
+ trace_none,
+ trace_scan,
+ trace_parse,
+ trace_automaton,
+ trace_bitsets,
+ 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);
+
+
+/*-----------------------.
+| --feature's handling. |
+`-----------------------*/
+
+static const char * const feature_args[] =
+{
+ "none",
+ "caret", "diagnostics-show-caret",
+ "all",
+ 0
+};
+
+static const int feature_types[] =
+{
+ feature_none,
+ feature_caret, feature_caret,
+ feature_all
+};
+
+ARGMATCH_VERIFY (feature_args, feature_types);
+
+/*-------------------------------------------.
+| Display the help message and exit STATUS. |
+`-------------------------------------------*/
+
+static void usage (int) ATTRIBUTE_NORETURN;
+
+static void
+usage (int status)
+{
+ if (status != 0)
+ fprintf (stderr, _("Try '%s --help' for more information.\n"),
+ program_name);
+ else
+ {
+ /* 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. */
+
+ 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 (_("\
+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\
+ --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\
+ -L, --language=LANGUAGE specify the output programming language\n\
+ -S, --skeleton=FILE specify the skeleton to use\n\
+ -t, --debug instrument the parser for tracing\n\
+ same as '-Dparse.trace'\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 (_("\
+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\
+ 'empty-rule' empty rules without %empty\n\
+ 'precedence' useless precedence and associativity\n\
+ 'other' all other warnings (enabled by default)\n\
+ 'all' all the warnings except 'yacc'\n\
+ 'no-CATEGORY' turn off warnings in CATEGORY\n\
+ 'none' turn off all the warnings\n\
+ 'error[=CATEGORY]' treat warnings as errors\n\
+"), stdout);
+ putc ('\n', stdout);
+
+ fputs (_("\
+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\
+ '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\
+"), stdout);
+ putc ('\n', stdout);
+
+ fputs (_("\
+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. */
+ fputs (_("For complete documentation, run: info bison.\n"), stdout);
+ }
+
+ exit (status);
+}
+
+
+/*------------------------------.
+| Display the version message. |
+`------------------------------*/
+
+static void
+version (void)
+{
+ /* Some efforts were made to ease the translators' task, please
+ continue. */
+ printf (_("bison (GNU Bison) %s"), VERSION);
+ putc ('\n', stdout);
+ fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout);
+ putc ('\n', stdout);
+
+ fprintf (stdout,
+ _("Copyright (C) %d Free Software Foundation, Inc.\n"),
+ 2013);
+
+ fputs (_("\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"),
+ stdout);
+}
+
+
+/*-------------------------------------.
+| --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 (&loc, complaint,
+ _("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 (&loc, complaint, msg, quotearg_colon (arg));
+}
+
+/*----------------------.
+| Process the options. |
+`----------------------*/
+
+/* Shorts options.
+ Should be computed from long_options. */
+static char const short_options[] =
+ "D:"
+ "F:"
+ "L:"
+ "S:"
+ "T::"
+ "V"
+ "W::"
+ "b:"
+ "d"
+ "f::"
+ "g::"
+ "h"
+ "k"
+ "l"
+ "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_DATADIR_OPTION,
+ REPORT_FILE_OPTION,
+ M4_PATH
+};
+
+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 },
+ { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
+ { "warnings", optional_argument, 0, 'W' },
+
+ /* Parser. */
+ { "name-prefix", required_argument, 0, 'p' },
+
+ /* Output. */
+ { "file-prefix", required_argument, 0, 'b' },
+ { "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. */
+ { "trace", optional_argument, 0, 'T' },
+ { "m4", required_argument, 0, M4_PATH },
+
+ /* Output. */
+ { "defines", optional_argument, 0, 'd' },
+ { "feature", optional_argument, 0, 'f' },
+
+ /* Operation modes. */
+ { "fixed-output-files", no_argument, 0, 'y' },
+ { "yacc", no_argument, 0, 'y' },
+
+ /* 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' },
+ { "skeleton", required_argument, 0, 'S' },
+ { "language", required_argument, 0, 'L' },
+ { "token-table", no_argument, 0, 'k' },
+
+ {0, 0, 0, 0}
+};
+
+/* Under DOS, there is no difference on the case. This can be
+ troublesome when looking for '.tab' etc. */
+#ifdef MSDOS
+# define AS_FILE_NAME(File) (strlwr (File), (File))
+#else
+# 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[])
+{
+ int c;
+
+ while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
+ != -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 'D': /* -DNAME[=(VALUE|"VALUE"|{VALUE})]. */
+ case 'F': /* -FNAME[=(VALUE|"VALUE"|{VALUE})]. */
+ {
+ char *name = optarg;
+ char *value = strchr (optarg, '=');
+ muscle_kind kind = muscle_keyword;
+ if (value)
+ {
+ char *end = value + strlen (value) - 1;
+ *value++ = 0;
+ if (*value == '{' && *end == '}')
+ {
+ kind = muscle_code;
+ ++value;
+ *end = 0;
+ }
+ else if (*value == '"' && *end == '"')
+ {
+ kind = muscle_string;
+ ++value;
+ *end = 0;
+ }
+ }
+ muscle_percent_define_insert (name, command_line_location (),
+ kind, value ? value : "",
+ c == 'D' ? MUSCLE_PERCENT_DEFINE_D
+ : MUSCLE_PERCENT_DEFINE_F);
+ }
+ 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, trace_all);
+ break;
+
+ case 'V':
+ version ();
+ exit (EXIT_SUCCESS);
+
+ case 'f':
+ FLAGS_ARGMATCH (feature, optarg, feature_all);
+ break;
+
+ case 'W':
+ warnings_argmatch (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;
+ if (optarg)
+ {
+ free (spec_defines_file);
+ spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
+ }
+ break;
+
+ case 'g':
+ graph_flag = true;
+ if (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 'o':
+ spec_outfile = AS_FILE_NAME (optarg);
+ break;
+
+ case 'p':
+ spec_name_prefix = optarg;
+ break;
+
+ case 'r':
+ FLAGS_ARGMATCH (report, optarg, report_all);
+ break;
+
+ case 't':
+ muscle_percent_define_insert ("parse.trace",
+ command_line_location (),
+ muscle_keyword, "",
+ MUSCLE_PERCENT_DEFINE_D);
+ 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':
+ warning_argmatch ("error=yacc", 0, 6);
+ yacc_flag = true;
+ break;
+
+ case LOCATIONS_OPTION:
+ muscle_percent_define_ensure ("locations",
+ command_line_location (), true);
+ break;
+
+#if 0
+ case PRINT_LOCALEDIR_OPTION:
+ printf ("%s\n", LOCALEDIR);
+ exit (EXIT_SUCCESS);
+#endif
+
+ case PRINT_DATADIR_OPTION:
+ printf ("%s\n", pkgdatadir ());
+ exit (EXIT_SUCCESS);
+
+ case REPORT_FILE_OPTION:
+ free (spec_verbose_file);
+ spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
+ break;
+
+ case M4_PATH:
+ m4_path = xstrdup (AS_FILE_NAME (optarg));
+ break;
+
+ default:
+ usage (EXIT_FAILURE);
+ }
+
+ if (argc - optind != 1)
+ {
+ if (argc - optind < 1)
+ error (0, 0, _("%s: missing operand"), quotearg_colon (argv[argc - 1]));
+ else
+ 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/contrib/tools/bison/src/getargs.h b/contrib/tools/bison/src/getargs.h
new file mode 100644
index 0000000000..178fb94377
--- /dev/null
+++ b/contrib/tools/bison/src/getargs.h
@@ -0,0 +1,141 @@
+/* Parse command line arguments for bison.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 2000-2013 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 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 defines_flag; /* for -d */
+extern bool graph_flag; /* for -g */
+extern bool xml_flag; /* for -x */
+extern bool no_lines_flag; /* for -l */
+extern bool token_table_flag; /* for -k */
+extern bool yacc_flag; /* for -y */
+
+extern const char *m4_path;
+
+
+/* GLR_PARSER is true if the input file says to use the GLR
+ (Generalized LR) parser, and to output some additional information
+ used by the GLR algorithm. */
+
+extern bool glr_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;
+
+
+/* --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_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;
+
+/*-------------.
+| --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/contrib/tools/bison/src/gram.c b/contrib/tools/bison/src/gram.c
new file mode 100644
index 0000000000..f6cc3c5d87
--- /dev/null
+++ b/contrib/tools/bison/src/gram.c
@@ -0,0 +1,310 @@
+/* Allocate input grammar variables for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2013 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 "complain.h"
+#include "getargs.h"
+#include "gram.h"
+#include "print-xml.h"
+#include "reader.h"
+#include "reduce.h"
+#include "symtab.h"
+
+/* Comments for these variables are in gram.h. */
+
+item_number *ritem = NULL;
+unsigned int nritems = 0;
+
+rule *rules = NULL;
+rule_number nrules = 0;
+
+symbol **symbols = NULL;
+int nsyms = 0;
+int ntokens = 1;
+int nvars = 0;
+
+symbol_number *token_translations = NULL;
+
+int max_user_token_number = 256;
+
+bool
+rule_useful_in_grammar_p (rule const *r)
+{
+ return r->number < nrules;
+}
+
+bool
+rule_useless_in_grammar_p (rule const *r)
+{
+ return !rule_useful_in_grammar_p (r);
+}
+
+bool
+rule_useless_in_parser_p (rule const *r)
+{
+ return !r->useful && rule_useful_in_grammar_p (r);
+}
+
+void
+rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out)
+{
+ fprintf (out, " %3d ", r->number);
+ if (previous_lhs != r->lhs)
+ fprintf (out, "%s:", r->lhs->tag);
+ else
+ fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
+}
+
+void
+rule_lhs_print_xml (rule const *r, FILE *out, int level)
+{
+ xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
+}
+
+size_t
+rule_rhs_length (rule const *r)
+{
+ size_t res = 0;
+ item_number *rhsp;
+ for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
+ ++res;
+ return res;
+}
+
+void
+rule_rhs_print (rule const *r, FILE *out)
+{
+ if (0 <= *r->rhs)
+ {
+ item_number *rp;
+ for (rp = r->rhs; *rp >= 0; rp++)
+ fprintf (out, " %s", symbols[*rp]->tag);
+ }
+ else
+ fputs (" %empty", out);
+}
+
+static void
+rule_rhs_print_xml (rule const *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
+ritem_print (FILE *out)
+{
+ unsigned int i;
+ fputs ("RITEM\n", out);
+ for (i = 0; i < nritems; ++i)
+ if (ritem[i] >= 0)
+ fprintf (out, " %s", symbols[ritem[i]]->tag);
+ else
+ fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
+ fputs ("\n\n", out);
+}
+
+size_t
+ritem_longest_rhs (void)
+{
+ int max = 0;
+ rule_number r;
+
+ for (r = 0; r < nrules; ++r)
+ {
+ int length = rule_rhs_length (&rules[r]);
+ if (length > max)
+ max = length;
+ }
+
+ return max;
+}
+
+void
+grammar_rules_partial_print (FILE *out, const char *title,
+ rule_filter filter)
+{
+ rule_number r;
+ bool first = true;
+ symbol *previous_lhs = NULL;
+
+ /* rule # : LHS -> RHS */
+ for (r = 0; r < nrules + nuseless_productions; r++)
+ {
+ if (filter && !filter (&rules[r]))
+ continue;
+ if (first)
+ fprintf (out, "%s\n\n", title);
+ else if (previous_lhs && previous_lhs != rules[r].lhs)
+ fputc ('\n', out);
+ first = false;
+ rule_lhs_print (&rules[r], previous_lhs, out);
+ rule_rhs_print (&rules[r], out);
+ fprintf (out, "\n");
+ previous_lhs = rules[r].lhs;
+ }
+ if (!first)
+ fputs ("\n\n", out);
+}
+
+void
+grammar_rules_print (FILE *out)
+{
+ 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;
+
+ 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)
+{
+ fprintf (out, "%s\n\n", title);
+ fprintf (out,
+ "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
+ ntokens, nvars, nsyms, nrules, nritems);
+
+
+ fprintf (out, "Variables\n---------\n\n");
+ {
+ symbol_number i;
+ fprintf (out, "Value Sprec Sassoc Tag\n");
+
+ for (i = ntokens; i < nsyms; i++)
+ fprintf (out, "%5d %5d %5d %s\n",
+ i,
+ symbols[i]->prec, symbols[i]->assoc,
+ symbols[i]->tag);
+ fprintf (out, "\n\n");
+ }
+
+ fprintf (out, "Rules\n-----\n\n");
+ {
+ rule_number i;
+ fprintf (out,
+ "Num (Prec, Assoc, Useful, Ritem Range) Lhs"
+ " -> Rhs (Ritem range) [Num]\n");
+ for (i = 0; i < nrules + nuseless_productions; i++)
+ {
+ rule const *rule_i = &rules[i];
+ item_number *rp = NULL;
+ unsigned int rhs_itemno = rule_i->rhs - ritem;
+ unsigned int rhs_count = 0;
+ /* Find the last RHS index in ritems. */
+ for (rp = rule_i->rhs; *rp >= 0; ++rp)
+ ++rhs_count;
+ fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
+ i,
+ rule_i->prec ? rule_i->prec->prec : 0,
+ rule_i->prec ? rule_i->prec->assoc : 0,
+ rule_i->useful,
+ rhs_itemno,
+ rhs_itemno + rhs_count - 1,
+ rule_i->lhs->number);
+ /* Dumped the RHS. */
+ for (rp = rule_i->rhs; *rp >= 0; rp++)
+ fprintf (out, " %3d", *rp);
+ fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
+ }
+ }
+ fprintf (out, "\n\n");
+
+ fprintf (out, "Rules interpreted\n-----------------\n\n");
+ {
+ rule_number r;
+ for (r = 0; r < nrules + nuseless_productions; r++)
+ {
+ fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
+ rule_rhs_print (&rules[r], out);
+ fprintf (out, "\n");
+ }
+ }
+ fprintf (out, "\n\n");
+}
+
+void
+grammar_rules_useless_report (const char *message)
+{
+ rule_number r;
+ for (r = 0; r < nrules ; ++r)
+ if (!rules[r].useful)
+ complain (&rules[r].location, Wother, "%s", message);
+}
+
+void
+grammar_free (void)
+{
+ if (ritem)
+ free (ritem - 1);
+ free (rules);
+ free (token_translations);
+ /* Free the symbol table data structure. */
+ symbols_free ();
+ free_merger_functions ();
+}
diff --git a/contrib/tools/bison/src/gram.h b/contrib/tools/bison/src/gram.h
new file mode 100644
index 0000000000..c1dd9a648a
--- /dev/null
+++ b/contrib/tools/bison/src/gram.h
@@ -0,0 +1,273 @@
+/* Data definitions for internal representation of Bison's input.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 2001-2007, 2009-2013 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 GRAM_H_
+# define GRAM_H_
+
+/* Representation of the grammar rules:
+
+ NTOKENS is the number of tokens, and NVARS is the number of
+ variables (nonterminals). NSYMS is the total number, ntokens +
+ nvars.
+
+ Each symbol (either token or variable) receives a symbol number.
+ Numbers 0 to NTOKENS - 1 are for tokens, and NTOKENS to NSYMS - 1
+ are for variables. Symbol number zero is the end-of-input token.
+ This token is counted in ntokens. The true number of token values
+ assigned is NTOKENS reduced by one for each alias declaration.
+
+ The rules receive rule numbers 1 to NRULES in the order they are
+ written. More precisely Bison augments the grammar with the
+ initial rule, '$accept: START-SYMBOL $end', which is numbered 1,
+ all the user rules are 2, 3 etc. Each time a rule number is
+ presented to the user, we subtract 1, so *displayed* rule numbers
+ are 0, 1, 2...
+
+ Internally, we cannot use the number 0 for a rule because for
+ instance RITEM stores both symbol (the RHS) and rule numbers: the
+ symbols are shorts >= 0, and rule number are stored negative.
+ Therefore 0 cannot be used, since it would be both the rule number
+ 0, and the token $end).
+
+ Actions are accessed via the rule number.
+
+ The rules themselves are described by several arrays: amongst which
+ RITEM, and RULES.
+
+ RULES is an array of rules, whose members are:
+
+ RULES[R].lhs -- the symbol of the left hand side of rule R.
+
+ RULES[R].rhs -- the index in RITEM of the beginning of the portion
+ for rule R.
+
+ RULES[R].prec -- the symbol providing the precedence level of R.
+
+ RULES[R].precsym -- the symbol attached (via %prec) to give its
+ precedence to R. Of course, if set, it is equal to 'prec', but we
+ need to distinguish one from the other when reducing: a symbol used
+ in a %prec is not useless.
+
+ RULES[R].assoc -- the associativity of R.
+
+ RULES[R].dprec -- the dynamic precedence level of R (for GLR
+ parsing).
+
+ RULES[R].merger -- index of merging function for R (for GLR
+ parsing).
+
+ RULES[R].line -- the line where R was defined.
+
+ RULES[R].useful -- true iff the rule is used (i.e., false if thrown
+ away by reduce).
+
+ The right hand side is stored as symbol numbers in a portion of
+ RITEM.
+
+ The length of the portion is one greater than the number of symbols
+ in the rule's right hand side. The last element in the portion
+ contains minus R, which identifies it as the end of a portion and
+ says which rule it is for.
+
+ The portions of RITEM come in order of increasing rule number.
+ NRITEMS is the total length of RITEM. Each element of RITEM is
+ called an "item" and its index in RITEM is an item number.
+
+ Item numbers are used in the finite state machine to represent
+ places that parsing can get to.
+
+ SYMBOLS[I]->prec records the precedence level of each symbol.
+
+ Precedence levels are assigned in increasing order starting with 1
+ so that numerically higher precedence values mean tighter binding
+ as they ought to. Zero as a symbol or rule's precedence means none
+ is assigned.
+
+ Associativities are recorded similarly in SYMBOLS[I]->assoc. */
+
+# include "location.h"
+# include "symtab.h"
+
+# define ISTOKEN(i) ((i) < ntokens)
+# define ISVAR(i) ((i) >= ntokens)
+
+extern int nsyms;
+extern int ntokens;
+extern int nvars;
+
+typedef int item_number;
+# define ITEM_NUMBER_MAX INT_MAX
+extern item_number *ritem;
+extern unsigned int nritems;
+
+/* There is weird relationship between OT1H item_number and OTOH
+ symbol_number and rule_number: we store the latter in
+ item_number. symbol_number values are stored as-is, while
+ the negation of (rule_number + 1) is stored.
+
+ Therefore, a symbol_number must be a valid item_number, and we
+ sometimes have to perform the converse transformation. */
+
+static inline item_number
+symbol_number_as_item_number (symbol_number sym)
+{
+ return sym;
+}
+
+static inline symbol_number
+item_number_as_symbol_number (item_number i)
+{
+ return i;
+}
+
+static inline bool
+item_number_is_symbol_number (item_number i)
+{
+ return i >= 0;
+}
+
+/* Rule numbers. */
+typedef int rule_number;
+# define RULE_NUMBER_MAX INT_MAX
+extern rule_number nrules;
+
+static inline item_number
+rule_number_as_item_number (rule_number r)
+{
+ return -1 - r;
+}
+
+static inline rule_number
+item_number_as_rule_number (item_number i)
+{
+ return -1 - i;
+}
+
+static inline bool
+item_number_is_rule_number (item_number i)
+{
+ return i < 0;
+}
+
+/*--------.
+| Rules. |
+`--------*/
+
+typedef struct
+{
+ /* The number of the rule in the source. It is usually the index in
+ RULES too, except if there are useless rules. */
+ rule_number user_number;
+
+ /* The index in RULES. Usually the rule number in the source,
+ except if some rules are useless. */
+ rule_number number;
+
+ symbol *lhs;
+ item_number *rhs;
+
+ /* This symbol provides both the associativity, and the precedence. */
+ symbol *prec;
+
+ int dprec;
+ int merger;
+
+ /* This symbol was attached to the rule via %prec. */
+ symbol *precsym;
+
+ location location;
+ bool useful;
+ bool is_predicate;
+
+ const char *action;
+ location action_location;
+} rule;
+
+extern rule *rules;
+
+/* A function that selects a rule. */
+typedef bool (*rule_filter) (rule const *);
+
+/* 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 const *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 const *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 const *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 const *r, symbol const *previous_lhs, FILE *out);
+void rule_lhs_print_xml (rule const *r, FILE *out, int level);
+
+/* Return the length of the RHS. */
+size_t rule_rhs_length (rule const *r);
+
+/* Print this rule's RHS on OUT. */
+void rule_rhs_print (rule const *r, FILE *out);
+
+
+
+
+/* Table of the symbols, indexed by the symbol number. */
+extern symbol **symbols;
+
+/* TOKEN_TRANSLATION -- a table indexed by a token number as returned
+ by the user's yylex routine, it yields the internal token number
+ used by the parser and throughout bison. */
+extern symbol_number *token_translations;
+extern int max_user_token_number;
+
+
+
+/* Dump RITEM for traces. */
+void ritem_print (FILE *out);
+
+/* Return the size of the longest rule RHS. */
+size_t ritem_longest_rhs (void);
+
+/* 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 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 '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);
+
+#endif /* !GRAM_H_ */
diff --git a/contrib/tools/bison/src/graphviz.c b/contrib/tools/bison/src/graphviz.c
new file mode 100644
index 0000000000..5ee41e73f3
--- /dev/null
+++ b/contrib/tools/bison/src/graphviz.c
@@ -0,0 +1,218 @@
+/* Output Graphviz specification of a state machine generated by Bison.
+
+ Copyright (C) 2006-2007, 2009-2013 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/contrib/tools/bison/src/graphviz.h b/contrib/tools/bison/src/graphviz.h
new file mode 100644
index 0000000000..0254ef748b
--- /dev/null
+++ b/contrib/tools/bison/src/graphviz.h
@@ -0,0 +1,71 @@
+/* Output Graphviz specification of a state machine generated by Bison.
+
+ Copyright (C) 2006, 2010-2013 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/contrib/tools/bison/src/ielr.c b/contrib/tools/bison/src/ielr.c
new file mode 100644
index 0000000000..38156b384d
--- /dev/null
+++ b/contrib/tools/bison/src/ielr.c
@@ -0,0 +1,1200 @@
+/* IELR main implementation.
+
+ Copyright (C) 2009-2013 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)
+ {
+ state_list *node;
+ timevar_push (TV_IELR_PHASE4);
+ initialize_LA ();
+ 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 (STREQ (type, "lalr"))
+ lr_type = LR_TYPE__LALR;
+ else if (STREQ (type, "ielr"))
+ lr_type = LR_TYPE__IELR;
+ else if (STREQ (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/contrib/tools/bison/src/ielr.h b/contrib/tools/bison/src/ielr.h
new file mode 100644
index 0000000000..b60ae36348
--- /dev/null
+++ b/contrib/tools/bison/src/ielr.h
@@ -0,0 +1,46 @@
+/* IELR main implementation.
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/lalr.c b/contrib/tools/bison/src/lalr.c
new file mode 100644
index 0000000000..d99f960fbf
--- /dev/null
+++ b/contrib/tools/bison/src/lalr.c
@@ -0,0 +1,500 @@
+/* Compute lookahead criteria for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 2000-2013 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/>. */
+
+
+/* Find which rules need lookahead in each state, and which lookahead
+ tokens they accept. */
+
+#include <config.h>
+#include "system.h"
+
+#include <bitset.h>
+#include <bitsetv.h>
+
+#include "LR0.h"
+#include "complain.h"
+#include "derives.h"
+#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;
+goto_number ngotos;
+state_number *from_state;
+state_number *to_state;
+bitsetv goto_follows = NULL;
+
+/* Linked list of goto numbers. */
+typedef struct goto_list
+{
+ struct goto_list *next;
+ goto_number value;
+} goto_list;
+
+
+/* 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. */
+
+static bitsetv LA = NULL;
+size_t nLA;
+
+
+static goto_number **includes;
+static goto_list **lookback;
+
+
+
+
+void
+set_goto_map (void)
+{
+ state_number s;
+ goto_number *temp_map;
+
+ goto_map = xcalloc (nvars + 1, sizeof *goto_map);
+ temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
+
+ ngotos = 0;
+ for (s = 0; s < nstates; ++s)
+ {
+ transitions *sp = states[s]->transitions;
+ int i;
+ for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
+ {
+ ngotos++;
+
+ /* Abort if (ngotos + 1) would overflow. */
+ aver (ngotos != GOTO_NUMBER_MAXIMUM);
+
+ goto_map[TRANSITION_SYMBOL (sp, i) - ntokens]++;
+ }
+ }
+
+ {
+ goto_number k = 0;
+ int i;
+ for (i = ntokens; i < nsyms; i++)
+ {
+ temp_map[i - ntokens] = k;
+ k += goto_map[i - ntokens];
+ }
+
+ for (i = ntokens; i < nsyms; i++)
+ goto_map[i - ntokens] = temp_map[i - ntokens];
+
+ goto_map[nsyms - ntokens] = ngotos;
+ temp_map[nsyms - ntokens] = ngotos;
+ }
+
+ from_state = xcalloc (ngotos, sizeof *from_state);
+ to_state = xcalloc (ngotos, sizeof *to_state);
+
+ for (s = 0; s < nstates; ++s)
+ {
+ transitions *sp = states[s]->transitions;
+ int i;
+ for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
+ {
+ goto_number k = temp_map[TRANSITION_SYMBOL (sp, i) - ntokens]++;
+ from_state[k] = s;
+ to_state[k] = sp->states[i]->number;
+ }
+ }
+
+ free (temp_map);
+}
+
+
+goto_number
+map_goto (state_number s0, symbol_number sym)
+{
+ goto_number high;
+ goto_number low;
+ goto_number middle;
+ state_number s;
+
+ low = goto_map[sym - ntokens];
+ high = goto_map[sym - ntokens + 1] - 1;
+
+ for (;;)
+ {
+ aver (low <= high);
+ middle = (low + high) / 2;
+ s = from_state[middle];
+ if (s == s0)
+ return middle;
+ else if (s < s0)
+ low = middle + 1;
+ else
+ high = middle - 1;
+ }
+}
+
+
+static void
+initialize_F (void)
+{
+ goto_number **reads = xnmalloc (ngotos, sizeof *reads);
+ goto_number *edge = xnmalloc (ngotos + 1, sizeof *edge);
+ goto_number nedges = 0;
+
+ goto_number i;
+
+ goto_follows = bitsetv_create (ngotos, ntokens, BITSET_FIXED);
+
+ for (i = 0; i < ngotos; i++)
+ {
+ state_number stateno = to_state[i];
+ transitions *sp = states[stateno]->transitions;
+
+ int j;
+ FOR_EACH_SHIFT (sp, j)
+ bitset_set (goto_follows[i], TRANSITION_SYMBOL (sp, j));
+
+ for (; j < sp->num; j++)
+ {
+ symbol_number sym = TRANSITION_SYMBOL (sp, j);
+ if (nullable[sym - ntokens])
+ edge[nedges++] = map_goto (stateno, sym);
+ }
+
+ if (nedges == 0)
+ reads[i] = NULL;
+ else
+ {
+ reads[i] = xnmalloc (nedges + 1, sizeof reads[i][0]);
+ memcpy (reads[i], edge, nedges * sizeof edge[0]);
+ reads[i][nedges] = END_NODE;
+ nedges = 0;
+ }
+ }
+
+ relation_digraph (reads, ngotos, &goto_follows);
+
+ for (i = 0; i < ngotos; i++)
+ free (reads[i]);
+
+ free (reads);
+ free (edge);
+}
+
+
+static void
+add_lookback_edge (state *s, rule *r, goto_number gotono)
+{
+ int ri = state_reduction_find (s, r);
+ goto_list *sp = xmalloc (sizeof *sp);
+ sp->next = lookback[(s->reductions->lookahead_tokens - LA) + ri];
+ sp->value = gotono;
+ lookback[(s->reductions->lookahead_tokens - LA) + ri] = sp;
+}
+
+
+
+static void
+build_relations (void)
+{
+ goto_number *edge = xnmalloc (ngotos + 1, sizeof *edge);
+ state_number *states1 = xnmalloc (ritem_longest_rhs () + 1, sizeof *states1);
+ goto_number i;
+
+ includes = xnmalloc (ngotos, sizeof *includes);
+
+ for (i = 0; i < ngotos; i++)
+ {
+ int nedges = 0;
+ symbol_number symbol1 = states[to_state[i]]->accessing_symbol;
+ rule **rulep;
+
+ for (rulep = derives[symbol1 - ntokens]; *rulep; rulep++)
+ {
+ bool done;
+ int length = 1;
+ item_number const *rp;
+ state *s = states[from_state[i]];
+ states1[0] = s->number;
+
+ for (rp = (*rulep)->rhs; ! item_number_is_rule_number (*rp); rp++)
+ {
+ s = transitions_to (s->transitions,
+ item_number_as_symbol_number (*rp));
+ states1[length++] = s->number;
+ }
+
+ if (!s->consistent)
+ add_lookback_edge (s, *rulep, i);
+
+ length--;
+ done = false;
+ while (!done)
+ {
+ done = true;
+ /* 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))
+ {
+ /* Downcasting from item_number to symbol_number. */
+ edge[nedges++] = map_goto (states1[--length],
+ item_number_as_symbol_number (*rp));
+ if (nullable[*rp - ntokens])
+ done = false;
+ }
+ }
+ }
+
+ if (nedges == 0)
+ includes[i] = NULL;
+ else
+ {
+ int j;
+ includes[i] = xnmalloc (nedges + 1, sizeof includes[i][0]);
+ for (j = 0; j < nedges; j++)
+ includes[i][j] = edge[j];
+ includes[i][nedges] = END_NODE;
+ }
+ }
+
+ free (edge);
+ free (states1);
+
+ relation_transpose (&includes, ngotos);
+}
+
+
+
+static void
+compute_FOLLOWS (void)
+{
+ goto_number i;
+
+ relation_digraph (includes, ngotos, &goto_follows);
+
+ for (i = 0; i < ngotos; i++)
+ free (includes[i]);
+
+ free (includes);
+}
+
+
+static 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], goto_follows[sp->value]);
+
+ /* Free LOOKBACK. */
+ for (i = 0; i < nLA; i++)
+ LIST_FREE (goto_list, lookback[i]);
+
+ free (lookback);
+}
+
+
+/*----------------------------------------------------.
+| Count the number of lookahead tokens required for S |
+| (N_LOOKAHEAD_TOKENS member). |
+`----------------------------------------------------*/
+
+static int
+state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
+{
+ int n_lookahead_tokens = 0;
+ reductions *rp = s->reductions;
+ transitions *sp = s->transitions;
+
+ /* 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_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;
+
+ return n_lookahead_tokens;
+}
+
+
+/*----------------------------------------------------.
+| Compute LA, NLA, and the lookahead_tokens members. |
+`----------------------------------------------------*/
+
+void
+initialize_LA (void)
+{
+ state_number i;
+ bitsetv pLA;
+ bool default_reduction_only_for_accept;
+ {
+ char *default_reductions =
+ muscle_percent_define_get ("lr.default-reduction");
+ default_reduction_only_for_accept = STREQ (default_reductions, "accepting");
+ free (default_reductions);
+ }
+
+ /* Compute the total number of reductions requiring a lookahead. */
+ nLA = 0;
+ for (i = 0; i < nstates; 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);
+
+ /* Initialize the members LOOKAHEAD_TOKENS for each state whose reductions
+ require lookahead tokens. */
+ for (i = 0; i < nstates; i++)
+ {
+ int count =
+ state_lookahead_tokens_count (states[i],
+ default_reduction_only_for_accept);
+ if (count)
+ {
+ states[i]->reductions->lookahead_tokens = pLA;
+ pLA += count;
+ }
+ }
+}
+
+
+/*---------------------------------------------.
+| Output the lookahead tokens for each state. |
+`---------------------------------------------*/
+
+static void
+lookahead_tokens_print (FILE *out)
+{
+ state_number i;
+ int j, k;
+ fprintf (out, "Lookahead tokens: BEGIN\n");
+ for (i = 0; i < nstates; ++i)
+ {
+ reductions *reds = states[i]->reductions;
+ bitset_iterator iter;
+ int n_lookahead_tokens = 0;
+
+ if (reds->lookahead_tokens)
+ for (k = 0; k < reds->num; ++k)
+ if (reds->lookahead_tokens[k])
+ ++n_lookahead_tokens;
+
+ fprintf (out, "State %d: %d lookahead tokens\n",
+ i, n_lookahead_tokens);
+
+ if (reds->lookahead_tokens)
+ for (j = 0; j < reds->num; ++j)
+ BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
+ {
+ fprintf (out, " on %d (%s) -> rule %d\n",
+ k, symbols[k]->tag,
+ reds->rules[j]->number);
+ };
+ }
+ fprintf (out, "Lookahead tokens: END\n");
+}
+
+void
+lalr (void)
+{
+ initialize_LA ();
+ set_goto_map ();
+ initialize_F ();
+ lookback = xcalloc (nLA, sizeof *lookback);
+ build_relations ();
+ compute_FOLLOWS ();
+ compute_lookahead_tokens ();
+
+ if (trace_flag & trace_sets)
+ 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;
+}
+
+
+void
+lalr_free (void)
+{
+ state_number s;
+ for (s = 0; s < nstates; ++s)
+ states[s]->reductions->lookahead_tokens = NULL;
+ bitsetv_free (LA);
+}
diff --git a/contrib/tools/bison/src/lalr.h b/contrib/tools/bison/src/lalr.h
new file mode 100644
index 0000000000..f483315747
--- /dev/null
+++ b/contrib/tools/bison/src/lalr.h
@@ -0,0 +1,106 @@
+/* Compute lookahead criteria for bison,
+
+ Copyright (C) 1984, 1986, 1989, 2000, 2002, 2004, 2006-2007,
+ 2009-2013 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 LALR_H_
+# define LALR_H_
+
+# include <bitset.h>
+# include <bitsetv.h>
+
+/* Import the definition of RULE_T. */
+# include "gram.h"
+
+/* Import the definition of CORE, TRANSITIONS and REDUCTIONS. */
+# include "state.h"
+
+
+/** 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);
+
+/**
+ * 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);
+
+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/contrib/tools/bison/src/location.c b/contrib/tools/bison/src/location.c
new file mode 100644
index 0000000000..662b2a12a0
--- /dev/null
+++ b/contrib/tools/bison/src/location.c
@@ -0,0 +1,232 @@
+/* Locations for Bison
+
+ Copyright (C) 2002, 2005-2013 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 <mbswidth.h>
+#include <quotearg.h>
+
+#include "complain.h"
+#include "location.h"
+
+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)
+ complain (loc, Wother, _("line number overflow"));
+ if (column == INT_MAX && loc->start.column != INT_MAX)
+ complain (loc, Wother, _("column number overflow"));
+}
+
+
+unsigned
+location_print (location loc, FILE *out)
+{
+ 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)
+ {
+ 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);
+ caret_info.source = NULL;
+ caret_info.line = 1;
+ caret_info.offset = 0;
+}
+
+void
+location_caret (location loc, FILE *out)
+{
+ /* 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 a previous line, 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 += getc (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 c = getc (caret_info.source);
+ if (c != EOF)
+ {
+ /* Quote the file, indent by a single column. */
+ putc (' ', out);
+ do
+ putc (c, out);
+ while ((c = getc (caret_info.source)) != EOF && c != '\n');
+ putc ('\n', out);
+
+ {
+ /* The caret of a multiline location ends with the first line. */
+ size_t len = loc.start.line != loc.end.line
+ ? ftell (caret_info.source) - caret_info.offset
+ : loc.end.column;
+ int i;
+
+ /* Print the carets (at least one), with the same indent as above.*/
+ fprintf (out, " %*s", loc.start.column - 1, "");
+ for (i = loc.start.column; i == loc.start.column || i < len; ++i)
+ putc ('^', out);
+ }
+ putc ('\n', out);
+ }
+ }
+}
+
+void
+boundary_set_from_string (boundary *bound, char *loc_str)
+{
+ /* Must search in reverse since the file name field may
+ * contain '.' or ':'. */
+ char *delim = strrchr (loc_str, '.');
+ aver (delim);
+ *delim = '\0';
+ bound->column = atoi (delim+1);
+ delim = strrchr (loc_str, ':');
+ aver (delim);
+ *delim = '\0';
+ bound->line = atoi (delim+1);
+ bound->file = uniqstr_new (loc_str);
+}
diff --git a/contrib/tools/bison/src/location.h b/contrib/tools/bison/src/location.h
new file mode 100644
index 0000000000..9c6e53c190
--- /dev/null
+++ b/contrib/tools/bison/src/location.h
@@ -0,0 +1,131 @@
+/* Locations for Bison
+
+ Copyright (C) 2002, 2004-2013 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 LOCATION_H_
+# define LOCATION_H_
+
+# include <stdbool.h>
+# include <stdio.h>
+# include <string.h> /* strcmp */
+
+# include "uniqstr.h"
+
+/* A boundary between two characters. */
+typedef struct
+{
+ /* The name of the file that contains the boundary. */
+ uniqstr file;
+
+ /* 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;
+
+ /* 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)
+{
+ return (a.column == b.column
+ && a.line == b.line
+ && UNIQSTR_EQ (a.file, b.file));
+}
+
+/* A location, that is, a region of source code. */
+typedef struct
+{
+ /* Boundary just before the location starts. */
+ boundary start;
+
+ /* Boundary just after the location ends. */
+ boundary end;
+
+} location;
+
+# define GRAM_LTYPE location
+
+# define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
+extern location const empty_location;
+
+/* 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.
+ Warning: uses quotearg's slot 3. */
+unsigned location_print (location loc, FILE *out);
+
+/* 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 (location loc, FILE *out);
+
+/* 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/contrib/tools/bison/src/main.c b/contrib/tools/bison/src/main.c
new file mode 100644
index 0000000000..f391a9417e
--- /dev/null
+++ b/contrib/tools/bison/src/main.c
@@ -0,0 +1,226 @@
+/* Top level entry point of Bison.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 1995, 2000-2002, 2004-2013 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 <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"
+#include "files.h"
+#include "getargs.h"
+#include "gram.h"
+#include "lalr.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"
+
+
+int
+main (int argc, char *argv[])
+{
+ set_program_name (argv[0]);
+ setlocale (LC_ALL, "");
+#if 0
+ (void) bindtextdomain (PACKAGE, LOCALEDIR);
+ (void) bindtextdomain ("bison-runtime", LOCALEDIR);
+ (void) textdomain (PACKAGE);
+#endif
+
+ {
+ char const *cp = getenv ("LC_CTYPE");
+ if (cp && STREQ (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 ();
+ complain_init ();
+
+ getargs (argc, argv);
+
+ timevar_report = trace_flag & trace_time;
+ init_timevar ();
+ timevar_start (TV_TOTAL);
+
+ if (trace_flag & trace_bitsets)
+ bitset_stats_enable ();
+
+ /* 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. */
+
+ timevar_push (TV_READER);
+ reader ();
+ timevar_pop (TV_READER);
+
+ if (complaint_status == status_complaint)
+ goto finish;
+
+ /* Find useless nonterminals and productions and reduce the grammar. */
+ timevar_push (TV_REDUCE);
+ reduce_grammar ();
+ timevar_pop (TV_REDUCE);
+
+ /* Record other info about the grammar. In files derives and
+ nullable. */
+ timevar_push (TV_SETS);
+ derives_compute ();
+ nullable_compute ();
+ timevar_pop (TV_SETS);
+
+ /* Compute LR(0) parser states. See state.h for more info. */
+ timevar_push (TV_LR0);
+ generate_states ();
+ timevar_pop (TV_LR0);
+
+ /* 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
+ 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-state"))
+ {
+ 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);
+
+ /* Compute the parser tables. */
+ timevar_push (TV_ACTIONS);
+ tables_generate ();
+ timevar_pop (TV_ACTIONS);
+
+ grammar_rules_useless_report (_("rule useless in parser due to conflicts"));
+
+ print_precedence_warnings ();
+
+ /* Output file names. */
+ compute_output_file_names ();
+
+ /* Output the detailed report on the grammar. */
+ if (report_flag)
+ {
+ timevar_push (TV_REPORT);
+ print_results ();
+ timevar_pop (TV_REPORT);
+ }
+
+ /* Output the graph. */
+ if (graph_flag)
+ {
+ timevar_push (TV_GRAPH);
+ print_graph ();
+ 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_status == status_complaint)
+ goto finish;
+
+ /* Lookahead tokens are no longer needed. */
+ timevar_push (TV_FREE);
+ lalr_free ();
+ timevar_pop (TV_FREE);
+
+ /* Output the tables and the parser to ftable. In file output. */
+ timevar_push (TV_PARSER);
+ output ();
+ timevar_pop (TV_PARSER);
+
+ timevar_push (TV_FREE);
+ nullable_free ();
+ derives_free ();
+ tables_free ();
+ states_free ();
+ 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. */
+ gram_scanner_free ();
+ muscle_free ();
+ uniqstrs_free ();
+ code_scanner_free ();
+ skel_scanner_free ();
+ quotearg_free ();
+ timevar_pop (TV_FREE);
+
+ if (trace_flag & trace_bitsets)
+ bitset_stats_dump (stderr);
+
+ finish:
+
+ /* Stop timing and print the times. */
+ timevar_stop (TV_TOTAL);
+ timevar_print (stderr);
+
+ cleanup_caret ();
+
+ return complaint_status ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/contrib/tools/bison/src/muscle-tab.c b/contrib/tools/bison/src/muscle-tab.c
new file mode 100644
index 0000000000..ca63ed21ad
--- /dev/null
+++ b/contrib/tools/bison/src/muscle-tab.c
@@ -0,0 +1,775 @@
+/* Muscle table manager for Bison.
+
+ Copyright (C) 2001-2013 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"
+
+muscle_kind
+muscle_kind_new (char const *k)
+{
+ if (STREQ (k, "code"))
+ return muscle_code;
+ else if (STREQ (k, "keyword"))
+ return muscle_keyword;
+ else if (STREQ (k, "string"))
+ return muscle_string;
+ aver (0);
+}
+
+char const *
+muscle_kind_string (muscle_kind k)
+{
+ switch (k)
+ {
+ case muscle_code: return "code";
+ case muscle_keyword: return "keyword";
+ case muscle_string: return "string";
+ }
+ aver (0);
+}
+
+
+/* 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_kind kind;
+} muscle_entry;
+
+
+/* The name of muscle for the %define variable VAR (corresponding to
+ FIELD, if defined). */
+static uniqstr
+muscle_name (char const *var, char const *field)
+{
+ if (field)
+ return uniqstr_vsprintf("percent_define_%s(%s)", field, var);
+ else
+ return uniqstr_vsprintf("percent_define(%s)", var);
+}
+
+/* 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 STREQ (m1->key, m2->key);
+}
+
+static size_t
+hash_muscle (const void *x, size_t tablesize)
+{
+ muscle_entry const *m = x;
+ return hash_string (m->key, tablesize);
+}
+
+/* Create a fresh muscle name KEY, and insert in the hash table. */
+static void *
+muscle_entry_new (char const *key)
+{
+ muscle_entry *res = xmalloc (sizeof *res);
+ res->key = key;
+ res->value = NULL;
+ res->storage = NULL;
+ if (!hash_insert (muscle_table, res))
+ xalloc_die ();
+ return res;
+}
+
+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);
+}
+
+
+void
+muscle_free (void)
+{
+ hash_free (muscle_table);
+ obstack_free (&muscle_obstack, NULL);
+}
+
+/* Look for the muscle named KEY. Return NULL if does not exist. */
+static
+muscle_entry *
+muscle_lookup (char const *key)
+{
+ muscle_entry probe;
+ probe.key = key;
+ return hash_lookup (muscle_table, &probe);
+}
+
+
+void
+muscle_insert (char const *key, char const *value)
+{
+ muscle_entry *entry = muscle_lookup (key);
+ if (entry)
+ free (entry->storage);
+ else
+ /* First insertion in the hash. */
+ entry = muscle_entry_new (key);
+ 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. If VALUE does not end
+ with TERMINATOR, append one. */
+
+static void
+muscle_grow (const char *key, const char *val,
+ const char *separator, const char *terminator)
+{
+ muscle_entry *entry = muscle_lookup (key);
+ size_t vals = strlen (val);
+ size_t terms = strlen (terminator);
+
+ if (entry)
+ {
+ obstack_sgrow (&muscle_obstack, entry->value);
+ obstack_sgrow (&muscle_obstack, separator);
+ free (entry->storage);
+ }
+ else
+ entry = muscle_entry_new (key);
+
+ obstack_sgrow (&muscle_obstack, val);
+
+ if (terms <= vals
+ && STRNEQ (val + vals - terms, terminator))
+ obstack_sgrow (&muscle_obstack, terminator);
+
+ {
+ char *new_val = obstack_finish0 (&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, ")[");
+ extension = obstack_finish0 (&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", "\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, "]");
+ pair = obstack_finish0 (&muscle_obstack);
+ muscle_grow (muscle, pair, ",\n", "");
+ obstack_free (&muscle_obstack, pair);
+}
+
+
+char const *
+muscle_find_const (char const *key)
+{
+ muscle_entry *entry = muscle_lookup (key);
+ return entry ? entry->value : NULL;
+}
+
+
+char *
+muscle_find (char const *key)
+{
+ muscle_entry *entry = muscle_lookup (key);
+ if (entry)
+ {
+ aver (entry->value == entry->storage);
+ return entry->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_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column);
+ extension = obstack_finish0 (&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 = muscle_find_const (key);
+ char *value_decoded;
+ char *result;
+
+ 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 *value)
+{
+ location loc;
+ aver (value);
+ aver (*value == '[');
+ aver (*++value == '[');
+ while (*++value)
+ switch (*value)
+ {
+ COMMON_DECODE (value)
+ case '[':
+ aver (false);
+ break;
+ case ']':
+ {
+ char *boundary_str;
+ aver (*++value == ']');
+ boundary_str = obstack_finish0 (&muscle_obstack);
+ switch (*++value)
+ {
+ case ',':
+ boundary_set_from_string (&loc.start, boundary_str);
+ obstack_free (&muscle_obstack, boundary_str);
+ aver (*++value == ' ');
+ aver (*++value == '[');
+ aver (*++value == '[');
+ 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, "]]", "", "");
+}
+
+
+/** Return an allocated string that represents the %define directive
+ that performs the assignment.
+
+ @param assignment "VAR", or "VAR=VAL".
+ @param value default value if VAL \a assignment has no '='.
+
+ For instance:
+ "foo", NULL => "%define foo"
+ "foo", "baz" => "%define foo baz"
+ "foo=bar", NULL => "%define foo bar"
+ "foo=bar", "baz" => "%define foo bar"
+ "foo=", NULL => "%define foo"
+ "foo=", "baz" => "%define foo"
+ */
+
+static
+char *
+define_directive (char const *assignment, char const *value)
+{
+ char *eq = strchr (assignment, '=');
+ char const *fmt = !eq && value && *value ? "%%define %s %s" : "%%define %s";
+ char *res = xmalloc (strlen (fmt) + strlen (assignment)
+ + (value ? strlen (value) : 0));
+ sprintf (res, fmt, assignment, value);
+ eq = strchr (res, '=');
+ if (eq)
+ *eq = eq[1] ? ' ' : '\0';
+ return res;
+}
+
+/** If the \a variable name is obsolete, return the name to use,
+ * otherwise \a variable. If the \a value is obsolete, update it too.
+ *
+ * Allocates the returned value. */
+static
+char *
+muscle_percent_variable_update (char const *variable, location variable_loc,
+ char const **value)
+{
+ typedef struct
+ {
+ const char *obsolete;
+ const char *updated;
+ } conversion_type;
+ const conversion_type conversion[] =
+ {
+ { "api.push_pull", "api.push-pull", },
+ { "api.tokens.prefix", "api.token.prefix", },
+ { "lex_symbol", "api.token.constructor", },
+ { "location_type", "api.location.type", },
+ { "lr.default-reductions", "lr.default-reduction", },
+ { "lr.keep-unreachable-states", "lr.keep-unreachable-state", },
+ { "lr.keep_unreachable_states", "lr.keep-unreachable-state", },
+ { "namespace", "api.namespace", },
+ { "stype", "api.value.type", },
+ { "variant=", "api.value.type=variant", },
+ { "variant=true", "api.value.type=variant", },
+ { NULL, NULL, }
+ };
+ conversion_type const *c;
+ char* res;
+ char* eq2;
+ for (c = conversion; c->obsolete; ++c)
+ {
+ char const *eq = strchr (c->obsolete, '=');
+ if (eq
+ ? (!strncmp (c->obsolete, variable, eq - c->obsolete)
+ && STREQ (eq + 1, *value))
+ : STREQ (c->obsolete, variable))
+ {
+ char *old = define_directive (c->obsolete, *value);
+ char *upd = define_directive (c->updated, *value);
+ deprecated_directive (&variable_loc, old, upd);
+ free (old);
+ free (upd);
+ res = xstrdup (c->updated);
+ {
+ eq2 = strchr (res, '=');
+ if (eq2)
+ {
+ *eq2 = '\0';
+ *value = eq2 + 1;
+ }
+ }
+ return res;
+ }
+ }
+ return xstrdup (variable);
+}
+
+void
+muscle_percent_define_insert (char const *var, location variable_loc,
+ muscle_kind kind,
+ char const *value,
+ muscle_percent_define_how how)
+{
+ /* Backward compatibility. */
+ char *variable = muscle_percent_variable_update (var, variable_loc, &value);
+ uniqstr name = muscle_name (variable, NULL);
+ uniqstr loc_name = muscle_name (variable, "loc");
+ uniqstr syncline_name = muscle_name (variable, "syncline");
+ uniqstr how_name = muscle_name (variable, "how");
+ uniqstr kind_name = muscle_name (variable, "kind");
+ location loc;
+
+ /* Command-line options are processed before the grammar file. */
+ if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
+ && muscle_find_const (name))
+ {
+ muscle_percent_define_how how_old = atoi (muscle_find_const (how_name));
+ unsigned i = 0;
+ if (how_old == MUSCLE_PERCENT_DEFINE_F)
+ goto end;
+ complain_indent (&variable_loc, complaint, &i,
+ _("%%define variable %s redefined"),
+ quote (variable));
+ i += SUB_INDENT;
+ loc = muscle_percent_define_get_loc (variable);
+ complain_indent (&loc, complaint, &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);
+ MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
+ end:
+ free (variable);
+}
+
+/* This is used for backward compatibility, e.g., "%define api.pure"
+ supersedes "%pure-parser". */
+void
+muscle_percent_define_ensure (char const *variable, location loc,
+ bool value)
+{
+ uniqstr name = muscle_name (variable, NULL);
+ char const *val = value ? "" : "false";
+
+ /* Don't complain is VARIABLE is already defined, but be sure to set
+ its value to VAL. */
+ if (!muscle_find_const (name)
+ || muscle_percent_define_flag_if (variable) != value)
+ muscle_percent_define_insert (variable, loc, muscle_keyword, val,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+}
+
+/* Mark %define VARIABLE as used. */
+static void
+muscle_percent_define_use (char const *variable)
+{
+ muscle_insert (muscle_name (variable, "bison_variables"), "");
+}
+
+/* The value of %define variable VARIABLE (corresponding to FIELD, if
+ defined). Do not register as used, but diagnose unset variables. */
+
+static
+char const *
+muscle_percent_define_get_raw (char const *variable, char const *field)
+{
+ uniqstr name = muscle_name (variable, field);
+ char const *res = muscle_find_const (name);
+ if (!res)
+ complain (NULL, fatal, _("%s: undefined %%define variable %s"),
+ "muscle_percent_define_get_raw", quote (variable));
+ return res;
+}
+
+char *
+muscle_percent_define_get (char const *variable)
+{
+ uniqstr name = muscle_name (variable, NULL);
+ char *value = string_decode (name);
+ if (!value)
+ value = xstrdup ("");
+ muscle_percent_define_use (variable);
+ return value;
+}
+
+/* The kind of VARIABLE. An error if undefined. */
+static muscle_kind
+muscle_percent_define_get_kind (char const *variable)
+{
+ return muscle_kind_new (muscle_percent_define_get_raw (variable, "kind"));
+}
+
+/* Check the kind of VARIABLE. An error if undefined. */
+static void
+muscle_percent_define_check_kind (char const *variable, muscle_kind kind)
+{
+ if (muscle_percent_define_get_kind (variable) != kind)
+ {
+ location loc = muscle_percent_define_get_loc (variable);
+ switch (kind)
+ {
+ case muscle_code:
+ complain (&loc, Wdeprecated,
+ "%%define variable '%s' requires '{...}' values",
+ variable);
+ break;
+ case muscle_keyword:
+ complain (&loc, Wdeprecated,
+ "%%define variable '%s' requires keyword values",
+ variable);
+ break;
+ case muscle_string:
+ complain (&loc, Wdeprecated,
+ "%%define variable '%s' requires '\"...\"' values",
+ variable);
+ break;
+ }
+ }
+}
+
+
+location
+muscle_percent_define_get_loc (char const *variable)
+{
+ return location_decode (muscle_percent_define_get_raw (variable, "loc"));
+}
+
+char const *
+muscle_percent_define_get_syncline (char const *variable)
+{
+ return muscle_percent_define_get_raw (variable, "syncline");
+}
+
+bool
+muscle_percent_define_ifdef (char const *variable)
+{
+ if (muscle_find_const (muscle_name (variable, NULL)))
+ {
+ muscle_percent_define_use (variable);
+ return true;
+ }
+ else
+ return false;
+}
+
+bool
+muscle_percent_define_flag_if (char const *variable)
+{
+ uniqstr invalid_boolean_name = muscle_name (variable, "invalid_boolean");
+ bool result = false;
+ location loc;
+
+ if (muscle_percent_define_ifdef (variable))
+ {
+ char *value = muscle_percent_define_get (variable);
+ muscle_percent_define_check_kind (variable, muscle_keyword);
+ if (value[0] == '\0' || STREQ (value, "true"))
+ result = true;
+ else if (STREQ (value, "false"))
+ result = false;
+ else if (!muscle_find_const (invalid_boolean_name))
+ {
+ muscle_insert (invalid_boolean_name, "");
+ loc = muscle_percent_define_get_loc (variable);
+ complain (&loc, complaint,
+ _("invalid value for %%define Boolean variable %s"),
+ quote (variable));
+ }
+ free (value);
+ }
+ else
+ complain (NULL, 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)
+{
+ uniqstr name = muscle_name (variable, NULL);
+ if (!muscle_find_const (name))
+ {
+ MUSCLE_INSERT_STRING (name, value);
+ MUSCLE_INSERT_STRING (muscle_name (variable, "kind"), "keyword");
+ {
+ uniqstr loc_name = muscle_name (variable, "loc");
+ location loc;
+ 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 (muscle_name (variable, "syncline"), "");
+ }
+}
+
+void
+muscle_percent_define_check_values (char const * const *values)
+{
+ for (; *values; ++values)
+ {
+ char const * const *variablep = values;
+ uniqstr name = muscle_name (*variablep, NULL);
+ char *value = string_decode (name);
+ muscle_percent_define_check_kind (*variablep, muscle_keyword);
+ if (value)
+ {
+ for (++values; *values; ++values)
+ {
+ if (STREQ (value, *values))
+ break;
+ }
+ if (!*values)
+ {
+ unsigned i = 0;
+ location loc = muscle_percent_define_get_loc (*variablep);
+ complain_indent (&loc, complaint, &i,
+ _("invalid value for %%define variable %s: %s"),
+ quote (*variablep), quote_n (1, value));
+ i += SUB_INDENT;
+ for (values = variablep + 1; *values; ++values)
+ complain_indent (&loc, complaint | no_caret | silent, &i,
+ _("accepted value: %s"), quote (*values));
+ }
+ else
+ {
+ while (*values)
+ ++values;
+ }
+ free (value);
+ }
+ else
+ complain (NULL, 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 = uniqstr_vsprintf("percent_code(%s)", 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"
+ "[[%s]])\n\n\n", entry->key, entry->value);
+ return true;
+}
+
+static bool
+muscle_m4_output_processor (void *entry, void *out)
+{
+ return muscle_m4_output (entry, out);
+}
+
+
+void
+muscles_m4_output (FILE *out)
+{
+ hash_do_for_each (muscle_table, muscle_m4_output_processor, out);
+}
diff --git a/contrib/tools/bison/src/muscle-tab.h b/contrib/tools/bison/src/muscle-tab.h
new file mode 100644
index 0000000000..2150327ba6
--- /dev/null
+++ b/contrib/tools/bison/src/muscle-tab.h
@@ -0,0 +1,218 @@
+/* Muscle table manager for Bison,
+
+ Copyright (C) 2001-2003, 2006-2013 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 <obstack.h>
+
+# include "location.h"
+
+/* The kind of value associated to this muscle, depending on the
+ syntax of the value: keyword (no delimiter, e.g., true), string
+ (double quotes, e.g., "foo.h"), or code (braces, e.g., {int}). */
+typedef enum
+{
+ muscle_code,
+ muscle_keyword,
+ muscle_string
+} muscle_kind;
+
+/* Conversion from string. */
+muscle_kind muscle_kind_new (char const *k);
+
+/* Conversion to string. */
+char const *muscle_kind_string (muscle_kind k);
+
+
+/* Create the MUSCLE_TABLE, and initialize it with default values.
+ Also set up the MUSCLE_OBSTACK. */
+void muscle_init (void);
+
+/* Insert (KEY, VALUE). If KEY already existed, overwrite the
+ previous value. Otherwise create as a muscle_string type. */
+void muscle_insert (char const *key, char const *value);
+
+/* 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);
+
+/* 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);
+
+/* Free all the memory consumed by the muscle machinery only. */
+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_INSERTF(Key, Format, Value) \
+ do { \
+ obstack_printf (&muscle_obstack, Format, Value); \
+ muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
+ } while (0)
+
+# define MUSCLE_INSERT_INT(Key, Value) \
+ MUSCLE_INSERTF (Key, "%d", Value)
+
+# define MUSCLE_INSERT_LONG_INT(Key, Value) \
+ MUSCLE_INSERTF (Key, "%ld", Value)
+
+/* Key -> Value, but don't apply escaping to Value. */
+# define MUSCLE_INSERT_STRING_RAW(Key, Value) \
+ MUSCLE_INSERTF (Key, "%s", Value)
+
+/* Key -> Value, applying M4 escaping to Value. */
+# define MUSCLE_INSERT_STRING(Key, Value) \
+ do { \
+ obstack_escape (&muscle_obstack, Value); \
+ muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
+ } while (0)
+
+/* Key -> Value, applying C escaping to Value (and then M4). */
+# define MUSCLE_INSERT_C_STRING(Key, Value) \
+ MUSCLE_INSERT_STRING (Key, quotearg_style (c_quoting_style, Value))
+
+
+/* Append VALUE to the current value of KEY, using muscle_grow. But
+ in addition, issue a synchronization line for the location LOC.
+ Be sure to append on a new line. */
+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,
+ muscle_kind kind,
+ char const *value,
+ muscle_percent_define_how how);
+
+/* Make sure that VARIABLE is set to the boolean VALUE. Warn on mismatches
+ only, but accept repeated declaration. Used for backward compatibility
+ between old directives such as %pure-parser, and the recommended use of
+ variables (%define api.pure). */
+void muscle_percent_define_ensure (char const *variable, location variable_loc,
+ bool value);
+
+/* 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);
+
+/* Output the definition of all the current muscles into a list of
+ m4_defines. */
+void muscles_m4_output (FILE *out);
+
+#endif /* not MUSCLE_TAB_H_ */
diff --git a/contrib/tools/bison/src/named-ref.c b/contrib/tools/bison/src/named-ref.c
new file mode 100644
index 0000000000..1693767918
--- /dev/null
+++ b/contrib/tools/bison/src/named-ref.c
@@ -0,0 +1,46 @@
+/* Named symbol references for Bison
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/named-ref.h b/contrib/tools/bison/src/named-ref.h
new file mode 100644
index 0000000000..84d02d7adb
--- /dev/null
+++ b/contrib/tools/bison/src/named-ref.h
@@ -0,0 +1,46 @@
+/* Named symbol references for Bison
+
+ Copyright (C) 2009-2013 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/contrib/tools/bison/src/nullable.c b/contrib/tools/bison/src/nullable.c
new file mode 100644
index 0000000000..a150f5f5c7
--- /dev/null
+++ b/contrib/tools/bison/src/nullable.c
@@ -0,0 +1,142 @@
+/* Calculate which nonterminals can expand into the null string for Bison.
+
+ Copyright (C) 1984, 1989, 2000-2006, 2009-2013 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/>. */
+
+
+/* Set up NULLABLE, a vector saying which nonterminals can expand into
+ the null string. NULLABLE[I - NTOKENS] is nonzero if symbol I can
+ do so. */
+
+#include <config.h>
+#include "system.h"
+
+#include "getargs.h"
+#include "gram.h"
+#include "nullable.h"
+#include "reduce.h"
+#include "symtab.h"
+
+/* Linked list of rules. */
+typedef struct rule_list
+{
+ struct rule_list *next;
+ rule *value;
+} rule_list;
+
+bool *nullable = NULL;
+
+static void
+nullable_print (FILE *out)
+{
+ int i;
+ fputs ("NULLABLE\n", out);
+ for (i = ntokens; i < nsyms; i++)
+ fprintf (out, " %s: %s\n", symbols[i]->tag,
+ nullable[i - ntokens] ? "yes" : "no");
+ fputs ("\n\n", out);
+}
+
+void
+nullable_compute (void)
+{
+ rule_number ruleno;
+ symbol_number *s1;
+ symbol_number *s2;
+ rule_list *p;
+
+ symbol_number *squeue = xnmalloc (nvars, sizeof *squeue);
+ size_t *rcount = xcalloc (nrules, sizeof *rcount);
+ /* RITEM contains all the rules, including useless productions.
+ Hence we must allocate room for useless nonterminals too. */
+ rule_list **rsets = xcalloc (nvars, sizeof *rsets);
+ /* This is said to be more elements than we actually use.
+ Supposedly NRITEMS - NRULES is enough. But why take the risk? */
+ rule_list *relts = xnmalloc (nritems + nvars + 1, sizeof *relts);
+
+ nullable = xcalloc (nvars, sizeof *nullable);
+
+ s1 = s2 = squeue;
+ p = relts;
+
+ for (ruleno = 0; ruleno < nrules; ++ruleno)
+ if (rules[ruleno].useful)
+ {
+ rule *rules_ruleno = &rules[ruleno];
+ if (rules_ruleno->rhs[0] >= 0)
+ {
+ /* This rule has a non empty RHS. */
+ item_number *rp = NULL;
+ bool any_tokens = false;
+ for (rp = rules_ruleno->rhs; *rp >= 0; ++rp)
+ if (ISTOKEN (*rp))
+ any_tokens = true;
+
+ /* This rule has only nonterminals: schedule it for the second
+ pass. */
+ if (!any_tokens)
+ for (rp = rules_ruleno->rhs; *rp >= 0; ++rp)
+ {
+ rcount[ruleno]++;
+ p->next = rsets[*rp - ntokens];
+ p->value = rules_ruleno;
+ rsets[*rp - ntokens] = p;
+ p++;
+ }
+ }
+ else
+ {
+ /* This rule has an empty RHS. */
+ aver (item_number_as_rule_number (rules_ruleno->rhs[0])
+ == ruleno);
+ if (rules_ruleno->useful
+ && ! nullable[rules_ruleno->lhs->number - ntokens])
+ {
+ nullable[rules_ruleno->lhs->number - ntokens] = true;
+ *s2++ = rules_ruleno->lhs->number;
+ }
+ }
+ }
+
+ while (s1 < s2)
+ for (p = rsets[*s1++ - ntokens]; p; p = p->next)
+ {
+ rule *r = p->value;
+ if (--rcount[r->number] == 0)
+ if (r->useful && ! nullable[r->lhs->number - ntokens])
+ {
+ nullable[r->lhs->number - ntokens] = true;
+ *s2++ = r->lhs->number;
+ }
+ }
+
+ free (squeue);
+ free (rcount);
+ free (rsets);
+ free (relts);
+
+ if (trace_flag & trace_sets)
+ nullable_print (stderr);
+}
+
+
+void
+nullable_free (void)
+{
+ free (nullable);
+}
diff --git a/contrib/tools/bison/src/nullable.h b/contrib/tools/bison/src/nullable.h
new file mode 100644
index 0000000000..63a8ae3f14
--- /dev/null
+++ b/contrib/tools/bison/src/nullable.h
@@ -0,0 +1,32 @@
+/* Part of the bison parser generator,
+
+ Copyright (C) 2000, 2002, 2009-2013 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 NULLABLE_H_
+# define NULLABLE_H_
+
+/* A vector saying which nonterminals can expand into the null string.
+ NULLABLE[I - NTOKENS] is nonzero if symbol I can do so. */
+extern bool *nullable;
+
+/* Set up NULLABLE. */
+extern void nullable_compute (void);
+
+/* Free NULLABLE. */
+extern void nullable_free (void);
+#endif /* !NULLABLE_H_ */
diff --git a/contrib/tools/bison/src/output.c b/contrib/tools/bison/src/output.c
new file mode 100644
index 0000000000..9f08095c6b
--- /dev/null
+++ b/contrib/tools/bison/src/output.c
@@ -0,0 +1,740 @@
+/* Output the generated parsing program for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 2000-2013 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 <concat-filename.h>
+#include <configmake.h>
+#include <filename.h>
+#include <get-errno.h>
+#include <quotearg.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 "output.h"
+#include "reader.h"
+#include "scan-code.h" /* max_left_semantic_context */
+#include "scan-skel.h"
+#include "symtab.h"
+#include "tables.h"
+
+#include "uniqstr.h"
+
+#include <contrib/tools/bison/arcadia_root.h>
+
+#ifndef M4
+#define M4 (m4_path)
+#endif
+
+#ifndef PKGDATADIR
+#define STR(a) XSTR(a)
+#define XSTR(a) #a
+
+const char*
+default_pkgdatadir()
+{
+ const char* arc_path = getenv("ARCADIA_ROOT_DISTBUILD");
+ if (arc_path == NULL)
+ arc_path = ArcadiaRoot();
+ return uniqstr_vsprintf("%s/" STR(BISON_DATA_DIR), arc_path);
+}
+#define PKGDATADIR (default_pkgdatadir())
+#endif
+
+static struct obstack format_obstack;
+
+
+/*-------------------------------------------------------------------.
+| Create a function NAME which associates to the muscle NAME the |
+| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
+| TYPE), and to the muscle NAME_max, the max value of the |
+| TABLE_DATA. |
+`-------------------------------------------------------------------*/
+
+
+#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
+ \
+static void \
+Name (char const *name, \
+ Type *table_data, \
+ Type first, \
+ int begin, \
+ int end) \
+{ \
+ Type min = first; \
+ Type max = first; \
+ long int lmin; \
+ long int lmax; \
+ int i; \
+ int j = 1; \
+ \
+ obstack_printf (&format_obstack, "%6d", first); \
+ for (i = begin; i < end; ++i) \
+ { \
+ obstack_1grow (&format_obstack, ','); \
+ if (j >= 10) \
+ { \
+ obstack_sgrow (&format_obstack, "\n "); \
+ j = 1; \
+ } \
+ else \
+ ++j; \
+ obstack_printf (&format_obstack, "%6d", table_data[i]); \
+ if (table_data[i] < min) \
+ min = table_data[i]; \
+ if (max < table_data[i]) \
+ max = table_data[i]; \
+ } \
+ muscle_insert (name, obstack_finish0 (&format_obstack)); \
+ \
+ lmin = min; \
+ lmax = max; \
+ /* Build 'NAME_min' and 'NAME_max' in the obstack. */ \
+ obstack_printf (&format_obstack, "%s_min", name); \
+ MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \
+ obstack_printf (&format_obstack, "%s_max", name); \
+ MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
+}
+
+GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned int)
+GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, int)
+GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_base_table, base_number)
+GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_number)
+GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_symbol_number_table, symbol_number)
+GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
+
+/*----------------------------------------------------------------.
+| Print to OUT a representation of CP quoted and escaped for M4. |
+`----------------------------------------------------------------*/
+
+static void
+quoted_output (FILE *out, char const *cp)
+{
+ fprintf (out, "[[");
+
+ for (; *cp; cp++)
+ switch (*cp)
+ {
+ case '$': fputs ("$][", out); break;
+ case '@': fputs ("@@", out); break;
+ case '[': fputs ("@{", out); break;
+ case ']': fputs ("@}", 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 |
+| toknum. |
+`------------------------------------------------------------------*/
+
+static void
+prepare_symbols (void)
+{
+ MUSCLE_INSERT_INT ("tokens_number", ntokens);
+ MUSCLE_INSERT_INT ("nterms_number", nvars);
+ MUSCLE_INSERT_INT ("symbols_number", nsyms);
+ MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
+ MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
+
+ muscle_insert_symbol_number_table ("translate",
+ token_translations,
+ token_translations[0],
+ 1, max_user_token_number + 1);
+
+ /* tname -- token names. */
+ {
+ 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 *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;
+
+ if (j + width > 75)
+ {
+ obstack_sgrow (&format_obstack, "\n ");
+ j = 1;
+ }
+
+ if (i)
+ obstack_1grow (&format_obstack, ' ');
+ obstack_escape (&format_obstack, cp);
+ free (cp);
+ obstack_1grow (&format_obstack, ',');
+ j += width;
+ }
+ free (qo);
+ obstack_sgrow (&format_obstack, " ]b4_null[");
+
+ /* Finish table and store. */
+ muscle_insert ("tname", obstack_finish0 (&format_obstack));
+ }
+
+ /* Output YYTOKNUM. */
+ {
+ int i;
+ int *values = xnmalloc (ntokens, sizeof *values);
+ for (i = 0; i < ntokens; ++i)
+ values[i] = symbols[i]->user_token_number;
+ muscle_insert_int_table ("toknum", values,
+ values[0], 1, ntokens);
+ free (values);
+ }
+}
+
+
+/*----------------------------------------------------------------.
+| Prepare the muscles related to the rules: r1, r2, rline, dprec, |
+| merger, immediate. |
+`----------------------------------------------------------------*/
+
+static void
+prepare_rules (void)
+{
+ unsigned int *rline = xnmalloc (nrules, sizeof *rline);
+ symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
+ unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
+ int *dprec = xnmalloc (nrules, sizeof *dprec);
+ int *merger = xnmalloc (nrules, sizeof *merger);
+ int *immediate = xnmalloc (nrules, sizeof *immediate);
+
+ rule_number r;
+ for (r = 0; r < nrules; ++r)
+ {
+ /* LHS of the rule R. */
+ r1[r] = rules[r].lhs->number;
+ /* Length of rule R's RHS. */
+ r2[r] = rule_rhs_length (&rules[r]);
+ /* Line where rule was defined. */
+ rline[r] = rules[r].location.start.line;
+ /* Dynamic precedence (GLR). */
+ dprec[r] = rules[r].dprec;
+ /* Merger-function index (GLR). */
+ merger[r] = rules[r].merger;
+ /* Immediate reduction flags (GLR). */
+ immediate[r] = rules[r].is_predicate;
+ }
+
+ muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
+ muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
+ muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
+ muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
+ muscle_insert_int_table ("merger", merger, 0, 0, nrules);
+ muscle_insert_int_table ("immediate", immediate, 0, 0, nrules);
+
+ MUSCLE_INSERT_INT ("rules_number", nrules);
+ MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
+
+ free (rline);
+ free (r1);
+ free (r2);
+ free (dprec);
+ free (merger);
+ free (immediate);
+}
+
+/*--------------------------------------------.
+| Prepare the muscles related to the states. |
+`--------------------------------------------*/
+
+static void
+prepare_states (void)
+{
+ state_number i;
+ symbol_number *values = xnmalloc (nstates, sizeof *values);
+ for (i = 0; i < nstates; ++i)
+ values[i] = states[i]->accessing_symbol;
+ muscle_insert_symbol_number_table ("stos", values,
+ 0, 1, nstates);
+ free (values);
+
+ MUSCLE_INSERT_INT ("last", high);
+ MUSCLE_INSERT_INT ("final_state_number", final_state->number);
+ MUSCLE_INSERT_INT ("states_number", nstates);
+}
+
+
+/*-------------------------------------------------------.
+| Compare two symbols by type-name, and then by number. |
+`-------------------------------------------------------*/
+
+static int
+symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
+{
+ int res = uniqstr_cmp ((*lhs)->type_name, (*rhs)->type_name);
+ if (!res)
+ res = (*lhs)->number - (*rhs)->number;
+ return res;
+}
+
+
+/*----------------------------------------------------------------.
+| Return a (malloc'ed) table of the symbols sorted by type-name. |
+`----------------------------------------------------------------*/
+
+static symbol **
+symbols_by_type_name (void)
+{
+ typedef int (*qcmp_type) (const void *, const void *);
+ symbol **res = xmemdup (symbols, nsyms * sizeof *res);
+ qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp);
+ return res;
+}
+
+
+/*------------------------------------------------------------------.
+| Define b4_type_names, which is a list of (lists of the numbers of |
+| symbols with same type-name). |
+`------------------------------------------------------------------*/
+
+static void
+type_names_output (FILE *out)
+{
+ int i;
+ symbol **syms = symbols_by_type_name ();
+ fputs ("m4_define([b4_type_names],\n[", out);
+ for (i = 0; i < nsyms; /* nothing */)
+ {
+ /* The index of the first symbol of the current type-name. */
+ int i0 = i;
+ fputs (i ? ",\n[" : "[", out);
+ for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
+ fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
+ fputs ("]", out);
+ }
+ fputs ("])\n\n", out);
+ free (syms);
+}
+
+
+/*-------------------------------------.
+| The list of all the symbol numbers. |
+`-------------------------------------*/
+
+static void
+symbol_numbers_output (FILE *out)
+{
+ int i;
+ fputs ("m4_define([b4_symbol_numbers],\n[", out);
+ for (i = 0; i < nsyms; ++i)
+ fprintf (out, "%s[%d]", i ? ", " : "", i);
+ fputs ("])\n\n", out);
+}
+
+
+/*---------------------------------.
+| Output the user actions to OUT. |
+`---------------------------------*/
+
+static void
+user_actions_output (FILE *out)
+{
+ rule_number r;
+
+ fputs ("m4_define([b4_actions], \n[", out);
+ for (r = 0; r < nrules; ++r)
+ if (rules[r].action)
+ {
+ fprintf (out, "b4_%scase(%d, [b4_syncline(%d, ",
+ rules[r].is_predicate ? "predicate_" : "",
+ r + 1, rules[r].action_location.start.line);
+ string_output (out, rules[r].action_location.start.file);
+ fprintf (out, ")\n[ %s]])\n\n", rules[r].action);
+ }
+ fputs ("])\n\n", out);
+}
+
+/*------------------------------------.
+| Output the merge functions to OUT. |
+`------------------------------------*/
+
+static void
+merger_output (FILE *out)
+{
+ int n;
+ merger_list* p;
+
+ fputs ("m4_define([b4_mergers], \n[[", out);
+ for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
+ {
+ if (p->type[0] == '\0')
+ fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
+ n, p->name);
+ else
+ fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
+ n, p->type, p->name);
+ }
+ fputs ("]])\n\n", out);
+}
+
+
+/*---------------------------------------------.
+| Prepare the muscles for symbol definitions. |
+`---------------------------------------------*/
+
+static void
+prepare_symbol_definitions (void)
+{
+ int i;
+ for (i = 0; i < nsyms; ++i)
+ {
+ symbol *sym = symbols[i];
+ const char *key;
+ const char *value;
+
+#define SET_KEY(Entry) \
+ obstack_printf (&format_obstack, "symbol(%d, %s)", \
+ i, Entry); \
+ key = obstack_finish0 (&format_obstack);
+
+#define SET_KEY2(Entry, Suffix) \
+ obstack_printf (&format_obstack, "symbol(%d, %s_%s)", \
+ i, Entry, Suffix); \
+ key = obstack_finish0 (&format_obstack);
+
+ /* Whether the symbol has an identifier. */
+ value = symbol_id_get (sym);
+ SET_KEY ("has_id");
+ MUSCLE_INSERT_INT (key, !!value);
+
+ /* Its identifier. */
+ SET_KEY ("id");
+ MUSCLE_INSERT_STRING (key, value ? value : "");
+
+ /* Its tag. Typically for documentation purpose. */
+ SET_KEY ("tag");
+ MUSCLE_INSERT_STRING (key, sym->tag);
+
+ SET_KEY ("user_number");
+ MUSCLE_INSERT_INT (key, sym->user_token_number);
+
+ SET_KEY ("is_token");
+ MUSCLE_INSERT_INT (key,
+ i < ntokens && sym != errtoken && sym != undeftoken);
+
+ SET_KEY ("number");
+ MUSCLE_INSERT_INT (key, sym->number);
+
+ SET_KEY ("has_type");
+ MUSCLE_INSERT_INT (key, !!sym->type_name);
+
+ SET_KEY ("type");
+ MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
+
+ {
+ int j;
+ for (j = 0; j < CODE_PROPS_SIZE; ++j)
+ {
+ /* "printer", not "%printer". */
+ char const *pname = code_props_type_string (j) + 1;
+ code_props const *p = symbol_code_props_get (sym, j);
+ SET_KEY2 ("has", pname);
+ MUSCLE_INSERT_INT (key, !!p->code);
+
+ if (p->code)
+ {
+ SET_KEY2 (pname, "file");
+ MUSCLE_INSERT_STRING (key, p->location.start.file);
+
+ SET_KEY2 (pname, "line");
+ MUSCLE_INSERT_INT (key, p->location.start.line);
+
+ SET_KEY (pname);
+ MUSCLE_INSERT_STRING_RAW (key, p->code);
+ }
+ }
+ }
+#undef SET_KEY2
+#undef SET_KEY
+ }
+}
+
+
+static void
+prepare_actions (void)
+{
+ /* Figure out the actions for the specified state, indexed by
+ lookahead token type. */
+
+ muscle_insert_rule_number_table ("defact", yydefact,
+ yydefact[0], 1, nstates);
+
+ /* Figure out what to do after reducing with each rule, depending on
+ the saved state from before the beginning of parsing the data
+ that matched this rule. */
+ muscle_insert_state_number_table ("defgoto", yydefgoto,
+ yydefgoto[0], 1, nsyms - ntokens);
+
+
+ /* Output PACT. */
+ muscle_insert_base_table ("pact", base,
+ base[0], 1, nstates);
+ MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
+
+ /* Output PGOTO. */
+ muscle_insert_base_table ("pgoto", base,
+ base[nstates], nstates + 1, nvectors);
+
+ muscle_insert_base_table ("table", table,
+ table[0], 1, high + 1);
+ MUSCLE_INSERT_INT ("table_ninf", table_ninf);
+
+ muscle_insert_base_table ("check", check,
+ check[0], 1, high + 1);
+
+ /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
+ YYPACT) so that in states with unresolved conflicts, the default
+ reduction is not used in the conflicted entries, so that there is
+ a place to put a conflict pointer.
+
+ This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
+ parser, so we could avoid accidents by not writing them out in
+ that case. Nevertheless, it seems even better to be able to use
+ the GLR skeletons even without the non-deterministic tables. */
+ muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
+ conflict_table[0], 1, high + 1);
+ muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
+ 0, 1, conflict_list_cnt);
+}
+
+
+/*--------------------------------------------.
+| Output the definitions of all the muscles. |
+`--------------------------------------------*/
+
+static void
+muscles_output (FILE *out)
+{
+ fputs ("m4_init()\n", out);
+ merger_output (out);
+ symbol_numbers_output (out);
+ type_names_output (out);
+ user_actions_output (out);
+ /* Must be last. */
+ muscles_m4_output (out);
+}
+
+/*---------------------------.
+| Call the skeleton parser. |
+`---------------------------*/
+
+#define M4_GNU_OPTION "--gnu"
+
+static void
+output_skeleton (void)
+{
+ int filter_fd[2];
+ pid_t pid;
+
+ /* Compute the names of the package data dir and skeleton files. */
+ char const *m4 = (m4 = getenv ("M4")) ? m4 : M4;
+ char const *datadir = pkgdatadir ();
+ char *m4sugar = xconcatenated_filename (datadir, "m4sugar/m4sugar.m4", NULL);
+ char *m4bison = xconcatenated_filename (datadir, "bison.m4", NULL);
+ char *skel = (IS_PATH_WITH_DIR (skeleton)
+ ? xstrdup (skeleton)
+ : xconcatenated_filename (datadir, skeleton, NULL));
+
+ /* 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 (m4sugar, "r"));
+
+ /* Create an m4 subprocess connected to us via two pipes. */
+
+ if (trace_flag & trace_tools)
+ fprintf (stderr, "running: %s %s - %s %s\n",
+ m4, m4sugar, m4bison, skel);
+
+ /* 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.
+
+ See the thread starting at
+ <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
+ for details. */
+ {
+ char const *argv[10];
+ 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++] = datadir;
+ if (trace_flag & trace_m4)
+ argv[i++] = "-dV";
+ argv[i++] = m4sugar;
+ argv[i++] = "-";
+ argv[i++] = m4bison;
+ argv[i++] = skel;
+ 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 (m4sugar);
+ free (m4bison);
+ free (skel);
+
+ if (trace_flag & trace_muscles)
+ muscles_output (stderr);
+ {
+ FILE *out = xfdopen (filter_fd[1], "w");
+ muscles_output (out);
+ xfclose (out);
+ }
+
+ /* Read and process m4's output. */
+ timevar_push (TV_M4);
+ {
+ FILE *in = xfdopen (filter_fd[0], "r");
+ 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);
+ }
+ 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 *cp = getenv ("BISON_USE_PUSH_FOR_PULL");
+ bool use_push_for_pull_flag = cp && *cp && strtol (cp, 0, 10);
+
+ /* Flags. */
+ MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
+ MUSCLE_INSERT_BOOL ("glr_flag", glr_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. */
+ 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);
+ DEFINE (spec_defines_file);
+ DEFINE (spec_file_prefix);
+ DEFINE (spec_graph_file);
+ DEFINE (spec_name_prefix);
+ DEFINE (spec_outfile);
+ DEFINE (spec_verbose_file);
+#undef DEFINE
+
+ /* 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", pkgdatadir ());
+ }
+}
+
+
+/*----------------------------------------------------------.
+| Output the parsing tables and the parser code to ftable. |
+`----------------------------------------------------------*/
+
+void
+output (void)
+{
+ obstack_init (&format_obstack);
+
+ prepare_symbols ();
+ prepare_rules ();
+ prepare_states ();
+ prepare_actions ();
+ prepare_symbol_definitions ();
+
+ prepare ();
+
+ /* Process the selected skeleton file. */
+ output_skeleton ();
+
+ obstack_free (&format_obstack, NULL);
+}
+
+char const *
+pkgdatadir (void)
+{
+ char const *cp = getenv ("BISON_PKGDATADIR");
+ return cp ? cp : PKGDATADIR;
+}
diff --git a/contrib/tools/bison/src/output.h b/contrib/tools/bison/src/output.h
new file mode 100644
index 0000000000..63a0ca803a
--- /dev/null
+++ b/contrib/tools/bison/src/output.h
@@ -0,0 +1,30 @@
+/* Output the generated parsing program for bison,
+
+ Copyright (C) 2000-2003, 2006-2007, 2009-2013 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 OUTPUT_H_
+# define OUTPUT_H_
+
+/* Output the parsing tables and the parser code to FTABLE. */
+void output (void);
+
+/* Where our data files are installed. */
+char const *pkgdatadir (void);
+
+#endif /* !OUTPUT_H_ */
diff --git a/contrib/tools/bison/src/parse-gram.c b/contrib/tools/bison/src/parse-gram.c
new file mode 100644
index 0000000000..5b862667e9
--- /dev/null
+++ b/contrib/tools/bison/src/parse-gram.c
@@ -0,0 +1,3106 @@
+/* A Bison parser, made by GNU Bison 3.0. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 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/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ 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. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 2
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* "%code top" blocks. */
+#line 27 "src/parse-gram.y" /* yacc.c:316 */
+
+ /* On column 0 to please syntax-check. */
+#include <config.h>
+#include "string--.h"
+
+#line 68 "src/parse-gram.c" /* yacc.c:316 */
+/* 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 yydebug gram_debug
+#define yynerrs gram_nerrs
+
+
+/* Copy the first part of user declarations. */
+
+#line 82 "src/parse-gram.c" /* yacc.c:339 */
+
+# 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
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "src/parse-gram.h". */
+#ifndef YY_GRAM_SRC_PARSE_GRAM_H_INCLUDED
+# define YY_GRAM_SRC_PARSE_GRAM_H_INCLUDED
+/* Debug 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
+/* "%code requires" blocks. */
+#line 21 "src/parse-gram.y" /* yacc.c:355 */
+
+ #include "symlist.h"
+ #include "symtab.h"
+#line 221 "src/parse-gram.y" /* yacc.c:355 */
+
+ typedef enum
+ {
+ param_none = 0,
+ param_lex = 1 << 0,
+ param_parse = 1 << 1,
+ param_both = param_lex | param_parse
+ } param_type;
+#line 645 "src/parse-gram.y" /* yacc.c:355 */
+#include "muscle-tab.h"
+
+#line 136 "src/parse-gram.c" /* yacc.c:355 */
+
+/* Token type. */
+#ifndef GRAM_TOKENTYPE
+# define GRAM_TOKENTYPE
+ enum gram_tokentype
+ {
+ GRAM_EOF = 0,
+ STRING = 258,
+ PERCENT_TOKEN = 259,
+ PERCENT_NTERM = 260,
+ PERCENT_TYPE = 261,
+ PERCENT_DESTRUCTOR = 262,
+ PERCENT_PRINTER = 263,
+ PERCENT_LEFT = 264,
+ PERCENT_RIGHT = 265,
+ PERCENT_NONASSOC = 266,
+ PERCENT_PRECEDENCE = 267,
+ PERCENT_PREC = 268,
+ PERCENT_DPREC = 269,
+ PERCENT_MERGE = 270,
+ PERCENT_CODE = 271,
+ PERCENT_DEFAULT_PREC = 272,
+ PERCENT_DEFINE = 273,
+ PERCENT_DEFINES = 274,
+ PERCENT_ERROR_VERBOSE = 275,
+ PERCENT_EXPECT = 276,
+ PERCENT_EXPECT_RR = 277,
+ PERCENT_FLAG = 278,
+ PERCENT_FILE_PREFIX = 279,
+ PERCENT_GLR_PARSER = 280,
+ PERCENT_INITIAL_ACTION = 281,
+ PERCENT_LANGUAGE = 282,
+ PERCENT_NAME_PREFIX = 283,
+ PERCENT_NO_DEFAULT_PREC = 284,
+ PERCENT_NO_LINES = 285,
+ PERCENT_NONDETERMINISTIC_PARSER = 286,
+ PERCENT_OUTPUT = 287,
+ PERCENT_REQUIRE = 288,
+ PERCENT_SKELETON = 289,
+ PERCENT_START = 290,
+ PERCENT_TOKEN_TABLE = 291,
+ PERCENT_VERBOSE = 292,
+ PERCENT_YACC = 293,
+ BRACED_CODE = 294,
+ BRACED_PREDICATE = 295,
+ BRACKETED_ID = 296,
+ CHAR = 297,
+ EPILOGUE = 298,
+ EQUAL = 299,
+ ID = 300,
+ ID_COLON = 301,
+ PERCENT_PERCENT = 302,
+ PIPE = 303,
+ PROLOGUE = 304,
+ SEMICOLON = 305,
+ TAG = 306,
+ TAG_ANY = 307,
+ TAG_NONE = 308,
+ INT = 309,
+ PERCENT_PARAM = 310,
+ PERCENT_UNION = 311,
+ PERCENT_EMPTY = 312
+ };
+#endif
+
+/* Value type. */
+#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
+typedef union GRAM_STYPE GRAM_STYPE;
+union GRAM_STYPE
+{
+#line 182 "src/parse-gram.y" /* yacc.c:355 */
+unsigned char character;
+#line 186 "src/parse-gram.y" /* yacc.c:355 */
+char *code;
+#line 191 "src/parse-gram.y" /* yacc.c:355 */
+uniqstr uniqstr;
+#line 199 "src/parse-gram.y" /* yacc.c:355 */
+int integer;
+#line 203 "src/parse-gram.y" /* yacc.c:355 */
+symbol *symbol;
+#line 208 "src/parse-gram.y" /* yacc.c:355 */
+assoc assoc;
+#line 211 "src/parse-gram.y" /* yacc.c:355 */
+symbol_list *list;
+#line 214 "src/parse-gram.y" /* yacc.c:355 */
+named_ref *named_ref;
+#line 241 "src/parse-gram.y" /* yacc.c:355 */
+param_type param;
+#line 409 "src/parse-gram.y" /* yacc.c:355 */
+code_props_type code_type;
+#line 647 "src/parse-gram.y" /* yacc.c:355 */
+
+ struct
+ {
+ char const *chars;
+ muscle_kind kind;
+ } value;
+
+#line 235 "src/parse-gram.c" /* yacc.c:355 */
+};
+# define GRAM_STYPE_IS_TRIVIAL 1
+# define GRAM_STYPE_IS_DECLARED 1
+#endif
+
+/* Location type. */
+#if ! defined GRAM_LTYPE && ! defined GRAM_LTYPE_IS_DECLARED
+typedef struct GRAM_LTYPE GRAM_LTYPE;
+struct GRAM_LTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define GRAM_LTYPE_IS_DECLARED 1
+# define GRAM_LTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+int gram_parse (void);
+
+#endif /* !YY_GRAM_SRC_PARSE_GRAM_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 263 "src/parse-gram.c" /* yacc.c:358 */
+/* Unqualified %code blocks. */
+#line 33 "src/parse-gram.y" /* yacc.c:359 */
+
+ #include "system.h"
+
+ #include "c-ctype.h"
+ #include "complain.h"
+ #include "conflicts.h"
+ #include "files.h"
+ #include "getargs.h"
+ #include "gram.h"
+ #include "named-ref.h"
+ #include "quotearg.h"
+ #include "reader.h"
+ #include "scan-gram.h"
+ #include "scan-code.h"
+ #include "xmemdup0.h"
+
+ static int current_prec = 0;
+ static location current_lhs_location;
+ static named_ref *current_lhs_named_ref;
+ static symbol *current_lhs_symbol;
+ static symbol_class current_class = unknown_sym;
+ static uniqstr current_type = NULL;
+
+ /** 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);
+
+ #define YYLLOC_DEFAULT(Current, Rhs, N) \
+ (Current) = lloc_default (Rhs, N)
+ static YYLTYPE lloc_default (YYLTYPE const *, int);
+
+ #define YY_LOCATION_PRINT(File, Loc) \
+ location_print (Loc, File)
+
+ /* Strip initial '{' and final '}' (must be first and last characters).
+ Return the result. */
+ static char *strip_braces (char *code);
+
+ /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
+ code_props_symbol_action_init. Call
+ gram_scanner_last_string_free to release the latest string from
+ the scanner (should be CODE). */
+ static char const *translate_code (char *code, location loc, bool plain);
+
+ /* Convert CODE by calling code_props_plain_init after having
+ stripped the first and last characters (expected to be '{', and
+ '}'). Call gram_scanner_last_string_free to release the latest
+ string from the scanner (should be CODE). */
+ static char const *translate_code_braceless (char *code, location loc);
+
+ static void version_check (location const *loc, char const *version);
+
+ static void gram_error (location const *, char const *);
+
+ /* A string that describes a char (e.g., 'a' -> "'a'"). */
+ static char const *char_name (char);
+
+ #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 231 "src/parse-gram.y" /* yacc.c:359 */
+
+ /** Add a lex-param and/or a parse-param.
+ *
+ * \param type where to push this formal argument.
+ * \param decl the formal argument. Destroyed.
+ * \param loc the location in the source.
+ */
+ static void add_param (param_type type, char *decl, location loc);
+ static param_type current_param = param_none;
+
+#line 339 "src/parse-gram.c" /* yacc.c:359 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+ || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+# define __attribute__(Spec) /* empty */
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#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
+# 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
+
+
+#if 1
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+# define YYCOPY_NEEDED 1
+#endif
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (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_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+# 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_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#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 (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 3
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 164
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 58
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 37
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 110
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 144
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 312
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 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, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57
+};
+
+#if GRAM_DEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 264, 264, 273, 274, 278, 279, 285, 289, 294,
+ 295, 300, 306, 307, 308, 309, 314, 319, 320, 321,
+ 322, 323, 324, 324, 325, 326, 350, 351, 352, 353,
+ 357, 358, 367, 368, 369, 373, 385, 389, 393, 401,
+ 412, 413, 423, 424, 428, 440, 440, 445, 445, 450,
+ 461, 476, 477, 478, 479, 483, 484, 489, 491, 496,
+ 501, 511, 513, 518, 519, 523, 524, 528, 529, 530,
+ 535, 540, 545, 551, 557, 568, 569, 578, 579, 585,
+ 586, 587, 594, 594, 602, 603, 604, 609, 612, 614,
+ 616, 618, 620, 622, 624, 629, 630, 640, 641, 666,
+ 667, 668, 669, 681, 683, 692, 697, 698, 703, 711,
+ 712
+};
+#endif
+
+#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\"", "\"%token\"",
+ "\"%nterm\"", "\"%type\"", "\"%destructor\"", "\"%printer\"",
+ "\"%left\"", "\"%right\"", "\"%nonassoc\"", "\"%precedence\"",
+ "\"%prec\"", "\"%dprec\"", "\"%merge\"", "\"%code\"",
+ "\"%default-prec\"", "\"%define\"", "\"%defines\"", "\"%error-verbose\"",
+ "\"%expect\"", "\"%expect-rr\"", "\"%<flag>\"", "\"%file-prefix\"",
+ "\"%glr-parser\"", "\"%initial-action\"", "\"%language\"",
+ "\"%name-prefix\"", "\"%no-default-prec\"", "\"%no-lines\"",
+ "\"%nondeterministic-parser\"", "\"%output\"", "\"%require\"",
+ "\"%skeleton\"", "\"%start\"", "\"%token-table\"", "\"%verbose\"",
+ "\"%yacc\"", "\"{...}\"", "\"%?{...}\"", "\"[identifier]\"", "\"char\"",
+ "\"epilogue\"", "\"=\"", "\"identifier\"", "\"identifier:\"", "\"%%\"",
+ "\"|\"", "\"%{...%}\"", "\";\"", "\"<tag>\"", "\"<*>\"", "\"<>\"",
+ "\"integer\"", "\"%param\"", "\"%union\"", "\"%empty\"", "$accept",
+ "input", "prologue_declarations", "prologue_declaration", "$@1",
+ "params", "grammar_declaration", "code_props_type", "union_name",
+ "symbol_declaration", "$@2", "$@3", "precedence_declaration",
+ "precedence_declarator", "tag.opt", "symbols.prec", "symbol.prec",
+ "symbols.1", "generic_symlist", "generic_symlist_item", "tag",
+ "symbol_def", "symbol_defs.1", "grammar", "rules_or_grammar_declaration",
+ "rules", "$@4", "rhses.1", "rhs", "named_ref.opt", "variable", "value",
+ "id", "id_colon", "symbol", "string_as_id", "epilogue.opt", YY_NULL
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 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, 307, 308, 309, 310, 311, 312
+};
+# endif
+
+#define YYPACT_NINF -113
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-113)))
+
+#define YYTABLE_NINF -110
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int8 yypact[] =
+{
+ -113, 16, 108, -113, -113, -113, -27, -113, -113, -113,
+ -113, -113, -113, -24, -113, 23, 24, -113, -21, -15,
+ -113, 29, -113, 3, 38, 42, -113, -113, -113, 44,
+ 47, 71, 31, -113, -113, -113, 55, -113, -113, -113,
+ 30, -113, -113, 39, -113, -113, 26, -22, -22, 31,
+ -113, 48, -113, -113, 1, -113, -113, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, 45, -113, 50, 2, -113, -113, 57, 49, -113,
+ 52, 41, -113, 31, -113, -113, -22, -2, -22, 31,
+ -113, -113, -113, -113, -113, -113, -113, -113, 46, -113,
+ -113, -113, -113, -113, 63, -113, -113, -113, -113, 41,
+ -113, -113, -113, 31, -113, 51, -113, 100, -113, -113,
+ -113, -113, -113, -113, -113, -113, -113, -20, 40, -113,
+ -113, 31, 53, 58, 57, -113, -113, 57, 40, -113,
+ -113, -113, -113, -113
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 3, 0, 0, 1, 47, 45, 0, 40, 41, 51,
+ 52, 53, 54, 0, 36, 0, 9, 11, 0, 0,
+ 7, 0, 15, 0, 0, 0, 37, 19, 20, 0,
+ 0, 0, 0, 26, 27, 28, 0, 6, 29, 22,
+ 42, 4, 5, 0, 33, 32, 55, 0, 0, 0,
+ 38, 0, 98, 97, 99, 10, 12, 13, 14, 16,
+ 17, 18, 21, 24, 25, 108, 104, 103, 106, 34,
+ 107, 0, 105, 0, 0, 77, 79, 95, 0, 43,
+ 0, 0, 56, 0, 70, 75, 48, 71, 46, 49,
+ 61, 39, 101, 102, 100, 8, 81, 80, 0, 78,
+ 2, 96, 82, 31, 23, 44, 67, 68, 69, 35,
+ 63, 66, 65, 50, 57, 59, 76, 72, 73, 62,
+ 110, 87, 30, 64, 58, 60, 74, 83, 84, 87,
+ 86, 0, 0, 0, 95, 90, 91, 95, 85, 92,
+ 93, 94, 89, 88
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -113, -113, -113, -113, -113, -113, 102, -113, -113, -113,
+ -113, -113, -113, -113, -113, -113, 8, -113, -113, 13,
+ -113, -50, 75, -113, 73, -113, -113, -113, 19, -112,
+ -113, -113, 22, -113, -32, -82, -113
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 1, 2, 41, 78, 104, 73, 43, 80, 44,
+ 48, 47, 45, 46, 83, 113, 114, 89, 109, 110,
+ 111, 85, 86, 74, 75, 76, 121, 127, 128, 102,
+ 54, 95, 68, 77, 112, 70, 100
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int16 yytable[] =
+{
+ 69, 65, -109, 71, 92, 118, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 50, 3, 90, 13, 14,
+ 66, 51, 142, 67, 49, 143, 52, 55, 129, 84,
+ 130, 26, 58, 56, 65, 126, 116, 32, 116, 57,
+ 93, 60, 59, 65, 65, 61, 94, 62, 72, 98,
+ 63, 115, 117, 131, 132, 133, 71, 119, 40, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 53, 87,
+ 87, 13, 14, 66, 64, 79, 67, 82, 81, 134,
+ 135, 115, 66, 66, 26, 67, 67, 91, 103, 120,
+ 32, 105, 106, 107, 108, 96, 137, 136, 101, 139,
+ 97, 72, 122, 65, 42, 125, 137, 140, 87, 141,
+ 87, 40, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 124, 123, 88, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 99, 138, 0,
+ 0, 0, 0, 0, 0, 36, 0, 37, 38, 0,
+ 0, 0, 0, 39, 40
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 32, 3, 0, 1, 3, 87, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 39, 0, 49, 16, 17,
+ 42, 45, 134, 45, 51, 137, 3, 3, 48, 51,
+ 50, 29, 3, 54, 3, 117, 86, 35, 88, 54,
+ 39, 3, 39, 3, 3, 3, 45, 3, 46, 47,
+ 3, 83, 54, 13, 14, 15, 1, 89, 56, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 45, 47,
+ 48, 16, 17, 42, 3, 45, 45, 51, 39, 39,
+ 40, 113, 42, 42, 29, 45, 45, 39, 39, 43,
+ 35, 39, 51, 52, 53, 50, 128, 57, 41, 131,
+ 50, 46, 39, 3, 2, 54, 138, 54, 86, 51,
+ 88, 56, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 113, 109, 48, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 74, 129, -1,
+ -1, -1, -1, -1, -1, 47, -1, 49, 50, -1,
+ -1, -1, -1, 55, 56
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 59, 60, 0, 4, 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, 47, 49, 50, 55,
+ 56, 61, 64, 65, 67, 70, 71, 69, 68, 51,
+ 39, 45, 3, 45, 88, 3, 54, 54, 3, 39,
+ 3, 3, 3, 3, 3, 3, 42, 45, 90, 92,
+ 93, 1, 46, 64, 81, 82, 83, 91, 62, 45,
+ 66, 39, 51, 72, 51, 79, 80, 90, 80, 75,
+ 92, 39, 3, 39, 45, 89, 50, 50, 47, 82,
+ 94, 41, 87, 39, 63, 39, 51, 52, 53, 76,
+ 77, 78, 92, 73, 74, 92, 79, 54, 93, 92,
+ 43, 84, 39, 77, 74, 54, 93, 85, 86, 48,
+ 50, 13, 14, 15, 39, 40, 57, 92, 86, 92,
+ 54, 51, 87, 87
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 58, 59, 60, 60, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 62, 61, 61, 61, 61, 61, 61, 61,
+ 63, 63, 64, 64, 64, 64, 64, 64, 64, 64,
+ 65, 65, 66, 66, 64, 68, 67, 69, 67, 67,
+ 70, 71, 71, 71, 71, 72, 72, 73, 73, 74,
+ 74, 75, 75, 76, 76, 77, 77, 78, 78, 78,
+ 79, 79, 79, 79, 79, 80, 80, 81, 81, 82,
+ 82, 82, 84, 83, 85, 85, 85, 86, 86, 86,
+ 86, 86, 86, 86, 86, 87, 87, 88, 88, 89,
+ 89, 89, 89, 90, 90, 91, 92, 92, 93, 94,
+ 94
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 4, 0, 2, 1, 1, 1, 3, 1,
+ 2, 1, 2, 2, 2, 1, 2, 2, 2, 1,
+ 1, 2, 0, 3, 2, 2, 1, 1, 1, 1,
+ 2, 1, 1, 1, 2, 3, 1, 1, 2, 3,
+ 1, 1, 0, 1, 3, 0, 3, 0, 3, 3,
+ 3, 1, 1, 1, 1, 0, 1, 1, 2, 1,
+ 2, 1, 2, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 3, 1, 2, 1, 2, 1,
+ 2, 2, 0, 4, 1, 3, 2, 0, 3, 3,
+ 2, 2, 3, 3, 3, 0, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 2
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ YY_LAC_DISCARD ("YYBACKUP"); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (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 (0)
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
+/* Enable debugging if requested. */
+#if GRAM_DEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+
+/* 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 defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+__attribute__((__unused__))
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+{
+ unsigned res = 0;
+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+ if (0 <= yylocp->first_line)
+ {
+ res += YYFPRINTF (yyo, "%d", yylocp->first_line);
+ if (0 <= yylocp->first_column)
+ res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
+ }
+ if (0 <= yylocp->last_line)
+ {
+ if (yylocp->first_line < yylocp->last_line)
+ {
+ res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
+ if (0 <= end_col)
+ res += YYFPRINTF (yyo, ".%d", end_col);
+ }
+ else if (0 <= end_col && yylocp->first_column < end_col)
+ res += YYFPRINTF (yyo, "-%d", end_col);
+ }
+ return res;
+ }
+
+# define YY_LOCATION_PRINT(File, Loc) \
+ yy_location_print_ (File, &(Loc))
+
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ YYUSE (yylocationp);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ switch (yytype)
+ {
+ case 3: /* "string" */
+#line 188 "src/parse-gram.y" /* yacc.c:684 */
+ { fputs (quotearg_style (c_quoting_style, ((*yyvaluep).code)), yyo); }
+#line 987 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 23: /* "%<flag>" */
+#line 196 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%%%s", ((*yyvaluep).uniqstr)); }
+#line 993 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 39: /* "{...}" */
+#line 189 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "{\n%s\n}", ((*yyvaluep).code)); }
+#line 999 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 40: /* "%?{...}" */
+#line 189 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "{\n%s\n}", ((*yyvaluep).code)); }
+#line 1005 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 41: /* "[identifier]" */
+#line 194 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "[%s]", ((*yyvaluep).uniqstr)); }
+#line 1011 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 42: /* "char" */
+#line 184 "src/parse-gram.y" /* yacc.c:684 */
+ { fputs (char_name (((*yyvaluep).character)), yyo); }
+#line 1017 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 43: /* "epilogue" */
+#line 189 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "{\n%s\n}", ((*yyvaluep).code)); }
+#line 1023 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 45: /* "identifier" */
+#line 193 "src/parse-gram.y" /* yacc.c:684 */
+ { fputs (((*yyvaluep).uniqstr), yyo); }
+#line 1029 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 46: /* "identifier:" */
+#line 195 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s:", ((*yyvaluep).uniqstr)); }
+#line 1035 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 49: /* "%{...%}" */
+#line 189 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "{\n%s\n}", ((*yyvaluep).code)); }
+#line 1041 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 51: /* "<tag>" */
+#line 197 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "<%s>", ((*yyvaluep).uniqstr)); }
+#line 1047 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 54: /* "integer" */
+#line 201 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%d", ((*yyvaluep).integer)); }
+#line 1053 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 55: /* "%param" */
+#line 244 "src/parse-gram.y" /* yacc.c:684 */
+ {
+ switch (((*yyvaluep).param))
+ {
+#define CASE(In, Out) \
+ case param_ ## In: fputs ("%" #Out, yyo); break
+ CASE (lex, lex-param);
+ CASE (parse, parse-param);
+ CASE (both, param);
+#undef CASE
+ case param_none: aver (false); break;
+ }
+}
+#line 1070 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 65: /* code_props_type */
+#line 410 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s", code_props_type_string (((*yyvaluep).code_type))); }
+#line 1076 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 74: /* symbol.prec */
+#line 205 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s", ((*yyvaluep).symbol)->tag); }
+#line 1082 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 78: /* tag */
+#line 197 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "<%s>", ((*yyvaluep).uniqstr)); }
+#line 1088 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 88: /* variable */
+#line 193 "src/parse-gram.y" /* yacc.c:684 */
+ { fputs (((*yyvaluep).uniqstr), yyo); }
+#line 1094 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 89: /* value */
+#line 656 "src/parse-gram.y" /* yacc.c:684 */
+ {
+ switch (((*yyvaluep).value).kind)
+ {
+ case muscle_code: fprintf (yyo, "{%s}", ((*yyvaluep).value).chars); break;
+ case muscle_keyword: fprintf (yyo, "%s", ((*yyvaluep).value).chars); break;
+ case muscle_string: fprintf (yyo, "\"%s\"", ((*yyvaluep).value).chars); break;
+ }
+}
+#line 1107 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 90: /* id */
+#line 205 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s", ((*yyvaluep).symbol)->tag); }
+#line 1113 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 91: /* id_colon */
+#line 206 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s:", ((*yyvaluep).symbol)->tag); }
+#line 1119 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 92: /* symbol */
+#line 205 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s", ((*yyvaluep).symbol)->tag); }
+#line 1125 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+ case 93: /* string_as_id */
+#line 205 "src/parse-gram.y" /* yacc.c:684 */
+ { fprintf (yyo, "%s", ((*yyvaluep).symbol)->tag); }
+#line 1131 "src/parse-gram.c" /* yacc.c:684 */
+ break;
+
+
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int 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 /* !GRAM_DEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# 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 (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 (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
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP. 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)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ 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;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in 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 yyn = yypact[*yyssp];
+ YYDPRINTF ((stderr, "Constructing syntax error message\n"));
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ int yyx;
+
+ for (yyx = 0; yyx < YYNTOKENS; ++yyx)
+ if (yyx != YYTERROR && yyx != YYUNDEFTOK)
+ {
+ {
+ int yy_lac_status = yy_lac (yyesa, yyes, yyes_capacity,
+ yyssp, yyx);
+ if (yy_lac_status == 2)
+ return 2;
+ if (yy_lac_status == 1)
+ continue;
+ }
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T 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
+ }
+
+ 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_
+ }
+
+ {
+ YYSIZE_T 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. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+/* The lookahead symbol. */
+int yychar;
+
+
+/* The semantic value of the lookahead symbol. */
+/* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
+YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
+
+/* Location data for the lookahead symbol. */
+static YYLTYPE yyloc_default
+# if defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL
+ = { 1, 1, 1, 1 }
+# endif
+;
+YYLTYPE yylloc = yyloc_default;
+
+ /* 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;
+ /* 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];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* 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. */
+
+/* User initialization code. */
+#line 108 "src/parse-gram.y" /* yacc.c:1429 */
+{
+ /* Bison's grammar can initial empty locations, hence a default
+ location is needed. */
+ boundary_set (&yylloc.start, current_file, 1, 1);
+ boundary_set (&yylloc.end, current_file, 1, 1);
+}
+
+#line 1833 "src/parse-gram.c" /* yacc.c:1429 */
+ yylsp[0] = yylloc;
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex (&yylval, &yylloc);
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ {
+ YY_LAC_ESTABLISH;
+ goto yydefault;
+ }
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ YY_LAC_ESTABLISH;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* 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;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ {
+ int yychar_backup = yychar;
+ switch (yyn)
+ {
+ case 6:
+#line 280 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
+ translate_code ((yyvsp[0].code), (yylsp[0]), true), (yylsp[0]));
+ code_scanner_last_string_free ();
+ }
+#line 2033 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 7:
+#line 286 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_percent_define_ensure ((yyvsp[0].uniqstr), (yylsp[0]), true);
+ }
+#line 2041 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 8:
+#line 290 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_percent_define_insert ((yyvsp[-1].uniqstr), (yylsp[-1]), (yyvsp[0].value).kind, (yyvsp[0].value).chars,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+ }
+#line 2050 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 9:
+#line 294 "src/parse-gram.y" /* yacc.c:1646 */
+ { defines_flag = true; }
+#line 2056 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 10:
+#line 296 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ defines_flag = true;
+ spec_defines_file = xstrdup ((yyvsp[0].code));
+ }
+#line 2065 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 11:
+#line 301 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_percent_define_insert ("parse.error", (yylsp[0]), muscle_keyword,
+ "verbose",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+ }
+#line 2075 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 12:
+#line 306 "src/parse-gram.y" /* yacc.c:1646 */
+ { expected_sr_conflicts = (yyvsp[0].integer); }
+#line 2081 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 13:
+#line 307 "src/parse-gram.y" /* yacc.c:1646 */
+ { expected_rr_conflicts = (yyvsp[0].integer); }
+#line 2087 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 14:
+#line 308 "src/parse-gram.y" /* yacc.c:1646 */
+ { spec_file_prefix = (yyvsp[0].code); }
+#line 2093 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 15:
+#line 310 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ nondeterministic_parser = true;
+ glr_parser = true;
+ }
+#line 2102 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 16:
+#line 315 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_code_grow ("initial_action", translate_code ((yyvsp[0].code), (yylsp[0]), false), (yylsp[0]));
+ code_scanner_last_string_free ();
+ }
+#line 2111 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 17:
+#line 319 "src/parse-gram.y" /* yacc.c:1646 */
+ { language_argmatch ((yyvsp[0].code), grammar_prio, (yylsp[-1])); }
+#line 2117 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 18:
+#line 320 "src/parse-gram.y" /* yacc.c:1646 */
+ { spec_name_prefix = (yyvsp[0].code); }
+#line 2123 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 19:
+#line 321 "src/parse-gram.y" /* yacc.c:1646 */
+ { no_lines_flag = true; }
+#line 2129 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+#line 322 "src/parse-gram.y" /* yacc.c:1646 */
+ { nondeterministic_parser = true; }
+#line 2135 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 21:
+#line 323 "src/parse-gram.y" /* yacc.c:1646 */
+ { spec_outfile = (yyvsp[0].code); }
+#line 2141 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 22:
+#line 324 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_param = (yyvsp[0].param); }
+#line 2147 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+#line 324 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_param = param_none; }
+#line 2153 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 24:
+#line 325 "src/parse-gram.y" /* yacc.c:1646 */
+ { version_check (&(yylsp[0]), (yyvsp[0].code)); }
+#line 2159 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 25:
+#line 327 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ char const *skeleton_user = (yyvsp[0].code);
+ if (strchr (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]));
+ }
+#line 2187 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 26:
+#line 350 "src/parse-gram.y" /* yacc.c:1646 */
+ { token_table_flag = true; }
+#line 2193 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+#line 351 "src/parse-gram.y" /* yacc.c:1646 */
+ { report_flag |= report_states; }
+#line 2199 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 28:
+#line 352 "src/parse-gram.y" /* yacc.c:1646 */
+ { yacc_flag = true; }
+#line 2205 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 30:
+#line 357 "src/parse-gram.y" /* yacc.c:1646 */
+ { add_param (current_param, (yyvsp[0].code), (yylsp[0])); }
+#line 2211 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 31:
+#line 358 "src/parse-gram.y" /* yacc.c:1646 */
+ { add_param (current_param, (yyvsp[0].code), (yylsp[0])); }
+#line 2217 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 34:
+#line 370 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ grammar_start_symbol_set ((yyvsp[0].symbol), (yylsp[0]));
+ }
+#line 2225 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 35:
+#line 374 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ code_props code;
+ code_props_symbol_action_init (&code, (yyvsp[-1].code), (yylsp[-1]));
+ code_props_translate_code (&code);
+ {
+ symbol_list *list;
+ for (list = (yyvsp[0].list); list; list = list->next)
+ symbol_list_code_props_set (list, (yyvsp[-2].code_type), &code);
+ symbol_list_free ((yyvsp[0].list));
+ }
+ }
+#line 2241 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+#line 386 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ default_prec = true;
+ }
+#line 2249 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 37:
+#line 390 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ default_prec = false;
+ }
+#line 2257 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 38:
+#line 394 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ /* Do not invoke muscle_percent_code_grow here since it invokes
+ muscle_user_name_list_grow. */
+ muscle_code_grow ("percent_code()",
+ translate_code_braceless ((yyvsp[0].code), (yylsp[0])), (yylsp[0]));
+ code_scanner_last_string_free ();
+ }
+#line 2269 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 39:
+#line 402 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_percent_code_grow ((yyvsp[-1].uniqstr), (yylsp[-1]), translate_code_braceless ((yyvsp[0].code), (yylsp[0])), (yylsp[0]));
+ code_scanner_last_string_free ();
+ }
+#line 2278 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 40:
+#line 412 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.code_type) = destructor; }
+#line 2284 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 41:
+#line 413 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.code_type) = printer; }
+#line 2290 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 42:
+#line 423 "src/parse-gram.y" /* yacc.c:1646 */
+ {}
+#line 2296 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 43:
+#line 424 "src/parse-gram.y" /* yacc.c:1646 */
+ { muscle_code_grow ("union_name", (yyvsp[0].uniqstr), (yylsp[0])); }
+#line 2302 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 44:
+#line 429 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ union_seen = true;
+ muscle_code_grow ("union_members", translate_code_braceless ((yyvsp[0].code), (yylsp[0])), (yylsp[0]));
+ code_scanner_last_string_free ();
+ }
+#line 2312 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+#line 440 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_class = nterm_sym; }
+#line 2318 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 46:
+#line 441 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ current_class = unknown_sym;
+ current_type = NULL;
+ }
+#line 2327 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 47:
+#line 445 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_class = token_sym; }
+#line 2333 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 48:
+#line 446 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ current_class = unknown_sym;
+ current_type = NULL;
+ }
+#line 2342 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 49:
+#line 451 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ symbol_list *list;
+ tag_seen = true;
+ for (list = (yyvsp[0].list); list; list = list->next)
+ symbol_type_set (list->content.sym, (yyvsp[-1].uniqstr), (yylsp[-1]));
+ symbol_list_free ((yyvsp[0].list));
+ }
+#line 2354 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 50:
+#line 462 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ symbol_list *list;
+ ++current_prec;
+ for (list = (yyvsp[0].list); list; list = list->next)
+ {
+ symbol_type_set (list->content.sym, current_type, (yylsp[-1]));
+ symbol_precedence_set (list->content.sym, current_prec, (yyvsp[-2].assoc), (yylsp[-2]));
+ }
+ symbol_list_free ((yyvsp[0].list));
+ current_type = NULL;
+ }
+#line 2370 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 51:
+#line 476 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.assoc) = left_assoc; }
+#line 2376 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 52:
+#line 477 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.assoc) = right_assoc; }
+#line 2382 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 53:
+#line 478 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.assoc) = non_assoc; }
+#line 2388 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 54:
+#line 479 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.assoc) = precedence_assoc; }
+#line 2394 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 55:
+#line 483 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_type = NULL; }
+#line 2400 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 56:
+#line 484 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_type = (yyvsp[0].uniqstr); tag_seen = true; }
+#line 2406 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 57:
+#line 490 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0])); }
+#line 2412 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 58:
+#line 492 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_append ((yyvsp[-1].list), symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0]))); }
+#line 2418 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+#line 497 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ (yyval.symbol) = (yyvsp[0].symbol);
+ symbol_class_set ((yyvsp[0].symbol), token_sym, (yylsp[0]), false);
+ }
+#line 2427 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 60:
+#line 502 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ (yyval.symbol) = (yyvsp[-1].symbol);
+ symbol_user_token_number_set ((yyvsp[-1].symbol), (yyvsp[0].integer), (yylsp[0]));
+ symbol_class_set ((yyvsp[-1].symbol), token_sym, (yylsp[-1]), false);
+ }
+#line 2437 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 61:
+#line 512 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0])); }
+#line 2443 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 62:
+#line 514 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_append ((yyvsp[-1].list), symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0]))); }
+#line 2449 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+#line 518 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = (yyvsp[0].list); }
+#line 2455 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 64:
+#line 519 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_append ((yyvsp[-1].list), (yyvsp[0].list)); }
+#line 2461 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+#line 523 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0])); }
+#line 2467 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+#line 524 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.list) = symbol_list_type_new ((yyvsp[0].uniqstr), (yylsp[0])); }
+#line 2473 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 68:
+#line 529 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.uniqstr) = uniqstr_new ("*"); }
+#line 2479 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 69:
+#line 530 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.uniqstr) = uniqstr_new (""); }
+#line 2485 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 70:
+#line 536 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ current_type = (yyvsp[0].uniqstr);
+ tag_seen = true;
+ }
+#line 2494 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 71:
+#line 541 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ symbol_class_set ((yyvsp[0].symbol), current_class, (yylsp[0]), true);
+ symbol_type_set ((yyvsp[0].symbol), current_type, (yylsp[0]));
+ }
+#line 2503 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 72:
+#line 546 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ symbol_class_set ((yyvsp[-1].symbol), current_class, (yylsp[-1]), true);
+ symbol_type_set ((yyvsp[-1].symbol), current_type, (yylsp[-1]));
+ symbol_user_token_number_set ((yyvsp[-1].symbol), (yyvsp[0].integer), (yylsp[0]));
+ }
+#line 2513 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+#line 552 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ symbol_class_set ((yyvsp[-1].symbol), current_class, (yylsp[-1]), true);
+ symbol_type_set ((yyvsp[-1].symbol), current_type, (yylsp[-1]));
+ symbol_make_alias ((yyvsp[-1].symbol), (yyvsp[0].symbol), (yyloc));
+ }
+#line 2523 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 74:
+#line 558 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ symbol_class_set ((yyvsp[-2].symbol), current_class, (yylsp[-2]), true);
+ symbol_type_set ((yyvsp[-2].symbol), current_type, (yylsp[-2]));
+ symbol_user_token_number_set ((yyvsp[-2].symbol), (yyvsp[-1].integer), (yylsp[-1]));
+ symbol_make_alias ((yyvsp[-2].symbol), (yyvsp[0].symbol), (yyloc));
+ }
+#line 2534 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 81:
+#line 588 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ yyerrok;
+ }
+#line 2542 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 82:
+#line 594 "src/parse-gram.y" /* yacc.c:1646 */
+ { current_lhs ((yyvsp[-1].symbol), (yylsp[-1]), (yyvsp[0].named_ref)); }
+#line 2548 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 83:
+#line 595 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ /* Free the current lhs. */
+ current_lhs (0, (yylsp[-3]), 0);
+ }
+#line 2557 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 84:
+#line 602 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_end ((yylsp[0])); }
+#line 2563 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 85:
+#line 603 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_end ((yylsp[0])); }
+#line 2569 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 87:
+#line 610 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
+ current_lhs_named_ref); }
+#line 2576 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 88:
+#line 613 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_symbol_append ((yyvsp[-1].symbol), (yylsp[-1]), (yyvsp[0].named_ref)); }
+#line 2582 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 89:
+#line 615 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_action_append ((yyvsp[-1].code), (yylsp[-1]), (yyvsp[0].named_ref), false); }
+#line 2588 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 90:
+#line 617 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_action_append ((yyvsp[0].code), (yylsp[0]), NULL, true); }
+#line 2594 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 91:
+#line 619 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_empty_set ((yylsp[0])); }
+#line 2600 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 92:
+#line 621 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_prec_set ((yyvsp[0].symbol), (yylsp[0])); }
+#line 2606 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 93:
+#line 623 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_dprec_set ((yyvsp[0].integer), (yylsp[0])); }
+#line 2612 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 94:
+#line 625 "src/parse-gram.y" /* yacc.c:1646 */
+ { grammar_current_rule_merge_set ((yyvsp[0].uniqstr), (yylsp[0])); }
+#line 2618 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 95:
+#line 629 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.named_ref) = 0; }
+#line 2624 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 96:
+#line 630 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.named_ref) = named_ref_new ((yyvsp[0].uniqstr), (yylsp[0])); }
+#line 2630 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 98:
+#line 641 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.uniqstr) = uniqstr_new ((yyvsp[0].code)); }
+#line 2636 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 99:
+#line 666 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.value).kind = muscle_keyword; (yyval.value).chars = ""; }
+#line 2642 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 100:
+#line 667 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.value).kind = muscle_keyword; (yyval.value).chars = (yyvsp[0].uniqstr); }
+#line 2648 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 101:
+#line 668 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.value).kind = muscle_string; (yyval.value).chars = (yyvsp[0].code); }
+#line 2654 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 102:
+#line 669 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.value).kind = muscle_code; (yyval.value).chars = strip_braces ((yyvsp[0].code)); }
+#line 2660 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 103:
+#line 682 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[0].uniqstr), (yylsp[0])); }
+#line 2666 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 104:
+#line 684 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ (yyval.symbol) = symbol_get (char_name ((yyvsp[0].character)), (yylsp[0]));
+ symbol_class_set ((yyval.symbol), token_sym, (yylsp[0]), false);
+ symbol_user_token_number_set ((yyval.symbol), (yyvsp[0].character), (yylsp[0]));
+ }
+#line 2676 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 105:
+#line 692 "src/parse-gram.y" /* yacc.c:1646 */
+ { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[0].uniqstr), (yylsp[0])); }
+#line 2682 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 108:
+#line 704 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[0].code)), (yylsp[0]));
+ symbol_class_set ((yyval.symbol), token_sym, (yylsp[0]), false);
+ }
+#line 2691 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+ case 110:
+#line 713 "src/parse-gram.y" /* yacc.c:1646 */
+ {
+ muscle_code_grow ("epilogue", translate_code ((yyvsp[0].code), (yylsp[0]), true), (yylsp[0]));
+ code_scanner_last_string_free ();
+ }
+#line 2700 "src/parse-gram.c" /* yacc.c:1646 */
+ break;
+
+
+#line 2704 "src/parse-gram.c" /* yacc.c:1646 */
+ 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);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| 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)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyesa, &yyes, &yyes_capacity, \
+ yyssp, yytoken)
+ {
+ 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 (&yylloc, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+ yyerror_range[1] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[1] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ /* 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[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if 1
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ 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 whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ if (yyes != yyesa)
+ YYSTACK_FREE (yyes);
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+#line 719 "src/parse-gram.y" /* yacc.c:1906 */
+
+
+/* Return the location of the left-hand side of a rule whose
+ right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
+ the right-hand side, and return an empty location equal to the end
+ boundary of RHS[0] if the right-hand side is empty. */
+
+static YYLTYPE
+lloc_default (YYLTYPE const *rhs, int n)
+{
+ int i;
+ YYLTYPE loc;
+
+ /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
+ The bug is fixed in 7.4.2m, but play it safe for now. */
+ loc.start = rhs[n].end;
+ loc.end = rhs[n].end;
+
+ /* 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++)
+ if (! equal_boundaries (rhs[i].start, rhs[i].end))
+ {
+ loc.start = rhs[i].start;
+ break;
+ }
+
+ return loc;
+}
+
+static
+char *strip_braces (char *code)
+{
+ code[strlen (code) - 1] = 0;
+ return code + 1;
+}
+
+static
+char const *
+translate_code (char *code, location loc, bool plain)
+{
+ code_props plain_code;
+ if (plain)
+ code_props_plain_init (&plain_code, code, loc);
+ else
+ code_props_symbol_action_init (&plain_code, code, loc);
+ code_props_translate_code (&plain_code);
+ gram_scanner_last_string_free ();
+ return plain_code.code;
+}
+
+static
+char const *
+translate_code_braceless (char *code, location loc)
+{
+ return translate_code (strip_braces (code), loc, true);
+}
+
+static void
+add_param (param_type type, char *decl, location loc)
+{
+ static char const alphanum[26 + 26 + 1 + 10] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_"
+ "0123456789";
+
+ char const *name_start = NULL;
+ {
+ char *p;
+ /* Stop on last actual character. */
+ for (p = decl; p[1]; p++)
+ if ((p == decl
+ || ! memchr (alphanum, p[-1], sizeof alphanum))
+ && memchr (alphanum, p[0], sizeof alphanum - 10))
+ name_start = p;
+
+ /* Strip the surrounding '{' and '}', and any blanks just inside
+ the braces. */
+ --p;
+ while (c_isspace ((unsigned char) *p))
+ --p;
+ p[1] = '\0';
+ ++decl;
+ while (c_isspace ((unsigned char) *decl))
+ ++decl;
+ }
+
+ if (! name_start)
+ complain (&loc, complaint, _("missing identifier in parameter declaration"));
+ else
+ {
+ char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
+ if (type & param_lex)
+ muscle_pair_list_grow ("lex_param", decl, name);
+ if (type & param_parse)
+ muscle_pair_list_grow ("parse_param", decl, name);
+ free (name);
+ }
+
+ gram_scanner_last_string_free ();
+}
+
+
+static void
+version_check (location const *loc, char const *version)
+{
+ if (strverscmp (version, PACKAGE_VERSION) > 0)
+ {
+ complain (loc, complaint, "require bison %s, but have %s",
+ version, PACKAGE_VERSION);
+ exit (EX_MISMATCH);
+ }
+}
+
+static void
+gram_error (location const *loc, char const *msg)
+{
+ complain (loc, complaint, "%s", msg);
+}
+
+char const *
+token_name (int type)
+{
+ 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);
+ }
+}
+
+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;
+}
diff --git a/contrib/tools/bison/src/parse-gram.h b/contrib/tools/bison/src/parse-gram.h
new file mode 100644
index 0000000000..09358961d3
--- /dev/null
+++ b/contrib/tools/bison/src/parse-gram.h
@@ -0,0 +1,190 @@
+/* A Bison parser, made by GNU Bison 3.0. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 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/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ 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
+/* Debug 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
+/* "%code requires" blocks. */
+#line 21 "src/parse-gram.y" /* yacc.c:1909 */
+
+ #include "symlist.h"
+ #include "symtab.h"
+#line 221 "src/parse-gram.y" /* yacc.c:1909 */
+
+ typedef enum
+ {
+ param_none = 0,
+ param_lex = 1 << 0,
+ param_parse = 1 << 1,
+ param_both = param_lex | param_parse
+ } param_type;
+#line 645 "src/parse-gram.y" /* yacc.c:1909 */
+#include "muscle-tab.h"
+
+#line 68 "src/parse-gram.h" /* yacc.c:1909 */
+
+/* Token type. */
+#ifndef GRAM_TOKENTYPE
+# define GRAM_TOKENTYPE
+ enum gram_tokentype
+ {
+ GRAM_EOF = 0,
+ STRING = 258,
+ PERCENT_TOKEN = 259,
+ PERCENT_NTERM = 260,
+ PERCENT_TYPE = 261,
+ PERCENT_DESTRUCTOR = 262,
+ PERCENT_PRINTER = 263,
+ PERCENT_LEFT = 264,
+ PERCENT_RIGHT = 265,
+ PERCENT_NONASSOC = 266,
+ PERCENT_PRECEDENCE = 267,
+ PERCENT_PREC = 268,
+ PERCENT_DPREC = 269,
+ PERCENT_MERGE = 270,
+ PERCENT_CODE = 271,
+ PERCENT_DEFAULT_PREC = 272,
+ PERCENT_DEFINE = 273,
+ PERCENT_DEFINES = 274,
+ PERCENT_ERROR_VERBOSE = 275,
+ PERCENT_EXPECT = 276,
+ PERCENT_EXPECT_RR = 277,
+ PERCENT_FLAG = 278,
+ PERCENT_FILE_PREFIX = 279,
+ PERCENT_GLR_PARSER = 280,
+ PERCENT_INITIAL_ACTION = 281,
+ PERCENT_LANGUAGE = 282,
+ PERCENT_NAME_PREFIX = 283,
+ PERCENT_NO_DEFAULT_PREC = 284,
+ PERCENT_NO_LINES = 285,
+ PERCENT_NONDETERMINISTIC_PARSER = 286,
+ PERCENT_OUTPUT = 287,
+ PERCENT_REQUIRE = 288,
+ PERCENT_SKELETON = 289,
+ PERCENT_START = 290,
+ PERCENT_TOKEN_TABLE = 291,
+ PERCENT_VERBOSE = 292,
+ PERCENT_YACC = 293,
+ BRACED_CODE = 294,
+ BRACED_PREDICATE = 295,
+ BRACKETED_ID = 296,
+ CHAR = 297,
+ EPILOGUE = 298,
+ EQUAL = 299,
+ ID = 300,
+ ID_COLON = 301,
+ PERCENT_PERCENT = 302,
+ PIPE = 303,
+ PROLOGUE = 304,
+ SEMICOLON = 305,
+ TAG = 306,
+ TAG_ANY = 307,
+ TAG_NONE = 308,
+ INT = 309,
+ PERCENT_PARAM = 310,
+ PERCENT_UNION = 311,
+ PERCENT_EMPTY = 312
+ };
+#endif
+
+/* Value type. */
+#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
+typedef union GRAM_STYPE GRAM_STYPE;
+union GRAM_STYPE
+{
+#line 182 "src/parse-gram.y" /* yacc.c:1909 */
+unsigned char character;
+#line 186 "src/parse-gram.y" /* yacc.c:1909 */
+char *code;
+#line 191 "src/parse-gram.y" /* yacc.c:1909 */
+uniqstr uniqstr;
+#line 199 "src/parse-gram.y" /* yacc.c:1909 */
+int integer;
+#line 203 "src/parse-gram.y" /* yacc.c:1909 */
+symbol *symbol;
+#line 208 "src/parse-gram.y" /* yacc.c:1909 */
+assoc assoc;
+#line 211 "src/parse-gram.y" /* yacc.c:1909 */
+symbol_list *list;
+#line 214 "src/parse-gram.y" /* yacc.c:1909 */
+named_ref *named_ref;
+#line 241 "src/parse-gram.y" /* yacc.c:1909 */
+param_type param;
+#line 409 "src/parse-gram.y" /* yacc.c:1909 */
+code_props_type code_type;
+#line 647 "src/parse-gram.y" /* yacc.c:1909 */
+
+ struct
+ {
+ char const *chars;
+ muscle_kind kind;
+ } value;
+
+#line 167 "src/parse-gram.h" /* yacc.c:1909 */
+};
+# define GRAM_STYPE_IS_TRIVIAL 1
+# define GRAM_STYPE_IS_DECLARED 1
+#endif
+
+/* Location type. */
+#if ! defined GRAM_LTYPE && ! defined GRAM_LTYPE_IS_DECLARED
+typedef struct GRAM_LTYPE GRAM_LTYPE;
+struct GRAM_LTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define GRAM_LTYPE_IS_DECLARED 1
+# define GRAM_LTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+int gram_parse (void);
+
+#endif /* !YY_GRAM_SRC_PARSE_GRAM_H_INCLUDED */
diff --git a/contrib/tools/bison/src/print-xml.c b/contrib/tools/bison/src/print-xml.c
new file mode 100644
index 0000000000..c30da729db
--- /dev/null
+++ b/contrib/tools/bison/src/print-xml.c
@@ -0,0 +1,545 @@
+/* Print an xml on generated parser, for Bison,
+
+ Copyright (C) 2007, 2009-2013 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 "string--.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;
+};
+enum { num_escape_bufs = 3 };
+static struct escape_buf escape_bufs[num_escape_bufs];
+
+
+/*--------------------------------.
+| 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)
+{
+ 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>");
+ {
+ state_number i;
+ 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>");
+
+ {
+ int i;
+ for (i = 0; i < num_escape_bufs; ++i)
+ free (escape_bufs[i].ptr);
+ }
+
+ xfclose (out);
+}
diff --git a/contrib/tools/bison/src/print-xml.h b/contrib/tools/bison/src/print-xml.h
new file mode 100644
index 0000000000..251c2033b9
--- /dev/null
+++ b/contrib/tools/bison/src/print-xml.h
@@ -0,0 +1,30 @@
+/* Output an xml of the generated parser, for Bison.
+
+ Copyright (C) 2007, 2009-2013 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/contrib/tools/bison/src/print.c b/contrib/tools/bison/src/print.c
new file mode 100644
index 0000000000..824bb4ae82
--- /dev/null
+++ b/contrib/tools/bison/src/print.c
@@ -0,0 +1,529 @@
+/* Print information on generated parser, for bison,
+
+ Copyright (C) 1984, 1986, 1989, 2000-2005, 2007, 2009-2013 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 <bitset.h>
+
+#include "LR0.h"
+#include "closure.h"
+#include "conflicts.h"
+#include "files.h"
+#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 no_reduce_set;
+
+#if 0
+static void
+print_token (int extnum, int token)
+{
+ fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
+}
+#endif
+
+
+
+/*---------------------------------------.
+| *WIDTH := max (*WIDTH, strlen (STR)). |
+`---------------------------------------*/
+
+static void
+max_length (size_t *width, const char *str)
+{
+ size_t len = strlen (str);
+ if (len > *width)
+ *width = len;
+}
+
+/*--------------------------------.
+| Report information on a state. |
+`--------------------------------*/
+
+static void
+print_core (FILE *out, state *s)
+{
+ size_t i;
+ item_number *sitems = s->items;
+ size_t snritems = s->nitems;
+ symbol *previous_lhs = NULL;
+
+ /* Output all the items of a state, not only its kernel. */
+ if (report_flag & report_itemsets)
+ {
+ closure (sitems, snritems);
+ sitems = itemset;
+ snritems = nitemset;
+ }
+
+ if (!snritems)
+ return;
+
+ fputc ('\n', out);
+
+ for (i = 0; i < snritems; i++)
+ {
+ 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);
+
+ rule_lhs_print (&rules[r], previous_lhs, out);
+ previous_lhs = rules[r].lhs;
+
+ for (sp = rules[r].rhs; sp < sp1; sp++)
+ fprintf (out, " %s", symbols[*sp]->tag);
+ fputs (" .", out);
+ for (/* Nothing */; *sp >= 0; ++sp)
+ fprintf (out, " %s", symbols[*sp]->tag);
+
+ /* 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);
+ }
+}
+
+
+/*------------------------------------------------------------.
+| Report the shifts iff DISPLAY_SHIFTS_P or the gotos of S on |
+| OUT. |
+`------------------------------------------------------------*/
+
+static void
+print_transitions (state *s, FILE *out, bool display_transitions_p)
+{
+ transitions *trans = s->transitions;
+ size_t width = 0;
+ int i;
+
+ /* 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)
+ {
+ symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+ max_length (&width, sym->tag);
+ }
+
+ /* Nothing to report. */
+ if (!width)
+ return;
+
+ fputc ('\n', out);
+ width += 2;
+
+ /* 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)
+ {
+ symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+ const char *tag = sym->tag;
+ state *s1 = trans->states[i];
+ int j;
+
+ fprintf (out, " %s", tag);
+ for (j = width - strlen (tag); j > 0; --j)
+ fputc (' ', out);
+ if (display_transitions_p)
+ fprintf (out, _("shift, and go to state %d\n"), s1->number);
+ else
+ fprintf (out, _("go to state %d\n"), s1->number);
+ }
+}
+
+
+/*--------------------------------------------------------.
+| Report the explicit errors of S raised from %nonassoc. |
+`--------------------------------------------------------*/
+
+static void
+print_errs (FILE *out, state *s)
+{
+ errs *errp = s->errs;
+ size_t width = 0;
+ int i;
+
+ /* 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);
+
+ /* Nothing to report. */
+ if (!width)
+ return;
+
+ fputc ('\n', out);
+ width += 2;
+
+ /* Report lookahead tokens and errors. */
+ for (i = 0; i < errp->num; ++i)
+ if (errp->symbols[i])
+ {
+ const char *tag = errp->symbols[i]->tag;
+ int j;
+ fprintf (out, " %s", tag);
+ for (j = width - strlen (tag); j > 0; --j)
+ fputc (' ', out);
+ fputs (_("error (nonassociative)\n"), out);
+ }
+}
+
+
+/*-------------------------------------------------------------------------.
+| 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 *lookahead_token,
+ rule *r, bool enabled)
+{
+ int j;
+ fprintf (out, " %s", lookahead_token);
+ for (j = width - strlen (lookahead_token); j > 0; --j)
+ fputc (' ', out);
+ if (!enabled)
+ fputc ('[', out);
+ if (r->number)
+ fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
+ else
+ fprintf (out, _("accept"));
+ if (!enabled)
+ fputc (']', out);
+ fputc ('\n', out);
+}
+
+
+/*-------------------------------------------.
+| Report on OUT the reduction actions of S. |
+`-------------------------------------------*/
+
+static void
+print_reductions (FILE *out, state *s)
+{
+ transitions *trans = s->transitions;
+ reductions *reds = s->reductions;
+ rule *default_reduction = NULL;
+ size_t width = 0;
+ int i, j;
+ bool default_reduction_only = true;
+
+ if (reds->num == 0)
+ 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);
+
+ /* Compute the width of the lookahead token column. */
+ if (default_reduction)
+ width = strlen (_("$default"));
+
+ 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)
+ max_length (&width, symbols[i]->tag);
+ count = true;
+ }
+ else
+ {
+ max_length (&width, symbols[i]->tag);
+ }
+ }
+ }
+
+ /* Nothing to report. */
+ if (!width)
+ return;
+
+ fputc ('\n', out);
+ width += 2;
+
+ /* 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);
+ if (count)
+ default_reduction_only = false;
+
+ for (j = 0; j < reds->num; ++j)
+ if (bitset_test (reds->lookahead_tokens[j], i))
+ {
+ if (! count)
+ {
+ 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_reduction, true);
+ defaulted = false;
+ print_reduction (out, width,
+ symbols[i]->tag,
+ reds->rules[j], false);
+ }
+ }
+ }
+
+ if (default_reduction)
+ {
+ char *default_reductions =
+ muscle_percent_define_get ("lr.default-reduction");
+ print_reduction (out, width, _("$default"), default_reduction, true);
+ aver (STREQ (default_reductions, "most")
+ || (STREQ (default_reductions, "consistent")
+ && default_reduction_only)
+ || (reds->num == 1 && reds->rules[0]->number == 0));
+ free (default_reductions);
+ }
+}
+
+
+/*--------------------------------------------------------------.
+| Report on OUT all the actions (shifts, gotos, reductions, and |
+| explicit erros from %nonassoc) of S. |
+`--------------------------------------------------------------*/
+
+static void
+print_actions (FILE *out, state *s)
+{
+ /* Print shifts. */
+ print_transitions (s, out, true);
+ print_errs (out, s);
+ print_reductions (out, s);
+ /* Print gotos. */
+ print_transitions (s, out, false);
+}
+
+
+/*----------------------------------.
+| Report all the data on S on OUT. |
+`----------------------------------*/
+
+static void
+print_state (FILE *out, state *s)
+{
+ fputs ("\n\n", out);
+ fprintf (out, _("State %d"), s->number);
+ fputc ('\n', out);
+ print_core (out, s);
+ print_actions (out, s);
+ if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
+ {
+ fputc ('\n', out);
+ fputs (s->solved_conflicts, out);
+ }
+}
+
+/*-----------------------------------------.
+| Print information on the whole grammar. |
+`-----------------------------------------*/
+
+#define END_TEST(End) \
+ do { \
+ if (column + strlen (buffer) > (End)) \
+ { \
+ fprintf (out, "%s\n ", buffer); \
+ column = 3; \
+ buffer[0] = 0; \
+ } \
+ } while (0)
+
+
+static void
+print_grammar (FILE *out)
+{
+ symbol_number i;
+ char buffer[90];
+ int column = 0;
+
+ grammar_rules_print (out);
+
+ /* TERMINAL (type #) : rule #s terminal is on RHS */
+ fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
+ for (i = 0; i < max_user_token_number + 1; i++)
+ if (token_translations[i] != undeftoken->number)
+ {
+ const char *tag = symbols[token_translations[i]]->tag;
+ rule_number r;
+ item_number *rhsp;
+
+ buffer[0] = 0;
+ column = strlen (tag);
+ fputs (tag, out);
+ END_TEST (65);
+ sprintf (buffer, " (%d)", i);
+
+ for (r = 0; r < nrules; r++)
+ for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+ if (item_number_as_symbol_number (*rhsp) == token_translations[i])
+ {
+ END_TEST (65);
+ sprintf (buffer + strlen (buffer), " %d", r);
+ break;
+ }
+ fprintf (out, "%s\n", buffer);
+ }
+ fputs ("\n\n", out);
+
+
+ fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
+ for (i = ntokens; i < nsyms; i++)
+ {
+ int left_count = 0, right_count = 0;
+ rule_number r;
+ const char *tag = symbols[i]->tag;
+
+ for (r = 0; r < nrules; r++)
+ {
+ item_number *rhsp;
+ if (rules[r].lhs->number == i)
+ left_count++;
+ for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+ if (item_number_as_symbol_number (*rhsp) == i)
+ {
+ right_count++;
+ break;
+ }
+ }
+
+ buffer[0] = 0;
+ fputs (tag, out);
+ column = strlen (tag);
+ sprintf (buffer, " (%d)", i);
+ END_TEST (0);
+
+ if (left_count > 0)
+ {
+ END_TEST (65);
+ sprintf (buffer + strlen (buffer), _(" on left:"));
+
+ for (r = 0; r < nrules; r++)
+ {
+ if (rules[r].lhs->number == i)
+ {
+ END_TEST (65);
+ sprintf (buffer + strlen (buffer), " %d", r);
+ }
+ }
+ }
+
+ if (right_count > 0)
+ {
+ if (left_count > 0)
+ sprintf (buffer + strlen (buffer), ",");
+ END_TEST (65);
+ sprintf (buffer + strlen (buffer), _(" on right:"));
+ for (r = 0; r < nrules; r++)
+ {
+ item_number *rhsp;
+ for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+ if (item_number_as_symbol_number (*rhsp) == i)
+ {
+ END_TEST (65);
+ sprintf (buffer + strlen (buffer), " %d", r);
+ break;
+ }
+ }
+ }
+ fprintf (out, "%s\n", buffer);
+ }
+}
+
+void
+print_results (void)
+{
+ state_number i;
+
+ /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
+ that conflicts with Posix. */
+ FILE *out = xfopen (spec_verbose_file, "w");
+
+ reduce_output (out);
+ grammar_rules_partial_print (out,
+ _("Rules useless in parser due to conflicts"),
+ rule_useless_in_parser_p);
+ conflicts_output (out);
+
+ print_grammar (out);
+
+ /* If the whole state item sets, not only the kernels, are wanted,
+ 'closure' will be run, which needs memory allocation/deallocation. */
+ if (report_flag & report_itemsets)
+ new_closure (nritems);
+ /* Storage for print_reductions. */
+ no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
+ for (i = 0; i < nstates; i++)
+ print_state (out, states[i]);
+ bitset_free (no_reduce_set);
+ if (report_flag & report_itemsets)
+ free_closure ();
+
+ xfclose (out);
+}
diff --git a/contrib/tools/bison/src/print.h b/contrib/tools/bison/src/print.h
new file mode 100644
index 0000000000..e1e254a9bc
--- /dev/null
+++ b/contrib/tools/bison/src/print.h
@@ -0,0 +1,25 @@
+/* Print information on generated parser, for bison,
+
+ Copyright (C) 2000, 2009-2013 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_H_
+# define PRINT_H_
+
+void print_results (void);
+
+#endif /* !PRINT_H_ */
diff --git a/contrib/tools/bison/src/print_graph.c b/contrib/tools/bison/src/print_graph.c
new file mode 100644
index 0000000000..7e429dbd10
--- /dev/null
+++ b/contrib/tools/bison/src/print_graph.c
@@ -0,0 +1,193 @@
+/* Output a graph of the generated parser, for Bison.
+
+ Copyright (C) 2001-2007, 2009-2013 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 "LR0.h"
+#include "closure.h"
+#include "complain.h"
+#include "conflicts.h"
+#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"
+
+
+/*----------------------------.
+| 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_core (struct obstack *oout, state *s)
+{
+ item_number const *sitems = s->items;
+ symbol *previous_lhs = NULL;
+ size_t i;
+ size_t snritems = s->nitems;
+
+ /* Output all the items of a state, not just its kernel. */
+ if (report_flag & report_itemsets)
+ {
+ closure (sitems, snritems);
+ sitems = itemset;
+ snritems = nitemset;
+ }
+
+ obstack_printf (oout, _("State %d"), s->number);
+ obstack_sgrow (oout, "\\n\\l");
+ for (i = 0; i < snritems; i++)
+ {
+ item_number const *sp1 = ritem + sitems[i];
+ item_number const *sp = sp1;
+ rule *r;
+
+ while (0 <= *sp)
+ sp++;
+
+ r = &rules[item_number_as_rule_number (*sp)];
+
+ obstack_printf (oout, "%3d ", r->number);
+ if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag))
+ obstack_printf (oout, "%*s| ",
+ (int) strlen (previous_lhs->tag), "");
+ else
+ obstack_printf (oout, "%s: ", escape (r->lhs->tag));
+ previous_lhs = r->lhs;
+
+ for (sp = r->rhs; sp < sp1; sp++)
+ obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
+
+ obstack_1grow (oout, '.');
+
+ for (/* Nothing */; *sp >= 0; ++sp)
+ obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
+
+ /* 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, r);
+
+ /* 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");
+ }
+}
+
+
+/*---------------------------------------------------------------.
+| Output in graph_obstack edges specifications in incidence with |
+| current node. |
+`---------------------------------------------------------------*/
+
+static void
+print_actions (state const *s, FILE *fgraph)
+{
+ transitions const *trans = s->transitions;
+ int i;
+
+ if (!trans->num && !s->reductions)
+ return;
+
+ for (i = 0; i < trans->num; i++)
+ if (!TRANSITION_IS_DISABLED (trans, i))
+ {
+ state *s1 = trans->states[i];
+ symbol_number sym = s1->accessing_symbol;
+
+ /* 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 (TRANSITION_IS_ERROR (trans, i)
+ && STRNEQ (symbols[sym]->tag, "error"))
+ 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);
+}
+
+
+/*-------------------------------------------------------------.
+| Output in FGRAPH the current node specifications and exiting |
+| edges. |
+`-------------------------------------------------------------*/
+
+static void
+print_state (state *s, FILE *fgraph)
+{
+ struct obstack node_obstack;
+
+ /* A node's label contains its items. */
+ obstack_init (&node_obstack);
+ print_core (&node_obstack, s);
+ output_node (s->number, obstack_finish0 (&node_obstack), fgraph);
+ obstack_free (&node_obstack, 0);
+
+ /* Output the edges. */
+ print_actions (s, fgraph);
+}
+
+
+void
+print_graph (void)
+{
+ state_number i;
+ 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], fgraph);
+ free_closure ();
+
+ finish_graph (fgraph);
+ xfclose (fgraph);
+}
diff --git a/contrib/tools/bison/src/print_graph.h b/contrib/tools/bison/src/print_graph.h
new file mode 100644
index 0000000000..073ae988b6
--- /dev/null
+++ b/contrib/tools/bison/src/print_graph.h
@@ -0,0 +1,25 @@
+/* Output a graph of the generated parser, for Bison.
+
+ Copyright (C) 2000, 2006, 2009-2013 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_GRAPH_H_
+# define PRINT_GRAPH_H_
+
+void print_graph (void);
+
+#endif /* !PRINT_GRAPH_H_ */
diff --git a/contrib/tools/bison/src/reader.c b/contrib/tools/bison/src/reader.c
new file mode 100644
index 0000000000..95c595ed4e
--- /dev/null
+++ b/contrib/tools/bison/src/reader.c
@@ -0,0 +1,796 @@
+/* Input parser for Bison
+
+ Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000-2003, 2005-2007,
+ 2009-2013 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 <quote.h>
+
+#include "complain.h"
+#include "conflicts.h"
+#include "files.h"
+#include "getargs.h"
+#include "gram.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;
+static bool start_flag = false;
+merger_list *merge_functions;
+
+/* Was %union seen? */
+bool union_seen = false;
+
+/* Was a tag seen? */
+bool tag_seen = false;
+
+/* Should rules have a default precedence? */
+bool default_prec = true;
+
+/*-----------------------.
+| Set the start symbol. |
+`-----------------------*/
+
+void
+grammar_start_symbol_set (symbol *sym, location loc)
+{
+ if (start_flag)
+ complain (&loc, complaint, _("multiple %s declarations"), "%start");
+ else
+ {
+ start_flag = true;
+ startsymbol = sym;
+ startsymbol_location = loc;
+ }
+}
+
+
+
+/*------------------------------------------------------------------------.
+| 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)
+{
+ merger_list *syms;
+ merger_list head;
+ int n;
+
+ if (! glr_parser)
+ return 0;
+
+ head.next = merge_functions;
+ for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
+ if (UNIQSTR_EQ (name, syms->next->name))
+ break;
+ if (syms->next == NULL)
+ {
+ syms->next = xmalloc (sizeof syms->next[0]);
+ syms->next->name = uniqstr_new (name);
+ /* 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;
+ }
+ 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_indent (&declaration_loc, complaint, &indent,
+ _("result type clash on merge function %s: "
+ "<%s> != <%s>"),
+ quote (merge_function->name), type,
+ merge_function->type);
+ indent += SUB_INDENT;
+ complain_indent (&merge_function->type_declaration_location, complaint,
+ &indent,
+ _("previous declaration"));
+ }
+ merge_function->type = uniqstr_new (type);
+ merge_function->type_declaration_location = declaration_loc;
+}
+
+/*--------------------------------------.
+| Free all merge-function definitions. |
+`--------------------------------------*/
+
+void
+free_merger_functions (void)
+{
+ merger_list *L0 = merge_functions;
+ while (L0)
+ {
+ merger_list *L1 = L0->next;
+ free (L0);
+ L0 = L1;
+ }
+}
+
+
+/*-------------------------------------------------------------------.
+| Parse the input grammar into a one symbol_list structure. Each |
+| rule is represented by a sequence of symbols: the left hand side |
+| followed by the contents of the right hand side, followed by a |
+| null pointer instead of a symbol to terminate the rule. The next |
+| symbol is the lhs of the following rule. |
+| |
+| All actions are copied out, labelled by the rule number they apply |
+| to. |
+`-------------------------------------------------------------------*/
+
+/* The (currently) last symbol of GRAMMAR. */
+static symbol_list *grammar_end = NULL;
+
+/* Append SYM to the grammar. */
+static symbol_list *
+grammar_symbol_append (symbol *sym, location loc)
+{
+ symbol_list *p = symbol_list_sym_new (sym, loc);
+
+ if (grammar_end)
+ grammar_end->next = p;
+ else
+ grammar = p;
+
+ grammar_end = p;
+
+ /* A null SYM stands for an end of rule; it is not an actual
+ 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)
+ {
+ complain (&name->loc, Wother,
+ _("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). */
+static symbol_list *current_rule = NULL;
+static symbol_list *previous_rule_end = NULL;
+
+
+/*----------------------------------------------.
+| Create a new rule for LHS in to the GRAMMAR. |
+`----------------------------------------------*/
+
+void
+grammar_current_rule_begin (symbol *lhs, location loc,
+ named_ref *lhs_name)
+{
+ symbol_list* p;
+
+ /* Start a new rule and record its lhs. */
+ ++nrules;
+ previous_rule_end = grammar_end;
+
+ 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. */
+ if (lhs->class == unknown_sym)
+ {
+ lhs->class = nterm_sym;
+ lhs->number = nvars;
+ ++nvars;
+ }
+ else if (lhs->class == token_sym)
+ complain (&loc, complaint, _("rule given for %s, which is a token"),
+ lhs->tag);
+}
+
+
+/*----------------------------------------------------------------------.
+| 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, bool *midrule_warning)
+{
+ if (symbol_code_props_get (s->content.sym, destructor)->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;
+}
+
+/*----------------------------------------------------------------.
+| Check that the rule R is properly defined. For instance, there |
+| should be no type clash on the default action. |
+`----------------------------------------------------------------*/
+
+static void
+grammar_rule_check (const symbol_list *r)
+{
+ /* Type check.
+
+ If there is an action, then there is nothing we can do: the user
+ is allowed to shoot herself in the foot.
+
+ Don't worry about the default action if $$ is untyped, since $$'s
+ value can't be used. */
+ if (!r->action_props.code && r->content.sym->type_name)
+ {
+ 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->content.sym->type_name;
+ const char *rhs_type =
+ first_rhs->type_name ? first_rhs->type_name : "";
+ if (!UNIQSTR_EQ (lhs_type, rhs_type))
+ complain (&r->location, Wother,
+ _("type clash on default action: <%s> != <%s>"),
+ lhs_type, rhs_type);
+ }
+ /* Warn if there is no default for $$ but we need one. */
+ else
+ complain (&r->location, Wother,
+ _("empty rule for typed nonterminal, and no action"));
+ }
+
+ /* Check that symbol values that should be used are in fact used. */
+ {
+ symbol_list const *l = r;
+ int n = 0;
+ 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)))
+ {
+ warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
+ if (n)
+ complain (&l->location, warn_flag, _("unused value: $%d"), n);
+ else
+ complain (&l->location, warn_flag, _("unset value: $$"));
+ }
+ }
+ }
+
+ /* Check that %empty => empty rule. */
+ if (r->percent_empty_loc.start.file
+ && r->next && r->next->content.sym)
+ complain (&r->percent_empty_loc, complaint,
+ _("%%empty on non-empty rule"));
+
+ /* Check that empty rule => %empty. */
+ if (!(r->next && r->next->content.sym)
+ && !r->midrule_parent_rule
+ && !r->percent_empty_loc.start.file)
+ complain (&r->location, Wempty_rule, _("empty rule without %%empty"));
+
+ /* 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->status != declared && !r->ruleprec->prec)
+ complain (&r->location, Wother,
+ _("token for %%prec is not defined: %s"), r->ruleprec->tag);
+}
+
+
+/*-------------------------------------.
+| End the currently being grown rule. |
+`-------------------------------------*/
+
+void
+grammar_current_rule_end (location loc)
+{
+ /* 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;
+}
+
+
+/*-------------------------------------------------------------------.
+| The previous action turns out the be a mid-rule action. Attach it |
+| to the current rule, i.e., create a dummy symbol, attach it this |
+| mid-rule action, and append this dummy nonterminal to the current |
+| rule. |
+`-------------------------------------------------------------------*/
+
+void
+grammar_midrule_action (void)
+{
+ /* Since the action was written out with this rule's number, we must
+ give the new rule this number by inserting the new rule before
+ it. */
+
+ /* Make a DUMMY nonterminal, whose location is that of the midrule
+ action. Create the MIDRULE. */
+ location dummy_location = current_rule->action_props.location;
+ symbol *dummy = dummy_symbol_get (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. */
+ ++nrules;
+ ++nritems;
+ /* Attach its location and actions to that of the DUMMY. */
+ midrule->location = dummy_location;
+ code_props_rule_action_init (&midrule->action_props,
+ current_rule->action_props.code,
+ current_rule->action_props.location,
+ midrule, 0,
+ current_rule->action_props.is_predicate);
+ code_props_none_init (&current_rule->action_props);
+
+ if (previous_rule_end)
+ previous_rule_end->next = midrule;
+ else
+ grammar = midrule;
+
+ /* End the dummy's rule. */
+ 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,
+ 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. */
+
+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)
+ duplicate_directive ("%prec",
+ current_rule->ruleprec->location, loc);
+ else
+ current_rule->ruleprec = precsym;
+}
+
+/* Set %empty for the current rule. */
+
+void
+grammar_current_rule_empty_set (location loc)
+{
+ /* If %empty is used and -Wno-empty-rule is not, then enable
+ -Wempty-rule. */
+ if (warning_is_unset (Wempty_rule))
+ warning_argmatch ("empty-rule", 0, 0);
+ if (current_rule->percent_empty_loc.start.file)
+ duplicate_directive ("%empty",
+ current_rule->percent_empty_loc, loc);
+ else
+ current_rule->percent_empty_loc = loc;
+}
+
+/* Attach dynamic precedence DPREC to the current rule. */
+
+void
+grammar_current_rule_dprec_set (int dprec, location loc)
+{
+ if (! glr_parser)
+ complain (&loc, Wother, _("%s affects only GLR parsers"),
+ "%dprec");
+ if (dprec <= 0)
+ complain (&loc, complaint, _("%s must be followed by positive number"),
+ "%dprec");
+ else if (current_rule->dprec != 0)
+ duplicate_directive ("%dprec",
+ current_rule->dprec_location, loc);
+ else
+ {
+ current_rule->dprec = dprec;
+ current_rule->dprec_location = loc;
+ }
+}
+
+/* Attach a merge function NAME with argument type TYPE to current
+ rule. */
+
+void
+grammar_current_rule_merge_set (uniqstr name, location loc)
+{
+ if (! glr_parser)
+ complain (&loc, Wother, _("%s affects only GLR parsers"),
+ "%merge");
+ if (current_rule->merger != 0)
+ duplicate_directive ("%merge",
+ current_rule->merger_declaration_location, loc);
+ else
+ {
+ 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,
+ named_ref *name)
+{
+ symbol_list *p;
+ if (current_rule->action_props.code)
+ grammar_midrule_action ();
+ p = grammar_symbol_append (sym, loc);
+ if (name)
+ assign_named_ref (p, name);
+ if (sym->status == undeclared || sym->status == used)
+ sym->status = needed;
+}
+
+/* Attach an ACTION to the current rule. */
+
+void
+grammar_current_rule_action_append (const char *action, location loc,
+ named_ref *name, bool is_predicate)
+{
+ 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, is_predicate);
+}
+
+
+/*---------------------------------------------------------------.
+| Convert the rules into the representation using RRHS, RLHS and |
+| RITEM. |
+`---------------------------------------------------------------*/
+
+static void
+packgram (void)
+{
+ unsigned int itemno = 0;
+ rule_number ruleno = 0;
+ symbol_list *p;
+
+ ritem = xnmalloc (nritems + 1, sizeof *ritem);
+
+ /* This sentinel is used by build_relations in gram.c. */
+ *ritem++ = 0;
+
+ rules = xnmalloc (nrules, sizeof *rules);
+
+ for (p = grammar; p; p = p->next)
+ {
+ 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->content.sym;
+ rules[ruleno].rhs = ritem + itemno;
+ rules[ruleno].prec = NULL;
+ rules[ruleno].dprec = p->dprec;
+ rules[ruleno].merger = p->merger;
+ rules[ruleno].precsym = NULL;
+ rules[ruleno].location = p->location;
+ rules[ruleno].useful = true;
+ rules[ruleno].action = p->action_props.code;
+ rules[ruleno].action_location = p->action_props.location;
+ rules[ruleno].is_predicate = p->action_props.is_predicate;
+
+ /* 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);
+
+ {
+ size_t rule_length = 0;
+ for (p = p->next; 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)
+ complain (&rules[ruleno].location, fatal, _("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->content.sym->number);
+ /* A rule gets by default the precedence and associativity
+ 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,
+ the specified symbol's precedence replaces the default. */
+ if (ruleprec)
+ {
+ 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);
+ }
+
+ aver (itemno == nritems);
+
+ if (trace_flag & trace_sets)
+ ritem_print (stderr);
+}
+
+/*------------------------------------------------------------------.
+| Read in the grammar specification and record it in the format |
+| described in gram.h. All actions are copied into ACTION_OBSTACK, |
+| in each case forming the body of a C function (YYACTION) which |
+| contains a switch statement to decide which action to execute. |
+`------------------------------------------------------------------*/
+
+void
+reader (void)
+{
+ /* Initialize the symbol table. */
+ symbols_new ();
+
+ /* Construct the accept symbol. */
+ accept = symbol_get ("$accept", empty_location);
+ accept->class = nterm_sym;
+ accept->number = nvars++;
+
+ /* Construct the error token */
+ errtoken = symbol_get ("error", empty_location);
+ errtoken->class = token_sym;
+ errtoken->number = ntokens++;
+
+ /* Construct a token that represents all undefined literal tokens.
+ It is always token number 2. */
+ undeftoken = symbol_get ("$undefined", empty_location);
+ undeftoken->class = token_sym;
+ undeftoken->number = ntokens++;
+
+ gram_in = xfopen (grammar_file, "r");
+
+ gram__flex_debug = trace_flag & trace_scan;
+ gram_debug = trace_flag & trace_parse;
+ gram_scanner_initialize ();
+ gram_parse ();
+ prepare_percent_define_front_end_variables ();
+
+ if (complaint_status < status_complaint)
+ check_and_convert_grammar ();
+
+ 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-state", "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 (STRNEQ (lr_type, "canonical-lr"))
+ muscle_percent_define_default ("lr.default-reduction", "most");
+ else
+ muscle_percent_define_default ("lr.default-reduction", "accepting");
+ free (lr_type);
+ }
+
+ /* Check %define front-end variables. */
+ {
+ static char const * const values[] = {
+ "lr.type", "lalr", "ielr", "canonical-lr", NULL,
+ "lr.default-reduction", "most", "consistent", "accepting", NULL,
+ NULL
+ };
+ muscle_percent_define_check_values (values);
+ }
+}
+
+
+/*-------------------------------------------------------------.
+| Check the grammar that has just been read, and convert it to |
+| internal form. |
+`-------------------------------------------------------------*/
+
+static void
+check_and_convert_grammar (void)
+{
+ /* Grammar has been read. Do some checking. */
+ if (nrules == 0)
+ complain (NULL, fatal, _("no rules in the input grammar"));
+
+ /* If the user did not define her ENDTOKEN, do it now. */
+ if (!endtoken)
+ {
+ endtoken = symbol_get ("$end", empty_location);
+ endtoken->class = token_sym;
+ endtoken->number = 0;
+ /* Value specified by POSIX. */
+ 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 $end. */
+ {
+ symbol_list *p = symbol_list_sym_new (accept, empty_location);
+ p->location = grammar->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;
+ }
+
+ aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
+ aver (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. */
+ symbol_list_free (grammar);
+}
diff --git a/contrib/tools/bison/src/reader.h b/contrib/tools/bison/src/reader.h
new file mode 100644
index 0000000000..ba6ffe6edc
--- /dev/null
+++ b/contrib/tools/bison/src/reader.h
@@ -0,0 +1,73 @@
+/* Input parser for Bison
+
+ Copyright (C) 2000-2003, 2005-2007, 2009-2013 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 READER_H_
+# define READER_H_
+
+# include "location.h"
+# include "symlist.h"
+# include "named-ref.h"
+
+# include "parse-gram.h"
+
+typedef struct merger_list
+{
+ struct merger_list* next;
+ uniqstr name;
+ uniqstr type;
+ location type_declaration_location;
+} merger_list;
+
+/* From the parser. */
+extern int gram_debug;
+int gram_parse (void);
+char const *token_name (int type);
+
+
+/* From reader.c. */
+void grammar_start_symbol_set (symbol *sym, 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);
+/* Apply %empty to the current rule. */
+void grammar_current_rule_empty_set (location loc);
+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,
+ named_ref *nref);
+void grammar_current_rule_action_append (const char *action, location loc,
+ named_ref *nref, bool);
+void reader (void);
+void free_merger_functions (void);
+
+extern merger_list *merge_functions;
+
+/* Was %union seen? */
+extern bool union_seen;
+
+/* Was a tag seen? */
+extern bool tag_seen;
+
+/* Should rules have a default precedence? */
+extern bool default_prec;
+
+#endif /* !READER_H_ */
diff --git a/contrib/tools/bison/src/reduce.c b/contrib/tools/bison/src/reduce.c
new file mode 100644
index 0000000000..eea11b1e20
--- /dev/null
+++ b/contrib/tools/bison/src/reduce.c
@@ -0,0 +1,466 @@
+/* Grammar reduction for Bison.
+
+ Copyright (C) 1988-1989, 2000-2003, 2005-2013 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/>. */
+
+
+/* Reduce the grammar: Find and eliminate unreachable terminals,
+ nonterminals, and productions. David S. Bakin. */
+
+/* Don't eliminate unreachable terminals: They may be used by the
+ user's parser. */
+
+#include <config.h>
+#include "system.h"
+
+#include <bitset.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"
+
+/* Set of all nonterminals which are not useless. */
+static bitset N;
+
+/* Set of all rules which have no useless nonterminals in their RHS. */
+static bitset P;
+
+/* Set of all accessible symbols. */
+static bitset V;
+
+/* Set of symbols used to define rule precedence (so they are
+ 'useless', but no warning should be issued). */
+static bitset V1;
+
+static rule_number nuseful_productions;
+rule_number nuseless_productions;
+static int nuseful_nonterminals;
+symbol_number nuseless_nonterminals;
+
+/*-------------------------------------------------------------------.
+| Another way to do this would be with a set for each production and |
+| then do subset tests against N0, but even for the C grammar the |
+| whole reducing process takes only 2 seconds on my 8Mhz AT. |
+`-------------------------------------------------------------------*/
+
+static bool
+useful_production (rule_number r, bitset N0)
+{
+ item_number *rhsp;
+
+ /* A production is useful if all of the nonterminals in its appear
+ in the set of useful nonterminals. */
+
+ for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
+ if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens))
+ return false;
+ return true;
+}
+
+
+/*---------------------------------------------------------.
+| Remember that rules are 1-origin, symbols are 0-origin. |
+`---------------------------------------------------------*/
+
+static void
+useless_nonterminals (void)
+{
+ bitset Np, Ns;
+ rule_number r;
+
+ /* N is set as built. Np is set being built this iteration. P is
+ set of all productions which have a RHS all in N. */
+
+ Np = bitset_create (nvars, BITSET_FIXED);
+
+
+ /* The set being computed is a set of nonterminals which can derive
+ the empty string or strings consisting of all terminals. At each
+ iteration a nonterminal is added to the set if there is a
+ production with that nonterminal as its LHS for which all the
+ nonterminals in its RHS are already in the set. Iterate until
+ the set being computed remains unchanged. Any nonterminals not
+ in the set at that point are useless in that they will never be
+ used in deriving a sentence of the language.
+
+ This iteration doesn't use any special traversal over the
+ productions. A set is kept of all productions for which all the
+ nonterminals in the RHS are in useful. Only productions not in
+ this set are scanned on each iteration. At the end, this set is
+ saved to be used when finding useful productions: only
+ productions in this set will appear in the final grammar. */
+
+ while (1)
+ {
+ bitset_copy (Np, N);
+ for (r = 0; r < nrules; r++)
+ if (!bitset_test (P, r)
+ && useful_production (r, N))
+ {
+ bitset_set (Np, rules[r].lhs->number - ntokens);
+ bitset_set (P, r);
+ }
+ if (bitset_equal_p (N, Np))
+ break;
+ Ns = Np;
+ Np = N;
+ N = Ns;
+ }
+ bitset_free (N);
+ N = Np;
+}
+
+
+static void
+inaccessable_symbols (void)
+{
+ bitset Vp, Vs, Pp;
+
+ /* Find out which productions are reachable and which symbols are
+ used. Starting with an empty set of productions and a set of
+ symbols which only has the start symbol in it, iterate over all
+ productions until the set of productions remains unchanged for an
+ iteration. For each production which has a LHS in the set of
+ reachable symbols, add the production to the set of reachable
+ productions, and add all of the nonterminals in the RHS of the
+ production to the set of reachable symbols.
+
+ Consider only the (partially) reduced grammar which has only
+ nonterminals in N and productions in P.
+
+ The result is the set P of productions in the reduced grammar,
+ and the set V of symbols in the reduced grammar.
+
+ Although this algorithm also computes the set of terminals which
+ are reachable, no terminal will be deleted from the grammar. Some
+ terminals might not be in the grammar but might be generated by
+ semantic routines, and so the user might want them available with
+ specified numbers. (Is this true?) However, the nonreachable
+ terminals are printed (if running in verbose mode) so that the
+ user can know. */
+
+ Vp = bitset_create (nsyms, BITSET_FIXED);
+ Pp = bitset_create (nrules, BITSET_FIXED);
+
+ /* If the start symbol isn't useful, then nothing will be useful. */
+ if (bitset_test (N, accept->number - ntokens))
+ {
+ bitset_set (V, accept->number);
+
+ while (1)
+ {
+ rule_number r;
+ bitset_copy (Vp, V);
+ for (r = 0; r < nrules; r++)
+ {
+ if (!bitset_test (Pp, r)
+ && bitset_test (P, r)
+ && bitset_test (V, rules[r].lhs->number))
+ {
+ item_number *rhsp;
+ for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+ if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
+ bitset_set (Vp, *rhsp);
+ bitset_set (Pp, r);
+ }
+ }
+ if (bitset_equal_p (V, Vp))
+ break;
+ Vs = Vp;
+ Vp = V;
+ V = Vs;
+ }
+ }
+
+ bitset_free (V);
+ V = Vp;
+
+ /* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
+ bitset_set (V, endtoken->number); /* end-of-input token */
+ bitset_set (V, errtoken->number); /* error token */
+ bitset_set (V, undeftoken->number); /* some undefined token */
+
+ bitset_free (P);
+ P = Pp;
+
+ nuseful_productions = bitset_count (P);
+ nuseless_productions = nrules - nuseful_productions;
+
+ nuseful_nonterminals = 0;
+ {
+ symbol_number i;
+ for (i = ntokens; i < nsyms; i++)
+ if (bitset_test (V, i))
+ nuseful_nonterminals++;
+ }
+ nuseless_nonterminals = nvars - nuseful_nonterminals;
+
+ /* A token that was used in %prec should not be warned about. */
+ {
+ rule_number r;
+ for (r = 0; r < nrules; ++r)
+ if (rules[r].precsym != 0)
+ bitset_set (V1, rules[r].precsym->number);
+ }
+}
+
+
+/*-------------------------------------------------------------------.
+| Put the useless productions at the end of RULES, and adjust NRULES |
+| accordingly. |
+`-------------------------------------------------------------------*/
+
+static void
+reduce_grammar_tables (void)
+{
+ /* Report and flag useless productions. */
+ {
+ rule_number r;
+ for (r = 0; r < nrules; r++)
+ rules[r].useful = bitset_test (P, r);
+ grammar_rules_useless_report (_("rule useless in grammar"));
+ }
+
+ /* Map the nonterminals to their new index: useful first, useless
+ afterwards. Kept for later report. */
+ {
+ int useful = 0;
+ int useless = nrules - nuseless_productions;
+ rule *rules_sorted = xnmalloc (nrules, sizeof *rules_sorted);
+ rule_number r;
+ for (r = 0; r < nrules; ++r)
+ rules_sorted[rules[r].useful ? useful++ : useless++] = rules[r];
+ free (rules);
+ rules = rules_sorted;
+
+ /* Renumber the rules markers in RITEMS. */
+ for (r = 0; r < nrules; ++r)
+ {
+ item_number *rhsp = rules[r].rhs;
+ for (/* Nothing. */; *rhsp >= 0; ++rhsp)
+ /* Nothing. */;
+ *rhsp = rule_number_as_item_number (r);
+ rules[r].number = r;
+ }
+ nrules -= nuseless_productions;
+ }
+
+ /* Adjust NRITEMS. */
+ {
+ rule_number r;
+ int length;
+ for (r = nrules; r < nrules + nuseless_productions; ++r)
+ {
+ length = rule_rhs_length (&rules[r]);
+ nritems -= length + 1;
+ }
+ }
+}
+
+
+/*------------------------------.
+| Remove useless nonterminals. |
+`------------------------------*/
+
+static void
+nonterminals_reduce (void)
+{
+ /* Map the nonterminals to their new index: useful first, useless
+ afterwards. Kept for later report. */
+
+ symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
+ symbol_number n = ntokens;
+ symbol_number i;
+ for (i = ntokens; i < nsyms; i++)
+ if (bitset_test (V, i))
+ nontermmap[i - ntokens] = n++;
+ for (i = ntokens; i < nsyms; i++)
+ if (!bitset_test (V, i))
+ {
+ nontermmap[i - ntokens] = n++;
+ if (symbols[i]->status != used)
+ complain (&symbols[i]->location, Wother,
+ _("nonterminal useless in grammar: %s"),
+ symbols[i]->tag);
+ }
+
+
+ /* Shuffle elements of tables indexed by symbol number. */
+ {
+ symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
+
+ for (i = ntokens; i < nsyms; i++)
+ symbols[i]->number = nontermmap[i - ntokens];
+ for (i = ntokens; i < nsyms; i++)
+ symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
+ for (i = ntokens; i < nsyms; i++)
+ symbols[i] = symbols_sorted[i - ntokens];
+ free (symbols_sorted);
+ }
+
+ {
+ rule_number r;
+ for (r = 0; r < nrules; ++r)
+ {
+ item_number *rhsp;
+ for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
+ if (ISVAR (*rhsp))
+ *rhsp = symbol_number_as_item_number (nontermmap[*rhsp
+ - ntokens]);
+ }
+ accept->number = nontermmap[accept->number - ntokens];
+ }
+
+ nsyms -= nuseless_nonterminals;
+ nvars -= nuseless_nonterminals;
+
+ free (nontermmap);
+}
+
+
+/*------------------------------------------------------------------.
+| Output the detailed results of the reductions. For FILE.output. |
+`------------------------------------------------------------------*/
+
+void
+reduce_output (FILE *out)
+{
+ if (nuseless_nonterminals > 0)
+ {
+ int i;
+ 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);
+ }
+
+ {
+ bool b = false;
+ int i;
+ for (i = 0; i < ntokens; i++)
+ if (reduce_token_unused_in_grammar (i))
+ {
+ if (!b)
+ fprintf (out, "%s\n\n", _("Terminals unused in grammar"));
+ b = true;
+ fprintf (out, " %s\n", symbols[i]->tag);
+ }
+ if (b)
+ fputs ("\n\n", out);
+ }
+
+ if (nuseless_productions > 0)
+ grammar_rules_partial_print (out, _("Rules useless in grammar"),
+ rule_useless_in_grammar_p);
+}
+
+
+/*-------------------------------.
+| Report the results to STDERR. |
+`-------------------------------*/
+
+static void
+reduce_print (void)
+{
+ if (nuseless_nonterminals > 0)
+ complain (NULL, Wother, ngettext ("%d nonterminal useless in grammar",
+ "%d nonterminals useless in grammar",
+ nuseless_nonterminals),
+ nuseless_nonterminals);
+ if (nuseless_productions > 0)
+ complain (NULL, Wother, ngettext ("%d rule useless in grammar",
+ "%d rules useless in grammar",
+ nuseless_productions),
+ nuseless_productions);
+}
+
+void
+reduce_grammar (void)
+{
+ bool reduced;
+
+ /* Allocate the global sets used to compute the reduced grammar */
+
+ N = bitset_create (nvars, BITSET_FIXED);
+ P = bitset_create (nrules, BITSET_FIXED);
+ V = bitset_create (nsyms, BITSET_FIXED);
+ V1 = bitset_create (nsyms, BITSET_FIXED);
+
+ useless_nonterminals ();
+ inaccessable_symbols ();
+
+ reduced = (nuseless_nonterminals + nuseless_productions > 0);
+ if (!reduced)
+ return;
+
+ reduce_print ();
+
+ if (!bitset_test (N, accept->number - ntokens))
+ complain (&startsymbol_location, fatal,
+ _("start symbol %s does not derive any sentence"),
+ startsymbol->tag);
+
+ /* First reduce the nonterminals, as they renumber themselves in the
+ whole grammar. If you change the order, nonterms would be
+ renumbered only in the reduced grammar. */
+ if (nuseless_nonterminals > 0)
+ nonterminals_reduce ();
+ if (nuseless_productions > 0)
+ reduce_grammar_tables ();
+
+ if (trace_flag & trace_grammar)
+ {
+ grammar_dump (stderr, "Reduced Grammar");
+
+ fprintf (stderr, "reduced %s defines %d terminals, %d nonterminals"
+ ", and %d productions.\n",
+ grammar_file, ntokens, nvars, nrules);
+ }
+}
+
+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. |
+`-----------------------------------------------------------*/
+
+void
+reduce_free (void)
+{
+ bitset_free (N);
+ bitset_free (V);
+ bitset_free (V1);
+ bitset_free (P);
+}
diff --git a/contrib/tools/bison/src/reduce.h b/contrib/tools/bison/src/reduce.h
new file mode 100644
index 0000000000..bc12ed0e50
--- /dev/null
+++ b/contrib/tools/bison/src/reduce.h
@@ -0,0 +1,32 @@
+/* Grammar reduction for Bison.
+
+ Copyright (C) 2000-2002, 2007, 2009-2013 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 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;
+extern rule_number nuseless_productions;
+#endif /* !REDUCE_H_ */
diff --git a/contrib/tools/bison/src/relation.c b/contrib/tools/bison/src/relation.c
new file mode 100644
index 0000000000..5746eca704
--- /dev/null
+++ b/contrib/tools/bison/src/relation.c
@@ -0,0 +1,183 @@
+/* Binary relations.
+
+ Copyright (C) 2002, 2004-2005, 2009-2013 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 <bitsetv.h>
+
+#include "getargs.h"
+#include "relation.h"
+
+void
+relation_print (relation r, relation_node size, FILE *out)
+{
+ relation_node i;
+ relation_node j;
+
+ for (i = 0; i < size; ++i)
+ {
+ fprintf (out, "%3lu: ", (unsigned long int) i);
+ if (r[i])
+ for (j = 0; r[i][j] != END_NODE; ++j)
+ fprintf (out, "%3lu ", (unsigned long int) r[i][j]);
+ fputc ('\n', out);
+ }
+ fputc ('\n', out);
+}
+
+
+/*---------------------------------------------------------------.
+| digraph & traverse. |
+| |
+| The following variables are used as common storage between the |
+| two. |
+`---------------------------------------------------------------*/
+
+static relation R;
+static relation_nodes INDEX;
+static relation_nodes VERTICES;
+static relation_node top;
+static relation_node infinity;
+static bitsetv F;
+
+static void
+traverse (relation_node i)
+{
+ relation_node j;
+ relation_node height;
+
+ VERTICES[++top] = i;
+ INDEX[i] = height = top;
+
+ if (R[i])
+ for (j = 0; R[i][j] != END_NODE; ++j)
+ {
+ if (INDEX[R[i][j]] == 0)
+ traverse (R[i][j]);
+
+ if (INDEX[i] > INDEX[R[i][j]])
+ INDEX[i] = INDEX[R[i][j]];
+
+ bitset_or (F[i], F[i], F[R[i][j]]);
+ }
+
+ if (INDEX[i] == height)
+ for (;;)
+ {
+ j = VERTICES[top--];
+ INDEX[j] = infinity;
+
+ if (i == j)
+ break;
+
+ bitset_copy (F[j], F[i]);
+ }
+}
+
+
+void
+relation_digraph (relation r, relation_node size, bitsetv *function)
+{
+ relation_node i;
+
+ infinity = size + 2;
+ INDEX = xcalloc (size + 1, sizeof *INDEX);
+ VERTICES = xnmalloc (size + 1, sizeof *VERTICES);
+ top = 0;
+
+ R = r;
+ F = *function;
+
+ for (i = 0; i < size; i++)
+ if (INDEX[i] == 0 && R[i])
+ traverse (i);
+
+ free (INDEX);
+ free (VERTICES);
+
+ *function = F;
+}
+
+
+/*-------------------------------------------.
+| Destructively transpose R_ARG, of size N. |
+`-------------------------------------------*/
+
+void
+relation_transpose (relation *R_arg, relation_node n)
+{
+ relation r = *R_arg;
+ /* The result. */
+ relation new_R = xnmalloc (n, sizeof *new_R);
+ /* END_R[I] -- next entry of NEW_R[I]. */
+ relation end_R = xnmalloc (n, sizeof *end_R);
+ /* NEDGES[I] -- total size of NEW_R[I]. */
+ size_t *nedges = xcalloc (n, sizeof *nedges);
+ relation_node i;
+ relation_node j;
+
+ if (trace_flag & trace_sets)
+ {
+ fputs ("relation_transpose: input\n", stderr);
+ relation_print (r, n, stderr);
+ }
+
+ /* Count. */
+ for (i = 0; i < n; i++)
+ if (r[i])
+ for (j = 0; r[i][j] != END_NODE; ++j)
+ ++nedges[r[i][j]];
+
+ /* Allocate. */
+ for (i = 0; i < n; i++)
+ {
+ relation_node *sp = NULL;
+ if (nedges[i] > 0)
+ {
+ sp = xnmalloc (nedges[i] + 1, sizeof *sp);
+ sp[nedges[i]] = END_NODE;
+ }
+ new_R[i] = sp;
+ end_R[i] = sp;
+ }
+
+ /* Store. */
+ for (i = 0; i < n; i++)
+ if (r[i])
+ for (j = 0; r[i][j] != END_NODE; ++j)
+ *end_R[r[i][j]]++ = i;
+
+ free (nedges);
+ free (end_R);
+
+ /* Free the input: it is replaced with the result. */
+ for (i = 0; i < n; i++)
+ free (r[i]);
+ free (r);
+
+ if (trace_flag & trace_sets)
+ {
+ fputs ("relation_transpose: output\n", stderr);
+ relation_print (new_R, n, stderr);
+ }
+
+ *R_arg = new_R;
+}
diff --git a/contrib/tools/bison/src/relation.h b/contrib/tools/bison/src/relation.h
new file mode 100644
index 0000000000..b44e1a7f98
--- /dev/null
+++ b/contrib/tools/bison/src/relation.h
@@ -0,0 +1,49 @@
+/* Binary relations.
+
+ Copyright (C) 2002, 2004, 2009-2013 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 RELATION_H_
+# define RELATION_H_
+
+/* Performing operations on graphs coded as list of adjacency.
+
+ If GRAPH is a relation, then GRAPH[Node] is a list of adjacent
+ nodes, ended with END_NODE. */
+
+# define END_NODE ((relation_node) -1)
+
+typedef size_t relation_node;
+typedef relation_node *relation_nodes;
+typedef relation_nodes *relation;
+
+
+/* Report a relation R that has SIZE vertices. */
+void relation_print (relation r, relation_node size, FILE *out);
+
+/* Compute the transitive closure of the FUNCTION on the relation R
+ with SIZE vertices.
+
+ If R (NODE-1, NODE-2) then on exit FUNCTION[NODE - 1] was extended
+ (unioned) with FUNCTION[NODE - 2]. */
+void relation_digraph (relation r, relation_node size, bitsetv *function);
+
+/* Destructively transpose *R_ARG, of size N. */
+void relation_transpose (relation *R_arg, relation_node n);
+
+#endif /* ! RELATION_H_ */
diff --git a/contrib/tools/bison/src/scan-code-c.c b/contrib/tools/bison/src/scan-code-c.c
new file mode 100644
index 0000000000..7d37b766b5
--- /dev/null
+++ b/contrib/tools/bison/src/scan-code-c.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#include "system.h"
+#include "src/scan-code.c"
diff --git a/contrib/tools/bison/src/scan-code.c b/contrib/tools/bison/src/scan-code.c
new file mode 100644
index 0000000000..971f30241f
--- /dev/null
+++ b/contrib/tools/bison/src/scan-code.c
@@ -0,0 +1,2990 @@
+#line 2 "src/scan-code.c"
+
+#line 4 "src/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 18
+#define YY_END_OF_BUFFER 19
+/* 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[91] =
+ { 0,
+ 0, 0, 0, 0, 3, 3, 4, 4, 4, 4,
+ 0, 0, 0, 0, 19, 17, 16, 17, 2, 17,
+ 6, 17, 5, 8, 11, 7, 17, 11, 11, 11,
+ 1, 0, 0, 3, 4, 4, 4, 4, 12, 0,
+ 12, 12, 0, 0, 9, 10, 0, 13, 0, 13,
+ 13, 0, 14, 0, 15, 0, 0, 0, 0, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 13, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 0,
+ 12, 12, 0, 14, 12, 12, 0, 0, 0, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 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, 2, 1, 4, 1, 5, 1, 1, 6, 1,
+ 1, 7, 1, 1, 8, 9, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 1, 1, 12,
+ 1, 13, 1, 14, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 15, 16, 17, 1, 9, 1, 9, 9, 9, 9,
+
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 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, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[19] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 3, 3, 1,
+ 3, 1, 2, 1, 1, 1, 1, 2
+ } ;
+
+static yyconst flex_int16_t yy_base[97] =
+ { 0,
+ 0, 13, 121, 120, 0, 3, 4, 5, 6, 7,
+ 27, 0, 20, 21, 125, 178, 178, 26, 178, 8,
+ 178, 41, 178, 178, 53, 178, 62, 74, 33, 119,
+ 178, 37, 44, 105, 178, 46, 101, 48, 178, 99,
+ 0, 96, 98, 91, 178, 178, 50, 178, 87, 0,
+ 86, 87, 178, 76, 178, 52, 50, 68, 71, 73,
+ 78, 74, 0, 16, 78, 84, 85, 0, 0, 94,
+ 86, 96, 55, 107, 0, 0, 58, 118, 100, 124,
+ 130, 136, 142, 106, 46, 0, 148, 43, 0, 178,
+ 165, 168, 4, 171, 1, 174
+
+ } ;
+
+static yyconst flex_int16_t yy_def[97] =
+ { 0,
+ 91, 91, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 11, 11, 11, 90, 90, 90, 90, 90, 90,
+ 90, 92, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+ 93, 90, 94, 90, 90, 90, 90, 90, 90, 95,
+ 90, 90, 90, 96, 90, 90, 90, 90, 90, 90,
+ 90, 92, 93, 94, 94, 90, 90, 27, 95, 90,
+ 96, 96, 25, 94, 66, 70, 90, 96, 94, 94,
+ 94, 94, 94, 96, 81, 81, 81, 87, 87, 0,
+ 90, 90, 90, 90, 90, 90
+
+ } ;
+
+static yyconst flex_int16_t yy_nxt[197] =
+ { 0,
+ 90, 90, 19, 69, 17, 19, 63, 21, 21, 33,
+ 34, 23, 23, 17, 17, 20, 17, 17, 20, 22,
+ 22, 22, 22, 65, 29, 29, 17, 17, 73, 17,
+ 24, 25, 26, 30, 30, 31, 27, 53, 56, 57,
+ 28, 32, 36, 37, 54, 33, 34, 59, 37, 61,
+ 62, 67, 68, 56, 57, 74, 38, 39, 74, 31,
+ 40, 41, 53, 42, 43, 32, 90, 44, 45, 33,
+ 34, 46, 59, 37, 59, 37, 90, 47, 48, 61,
+ 62, 49, 50, 72, 51, 65, 67, 68, 52, 38,
+ 74, 75, 75, 72, 75, 70, 51, 51, 77, 66,
+
+ 39, 76, 76, 72, 76, 65, 42, 65, 78, 42,
+ 48, 79, 73, 72, 80, 81, 60, 82, 77, 73,
+ 58, 83, 84, 55, 90, 72, 18, 18, 90, 90,
+ 77, 65, 90, 90, 82, 90, 74, 85, 86, 90,
+ 86, 90, 73, 65, 90, 90, 82, 90, 73, 65,
+ 87, 90, 90, 90, 73, 88, 89, 90, 89, 90,
+ 90, 90, 90, 90, 79, 16, 16, 16, 35, 35,
+ 35, 64, 90, 64, 71, 90, 71, 15, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90
+
+ } ;
+
+static yyconst flex_int16_t yy_chk[197] =
+ { 0,
+ 0, 0, 5, 95, 1, 6, 93, 7, 8, 20,
+ 20, 9, 10, 1, 1, 5, 1, 2, 6, 7,
+ 8, 9, 10, 64, 13, 14, 2, 2, 64, 2,
+ 11, 11, 11, 13, 14, 18, 11, 29, 32, 32,
+ 11, 18, 22, 22, 29, 33, 33, 36, 36, 38,
+ 38, 47, 47, 56, 56, 88, 22, 25, 85, 57,
+ 25, 25, 77, 25, 25, 57, 73, 25, 27, 58,
+ 58, 27, 59, 59, 60, 60, 62, 27, 28, 61,
+ 61, 28, 28, 54, 28, 65, 67, 67, 28, 62,
+ 65, 66, 66, 71, 66, 52, 51, 49, 71, 44,
+
+ 66, 70, 70, 72, 70, 43, 42, 79, 72, 40,
+ 70, 74, 79, 84, 74, 74, 37, 74, 84, 74,
+ 34, 74, 78, 30, 15, 78, 4, 3, 0, 0,
+ 78, 80, 0, 0, 80, 0, 80, 81, 81, 0,
+ 81, 0, 81, 82, 0, 0, 82, 0, 82, 83,
+ 83, 0, 0, 0, 83, 87, 87, 0, 87, 0,
+ 0, 0, 0, 0, 87, 91, 91, 91, 92, 92,
+ 92, 94, 0, 94, 96, 0, 96, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90
+
+ } ;
+
+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[18] =
+ { 0,
+ 114, 124, 125, 135, 140, 145, 151, 152, 153, 154,
+ 156, 164, 170, 180, 188, 198, 201
+ } ;
+
+/* 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 "../../src/scan-code.l"
+/* Bison Action Scanner -*- C -*-
+
+ Copyright (C) 2006-2013 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 "../../src/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 <src/flex-scanner.h>
+
+#include <src/complain.h>
+#include <src/reader.h>
+#include <src/getargs.h>
+#include <src/muscle-tab.h>
+#include <src/scan-code.h>
+#include <src/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. We allow
+ "->" as a means to dereference a pointer. */
+/* 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 713 "src/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 96 "../../src/scan-code.l"
+
+
+
+ /* 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 976 "src/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 >= 91 )
+ 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 != 90 );
+ 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 < 18 )
+ fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+ (long)yy_rule_linenum[yy_act], code_text );
+ else if ( yy_act == 18 )
+ fprintf( stderr, "--accepting default rule (\"%s\")\n",
+ code_text );
+ else if ( yy_act == 19 )
+ 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 114 "../../src/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 124 "../../src/scan-code.l"
+STRING_GROW; BEGIN sc_context;
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 125 "../../src/scan-code.l"
+STRING_GROW;
+ YY_BREAK
+
+/*--------------------------------------------.
+ | Scanning user-code characters and strings. |
+ `--------------------------------------------*/
+
+
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+#line 135 "../../src/scan-code.l"
+STRING_GROW;
+ YY_BREAK
+
+
+
+case 5:
+YY_RULE_SETUP
+#line 140 "../../src/scan-code.l"
+STRING_GROW; BEGIN sc_context;
+ YY_BREAK
+
+
+
+case 6:
+YY_RULE_SETUP
+#line 145 "../../src/scan-code.l"
+STRING_GROW; BEGIN sc_context;
+ YY_BREAK
+
+
+
+case 7:
+YY_RULE_SETUP
+#line 151 "../../src/scan-code.l"
+STRING_GROW; BEGIN SC_CHARACTER;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 152 "../../src/scan-code.l"
+STRING_GROW; BEGIN SC_STRING;
+ YY_BREAK
+case 9:
+/* rule 9 can match eol */
+YY_RULE_SETUP
+#line 153 "../../src/scan-code.l"
+STRING_GROW; BEGIN SC_COMMENT;
+ YY_BREAK
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 154 "../../src/scan-code.l"
+STRING_GROW; BEGIN SC_LINE_COMMENT;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 156 "../../src/scan-code.l"
+{
+ complain (loc, Wother, _("stray '%s'"), code_text);
+ obstack_escape (&obstack_for_string, code_text);
+ }
+ YY_BREAK
+
+
+
+case 12:
+YY_RULE_SETUP
+#line 164 "../../src/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);
+ }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 170 "../../src/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);
+ }
+ YY_BREAK
+
+
+
+case 14:
+YY_RULE_SETUP
+#line 180 "../../src/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 15:
+YY_RULE_SETUP
+#line 188 "../../src/scan-code.l"
+{
+ obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
+ muscle_percent_define_ensure("locations", the_location, true);
+ }
+ YY_BREAK
+
+
+
+/* Escape M4 quoting characters in C code. */
+case 16:
+YY_RULE_SETUP
+#line 198 "../../src/scan-code.l"
+obstack_escape (&obstack_for_string, code_text);
+ YY_BREAK
+/* By default, grow the string obstack with the input. */
+case 17:
+/* rule 17 can match eol */
+YY_RULE_SETUP
+#line 201 "../../src/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 204 "../../src/scan-code.l"
+STRING_FINISH; return last_string;
+ YY_BREAK
+
+case 18:
+YY_RULE_SETUP
+#line 207 "../../src/scan-code.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 1250 "src/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)] : 18);
+ 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 >= 91 )
+ 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 = 18;
+ 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 >= 91 )
+ 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 == 90);
+
+ 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 207 "../../src/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_message (warnings warning,
+ const char* cp, bool explicit_bracketing,
+ int midrule_rhs_index, char dollar_or_at,
+ unsigned indent, const variant *var)
+{
+ const char *at_spec = get_at_spec (var->symbol_index);
+
+ if (var->err == 0)
+ complain_indent (&var->loc, warning, &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)
+ obstack_printf (&msg_buf,
+ _(", cannot be accessed from mid-rule action at $%d"),
+ midrule_rhs_index);
+
+ complain_indent (&id_loc, warning, &indent, "%s",
+ obstack_finish0 (&msg_buf));
+ obstack_free (&msg_buf, 0);
+ }
+}
+
+static void
+show_sub_messages (warnings warning,
+ const char* cp, bool explicit_bracketing,
+ int midrule_rhs_index, char dollar_or_at,
+ unsigned indent)
+{
+ unsigned i;
+
+ for (i = 0; i < variant_count; ++i)
+ show_sub_message (warning | silent,
+ cp, explicit_bracketing,
+ midrule_rhs_index, dollar_or_at,
+ indent, &variant_table[i]);
+}
+
+/* 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 (&text_loc, complaint, _("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_indent (&text_loc, complaint, &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;
+ complain_indent (&sym_loc, complaint, &indent,
+ _("syntax error after '%c', expecting integer, "
+ "letter, '_', '[', or '$'"),
+ dollar_or_at);
+ }
+ else if (midrule_rhs_index)
+ complain_indent (&rule->location, complaint, &indent,
+ _("symbol not found in production before $%d: "
+ "%.*s"),
+ midrule_rhs_index, len, cp);
+ else
+ complain_indent (&rule->location, complaint, &indent,
+ _("symbol not found in production: %.*s"),
+ len, cp);
+
+ if (variant_count > 0)
+ show_sub_messages (complaint,
+ cp, explicit_bracketing, midrule_rhs_index,
+ dollar_or_at, indent);
+ return INVALID_REF;
+ }
+ case 1:
+ {
+ unsigned indent = 0;
+ if (variant_count > 1)
+ {
+ complain_indent (&text_loc, Wother, &indent,
+ _("misleading reference: %s"), quote (text));
+ show_sub_messages (Wother,
+ cp, explicit_bracketing, midrule_rhs_index,
+ dollar_or_at, 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_indent (&text_loc, complaint, &indent,
+ _("ambiguous reference: %s"), quote (text));
+ show_sub_messages (complaint,
+ cp, explicit_bracketing, midrule_rhs_index,
+ dollar_or_at, 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;
+ /* Series of non-'>' or "->". */
+ while (*cp != '>' || cp[-1] == '-')
+ ++cp;
+
+ /* The '>' symbol will be later replaced by '\0'. Original
+ 'text' is needed for error messages. */
+ ++cp;
+ if (untyped_var_seen)
+ complain (&dollar_loc, complaint,
+ _("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 (&dollar_loc, complaint,
+ _("$$ for the midrule at $%d of %s"
+ " has no declared type"),
+ rule->midrule_parent_rhs_index,
+ quote (effective_rule->content.sym->tag));
+ else
+ complain (&dollar_loc, complaint,
+ _("$$ 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 (&dollar_loc, complaint,
+ _("$%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);
+ }
+
+ muscle_percent_define_ensure("locations", at_loc, 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 code_props_none = CODE_PROPS_NONE_INIT;
+
+void
+code_props_plain_init (code_props *self, char const *code,
+ location code_loc)
+{
+ code_props_none_init (self);
+ self->kind = CODE_PROPS_PLAIN;
+ self->code = code;
+ self->location = code_loc;
+}
+
+void
+code_props_symbol_action_init (code_props *self, char const *code,
+ location code_loc)
+{
+ code_props_none_init (self);
+ self->kind = CODE_PROPS_SYMBOL_ACTION;
+ self->code = code;
+ self->location = code_loc;
+}
+
+void
+code_props_rule_action_init (code_props *self, char const *code,
+ location code_loc, symbol_list *rule,
+ named_ref *name, bool is_predicate)
+{
+ code_props_none_init (self);
+ self->kind = CODE_PROPS_RULE_ACTION;
+ self->code = code;
+ self->location = code_loc;
+ self->rule = rule;
+ self->named_ref = name;
+ self->is_predicate = is_predicate;
+}
+
+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/contrib/tools/bison/src/scan-code.h b/contrib/tools/bison/src/scan-code.h
new file mode 100644
index 0000000000..d5a15c1a1c
--- /dev/null
+++ b/contrib/tools/bison/src/scan-code.h
@@ -0,0 +1,196 @@
+/* Bison code properties structure and scanner.
+
+ Copyright (C) 2006-2007, 2009-2013 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 true iff this code is an action that is not to be deferred in
+ * a non-deterministic parser.
+ */
+ bool is_predicate;
+
+ /**
+ * Whether this is actually used (i.e., not completely masked by
+ * other code props). */
+ bool is_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 \
+ { \
+ /* .kind = */ CODE_PROPS_NONE, \
+ /* .code = */ NULL, \
+ /* .location = */ EMPTY_LOCATION_INIT, \
+ /* .is_value_used = */ false, \
+ /* .is_predicate = */ false, \
+ /* .is_used = */ false, \
+ /* .rule = */ NULL, \
+ /* .named_ref = */ NULL \
+ }
+
+/** Initialized by \c CODE_PROPS_NONE_INIT with no further modification. */
+extern code_props 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, bool is_predicate);
+
+/**
+ * \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/contrib/tools/bison/src/scan-gram-c.c b/contrib/tools/bison/src/scan-gram-c.c
new file mode 100644
index 0000000000..2b4fc67b48
--- /dev/null
+++ b/contrib/tools/bison/src/scan-gram-c.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#include "system.h"
+#include "src/scan-gram.c"
diff --git a/contrib/tools/bison/src/scan-gram.c b/contrib/tools/bison/src/scan-gram.c
new file mode 100644
index 0000000000..3c74a56bea
--- /dev/null
+++ b/contrib/tools/bison/src/scan-gram.c
@@ -0,0 +1,4018 @@
+#line 2 "src/scan-gram.c"
+
+#line 4 "src/scan-gram.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 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 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 gram_restart(gram_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 gram_leng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+extern FILE *gram_in, *gram_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 gram_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 gram_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 gram_restart()), so that the user can continue scanning by
+ * just pointing gram_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 gram_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 gram_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 gram_wrap()'s to do buffer switches
+ * instead of setting up a fresh gram_in. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+/* %ok-for-header */
+
+/* %endif */
+
+void gram_restart (FILE *input_file );
+void gram__switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE gram__create_buffer (FILE *file,int size );
+void gram__delete_buffer (YY_BUFFER_STATE b );
+void gram__flush_buffer (YY_BUFFER_STATE b );
+void gram_push_buffer_state (YY_BUFFER_STATE new_buffer );
+void gram_pop_buffer_state (void );
+
+static void gram_ensure_buffer_stack (void );
+static void gram__load_buffer_state (void );
+static void gram__init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER gram__flush_buffer(YY_CURRENT_BUFFER )
+
+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,yy_size_t len );
+
+/* %endif */
+
+void *gram_alloc (yy_size_t );
+void *gram_realloc (void *,yy_size_t );
+void gram_free (void * );
+
+#define yy_new_buffer gram__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ gram_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ gram__create_buffer(gram_in,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ gram_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ gram__create_buffer(gram_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] gram_text/gram_in/gram_out/yy_state_type/gram_lineno etc. def's & init go here */
+/* Begin user sect3 */
+
+#define gram_wrap() 1
+#define YY_SKIP_YYWRAP
+
+#define FLEX_DEBUG
+
+typedef unsigned char YY_CHAR;
+
+FILE *gram_in = (FILE *) 0, *gram_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int gram_lineno;
+
+int gram_lineno = 1;
+
+extern char *gram_text;
+#define yytext_ptr gram_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 gram_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle gram_text and gram_leng for yymore() goes here \ */\
+ gram_leng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to gram_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 130
+#define YY_END_OF_BUFFER 131
+/* 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[582] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 93, 93, 113, 113, 113, 113, 0, 0,
+ 0, 0, 131, 80, 2, 2, 71, 80, 70, 80,
+ 1, 66, 80, 67, 67, 65, 77, 63, 66, 79,
+ 73, 64, 80, 90, 90, 128, 95, 94, 128, 81,
+ 97, 96, 84, 2, 1, 84, 83, 82, 84, 99,
+ 99, 100, 98, 81, 129, 119, 128, 118, 128, 128,
+ 128, 122, 125, 126, 128, 92, 128, 117, 116, 128,
+ 115, 114, 87, 2, 1, 85, 87, 87, 86, 87,
+
+ 88, 2, 1, 88, 88, 80, 0, 78, 62, 0,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 72, 66,
+ 66, 4, 3, 69, 67, 69, 0, 76, 0, 89,
+ 112, 110, 101, 112, 103, 104, 105, 106, 107, 108,
+ 112, 109, 112, 99, 99, 100, 127, 120, 121, 0,
+ 123, 0, 122, 124, 0, 91, 0, 0, 93, 113,
+ 113, 113, 113, 87, 85, 62, 62, 0, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 3, 69, 68, 75, 0, 101, 0, 0, 102, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 74, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 0, 101, 0, 0, 62, 7, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 23, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+
+ 62, 62, 62, 62, 62, 36, 62, 62, 62, 62,
+ 62, 62, 44, 62, 47, 62, 62, 50, 0, 0,
+ 0, 62, 8, 62, 62, 62, 13, 14, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 26, 62, 62,
+ 62, 62, 62, 62, 62, 62, 32, 62, 34, 62,
+ 62, 62, 62, 62, 62, 41, 62, 43, 45, 48,
+ 62, 0, 0, 111, 6, 62, 10, 62, 62, 62,
+ 16, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 33, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 0, 62,
+
+ 11, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 0, 59, 62, 62, 38, 62, 62, 40,
+ 62, 62, 62, 49, 5, 0, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 22, 62,
+ 62, 62, 62, 62, 29, 62, 58, 30, 62, 62,
+ 62, 62, 62, 42, 62, 62, 0, 62, 62, 62,
+ 62, 62, 17, 53, 62, 62, 62, 62, 62, 24,
+ 25, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 0, 0, 62, 62, 12, 62, 62, 62,
+
+ 62, 62, 21, 62, 62, 62, 62, 62, 62, 62,
+ 37, 62, 62, 62, 62, 62, 62, 62, 62, 18,
+ 62, 62, 62, 27, 56, 62, 62, 62, 35, 39,
+ 60, 46, 61, 9, 51, 62, 62, 0, 54, 62,
+ 62, 62, 0, 56, 62, 62, 62, 15, 52, 62,
+ 62, 62, 62, 62, 62, 62, 62, 20, 62, 62,
+ 62, 62, 62, 28, 57, 62, 62, 62, 62, 62,
+ 62, 62, 19, 55, 62, 62, 62, 62, 62, 31,
+ 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 2, 2, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 6, 7, 8, 6, 9, 6, 10, 6,
+ 6, 11, 6, 12, 13, 14, 15, 16, 17, 17,
+ 17, 17, 17, 17, 17, 18, 18, 19, 20, 21,
+ 22, 23, 24, 6, 25, 25, 25, 25, 25, 25,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 27, 26, 26, 28, 26, 26,
+ 29, 30, 31, 6, 32, 6, 33, 34, 35, 36,
+
+ 37, 38, 39, 40, 41, 26, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 26, 54,
+ 55, 26, 56, 57, 58, 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, 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[60] =
+ { 0,
+ 1, 2, 3, 1, 2, 4, 5, 4, 5, 5,
+ 5, 5, 6, 7, 8, 9, 9, 9, 4, 5,
+ 10, 5, 10, 4, 9, 11, 11, 11, 12, 4,
+ 13, 11, 9, 9, 9, 9, 9, 9, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 5, 5, 5, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[609] =
+ { 0,
+ 0, 1065, 1061, 1060, 57, 58, 59, 60, 79, 94,
+ 53, 62, 117, 126, 135, 144, 100, 145, 154, 163,
+ 68, 69, 65, 70, 98, 155, 101, 164, 221, 1062,
+ 174, 193, 1069, 0, 1074, 1074, 1074, 280, 1074, 1074,
+ 1074, 339, 119, 164, 197, 1074, 114, 1074, 398, 1074,
+ 1074, 1074, 1025, 1074, 1052, 1074, 1074, 1074, 451, 1074,
+ 1074, 1074, 1074, 1074, 1074, 128, 1074, 1074, 1023, 1052,
+ 54, 1043, 1074, 1050, 1074, 1074, 1004, 1074, 331, 63,
+ 190, 1074, 1074, 1074, 153, 1074, 185, 1074, 1074, 346,
+ 1074, 1074, 0, 1074, 0, 0, 192, 1074, 1074, 1018,
+
+ 1074, 1074, 1074, 339, 1017, 0, 0, 1074, 0, 354,
+ 1018, 1012, 169, 311, 1016, 1013, 1010, 329, 1017, 331,
+ 1001, 334, 331, 98, 334, 1007, 1014, 1017, 1074, 505,
+ 0, 1074, 0, 0, 374, 549, 1026, 1074, 1007, 1074,
+ 1074, 1074, 357, 0, 1074, 1074, 1074, 1074, 1074, 1074,
+ 0, 1074, 0, 1034, 365, 1025, 1074, 1074, 1074, 382,
+ 1074, 391, 1074, 1074, 398, 1074, 406, 410, 1015, 1074,
+ 416, 1014, 421, 0, 0, 0, 0, 430, 0, 998,
+ 1006, 393, 992, 993, 990, 991, 362, 988, 995, 990,
+ 341, 999, 984, 988, 407, 994, 979, 980, 393, 979,
+
+ 979, 987, 988, 991, 974, 980, 974, 979, 970, 983,
+ 0, 0, 0, 1074, 972, 420, 0, 0, 0, 439,
+ 434, 445, 174, 451, 442, 457, 410, 468, 474, 485,
+ 489, 435, 1074, 983, 978, 962, 81, 962, 975, 960,
+ 964, 972, 971, 970, 993, 954, 965, 952, 989, 968,
+ 961, 962, 371, 465, 308, 949, 950, 433, 961, 950,
+ 957, 941, 952, 948, 941, 945, 951, 950, 940, 951,
+ 949, 946, 1074, 0, 0, 933, 0, 942, 928, 934,
+ 929, 942, 921, 926, 939, 960, 936, 924, 929, 917,
+ 0, 921, 916, 929, 442, 928, 923, 926, 921, 911,
+
+ 923, 915, 906, 913, 919, 918, 903, 467, 912, 901,
+ 914, 899, 0, 904, 0, 903, 901, 0, 941, 0,
+ 0, 890, 0, 901, 906, 890, 0, 0, 480, 890,
+ 893, 482, 906, 905, 904, 903, 894, 0, 887, 886,
+ 894, 886, 892, 884, 878, 876, 0, 875, 0, 912,
+ 888, 886, 875, 874, 871, 0, 868, 0, 484, 0,
+ 868, 504, 0, 1074, 0, 866, 866, 880, 861, 860,
+ 485, 863, 865, 864, 860, 865, 868, 857, 859, 855,
+ 854, 869, 864, 867, 862, 852, 860, 523, 849, 858,
+ 845, 860, 859, 854, 844, 838, 837, 850, 534, 502,
+
+ 0, 835, 848, 847, 834, 833, 844, 828, 827, 828,
+ 864, 839, 842, 829, 836, 835, 819, 820, 817, 818,
+ 832, 817, 538, 1074, 832, 819, 0, 814, 813, 0,
+ 816, 827, 826, 0, 1074, 851, 810, 809, 809, 805,
+ 804, 803, 802, 812, 798, 797, 810, 813, 0, 801,
+ 794, 805, 804, 798, 0, 797, 0, 0, 795, 789,
+ 802, 786, 785, 0, 800, 799, 825, 782, 781, 780,
+ 794, 793, 0, 0, 785, 778, 777, 774, 787, 0,
+ 0, 780, 779, 768, 767, 776, 783, 768, 764, 762,
+ 743, 739, 773, 541, 729, 727, 0, 714, 712, 703,
+
+ 704, 700, 0, 700, 681, 657, 517, 525, 664, 662,
+ 0, 655, 653, 662, 660, 661, 658, 642, 641, 551,
+ 639, 638, 645, 566, 573, 637, 636, 574, 0, 0,
+ 0, 0, 0, 0, 0, 577, 576, 587, 1074, 548,
+ 549, 566, 594, 1074, 562, 561, 558, 0, 0, 569,
+ 568, 560, 567, 566, 551, 560, 559, 0, 559, 558,
+ 538, 529, 520, 0, 0, 524, 521, 510, 533, 483,
+ 482, 484, 0, 0, 490, 461, 457, 445, 420, 0,
+ 1074, 616, 629, 642, 655, 668, 681, 694, 701, 712,
+ 725, 738, 749, 756, 764, 772, 783, 791, 437, 388,
+
+ 372, 208, 200, 162, 137, 83, 69, 802
+ } ;
+
+static yyconst flex_int16_t yy_def[609] =
+ { 0,
+ 581, 1, 582, 582, 583, 583, 583, 583, 584, 584,
+ 585, 585, 583, 583, 583, 583, 583, 583, 583, 583,
+ 583, 583, 583, 583, 583, 583, 583, 583, 581, 29,
+ 586, 586, 581, 587, 581, 581, 581, 581, 581, 581,
+ 581, 588, 581, 589, 589, 581, 581, 581, 588, 581,
+ 581, 581, 587, 581, 581, 581, 581, 581, 590, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 591,
+ 591, 581, 581, 591, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 592,
+ 581, 581, 593, 581, 593, 594, 581, 581, 581, 593,
+
+ 581, 581, 581, 581, 581, 587, 595, 581, 596, 595,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 581, 588,
+ 49, 581, 597, 598, 589, 598, 581, 581, 581, 581,
+ 581, 581, 581, 599, 581, 581, 581, 581, 581, 581,
+ 600, 581, 601, 591, 591, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 593, 594, 595, 596, 581, 595, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 597, 598, 136, 581, 581, 581, 602, 603, 601, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 592, 581, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 581, 581, 604, 605, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 581, 606,
+ 607, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 581, 600, 581, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 581, 596,
+
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 581, 581, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 581, 581, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 608, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 608, 608, 596, 596, 596, 596, 596, 596,
+
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 581, 581, 596,
+ 596, 596, 581, 581, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 0, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+
+ 581, 581, 581, 581, 581, 581, 581, 581
+ } ;
+
+static yyconst flex_int16_t yy_nxt[1134] =
+ { 0,
+ 34, 35, 36, 34, 35, 34, 37, 34, 38, 39,
+ 40, 41, 34, 42, 43, 44, 45, 45, 34, 46,
+ 47, 48, 40, 34, 49, 49, 49, 49, 50, 34,
+ 34, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 51, 52, 40, 34, 57,
+ 57, 61, 61, 58, 58, 71, 155, 86, 62, 62,
+ 75, 75, 86, 72, 71, 73, 154, 364, 85, 85,
+ 64, 36, 72, 64, 73, 161, 59, 59, 59, 59,
+ 65, 363, 162, 66, 87, 64, 36, 67, 64, 87,
+
+ 88, 69, 75, 91, 89, 65, 76, 68, 66, 78,
+ 92, 74, 67, 279, 79, 60, 60, 60, 60, 75,
+ 74, 280, 68, 76, 137, 77, 78, 90, 75, 132,
+ 90, 79, 76, 133, 77, 78, 138, 75, 132, 203,
+ 79, 76, 133, 80, 78, 321, 75, 75, 204, 79,
+ 76, 76, 80, 78, 78, 81, 75, 88, 79, 79,
+ 76, 89, 80, 78, 81, 75, 91, 166, 79, 76,
+ 320, 80, 78, 92, 81, 102, 36, 79, 102, 135,
+ 135, 135, 167, 81, 90, 103, 168, 169, 104, 168,
+ 82, 136, 83, 90, 102, 36, 161, 102, 163, 82,
+
+ 105, 83, 132, 162, 103, 182, 133, 104, 275, 82,
+ 164, 84, 135, 135, 135, 183, 274, 136, 82, 165,
+ 84, 93, 94, 36, 93, 94, 93, 93, 93, 93,
+ 93, 93, 95, 93, 96, 97, 98, 98, 98, 93,
+ 93, 93, 93, 93, 93, 96, 96, 96, 96, 93,
+ 93, 99, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 93, 93, 93, 93,
+ 107, 107, 107, 107, 107, 107, 107, 107, 108, 107,
+ 107, 107, 107, 109, 107, 107, 107, 107, 107, 107,
+
+ 107, 107, 107, 110, 109, 109, 109, 109, 107, 107,
+ 107, 109, 109, 111, 112, 113, 114, 115, 116, 109,
+ 117, 109, 118, 119, 120, 121, 122, 109, 123, 124,
+ 125, 126, 127, 109, 128, 129, 107, 107, 107, 106,
+ 300, 158, 106, 301, 106, 159, 106, 171, 172, 132,
+ 171, 130, 130, 133, 184, 178, 178, 106, 178, 185,
+ 160, 190, 106, 194, 186, 191, 198, 201, 106, 106,
+ 205, 202, 216, 216, 192, 173, 195, 155, 248, 206,
+ 219, 196, 199, 220, 221, 200, 220, 154, 207, 135,
+ 135, 135, 222, 223, 249, 222, 218, 106, 581, 224,
+
+ 225, 581, 224, 581, 243, 581, 296, 226, 227, 179,
+ 226, 168, 169, 297, 168, 244, 581, 229, 172, 253,
+ 229, 581, 231, 232, 166, 231, 236, 581, 581, 259,
+ 237, 178, 178, 260, 178, 273, 273, 581, 254, 167,
+ 220, 221, 238, 220, 158, 217, 222, 223, 159, 222,
+ 163, 255, 224, 225, 339, 224, 581, 142, 226, 227,
+ 142, 226, 164, 160, 173, 304, 143, 143, 580, 168,
+ 169, 165, 168, 340, 142, 229, 172, 144, 229, 353,
+ 142, 579, 305, 145, 146, 233, 229, 172, 147, 229,
+ 231, 232, 369, 231, 373, 148, 396, 405, 354, 149,
+
+ 298, 150, 151, 152, 153, 106, 578, 299, 106, 577,
+ 106, 370, 106, 374, 437, 397, 406, 130, 130, 399,
+ 399, 399, 576, 106, 423, 423, 423, 423, 106, 526,
+ 575, 574, 573, 438, 106, 106, 435, 527, 436, 423,
+ 423, 423, 423, 435, 424, 572, 571, 494, 527, 399,
+ 399, 399, 538, 538, 538, 538, 527, 570, 569, 424,
+ 550, 551, 568, 106, 213, 213, 213, 543, 543, 543,
+ 543, 567, 539, 213, 543, 543, 543, 543, 566, 551,
+ 551, 213, 213, 213, 213, 213, 213, 544, 538, 538,
+ 538, 538, 565, 564, 544, 543, 543, 543, 543, 563,
+
+ 562, 561, 560, 559, 558, 557, 556, 555, 539, 554,
+ 553, 552, 549, 548, 547, 544, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 101, 101,
+ 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+ 101, 106, 546, 545, 106, 542, 106, 106, 541, 540,
+ 537, 536, 535, 106, 131, 534, 533, 131, 532, 131,
+
+ 131, 531, 131, 530, 131, 529, 131, 134, 528, 134,
+ 525, 134, 141, 141, 141, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 154, 154, 154, 154, 154,
+ 154, 154, 154, 154, 524, 154, 154, 154, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 174,
+ 523, 522, 174, 174, 174, 521, 520, 519, 174, 518,
+ 174, 175, 175, 517, 175, 516, 175, 176, 176, 176,
+ 176, 176, 176, 176, 176, 176, 176, 177, 177, 494,
+ 177, 515, 177, 211, 211, 514, 211, 211, 211, 211,
+ 211, 211, 211, 211, 211, 211, 212, 212, 513, 212,
+
+ 512, 212, 493, 493, 511, 493, 493, 493, 493, 493,
+ 493, 493, 493, 493, 493, 510, 509, 508, 507, 506,
+ 505, 504, 503, 502, 501, 500, 499, 498, 497, 496,
+ 495, 494, 492, 491, 490, 489, 488, 487, 486, 485,
+ 484, 483, 482, 481, 480, 479, 478, 477, 476, 475,
+ 474, 473, 472, 471, 470, 469, 468, 467, 466, 465,
+ 464, 463, 462, 461, 460, 459, 458, 457, 456, 455,
+ 454, 453, 452, 451, 450, 449, 448, 447, 446, 445,
+ 444, 443, 442, 441, 440, 439, 434, 433, 432, 431,
+ 430, 429, 428, 427, 426, 425, 422, 421, 420, 419,
+
+ 418, 417, 416, 415, 414, 413, 412, 411, 410, 409,
+ 408, 407, 404, 403, 402, 401, 400, 398, 395, 394,
+ 393, 392, 391, 390, 389, 388, 387, 386, 385, 384,
+ 383, 382, 381, 380, 379, 378, 377, 376, 375, 372,
+ 371, 368, 367, 366, 365, 362, 361, 360, 359, 358,
+ 357, 356, 355, 352, 351, 350, 349, 348, 347, 346,
+ 345, 344, 343, 342, 341, 338, 337, 336, 335, 334,
+ 333, 332, 331, 330, 329, 328, 327, 326, 325, 324,
+ 323, 322, 319, 318, 317, 316, 315, 314, 313, 312,
+ 311, 310, 309, 308, 307, 306, 303, 302, 295, 294,
+
+ 293, 292, 291, 290, 289, 288, 287, 286, 285, 284,
+ 283, 282, 281, 278, 277, 276, 272, 271, 270, 269,
+ 268, 267, 266, 265, 264, 263, 262, 261, 258, 257,
+ 256, 252, 251, 250, 247, 246, 245, 242, 241, 240,
+ 239, 235, 234, 230, 228, 156, 155, 215, 214, 210,
+ 209, 208, 197, 193, 189, 188, 187, 181, 180, 139,
+ 139, 157, 155, 156, 155, 139, 140, 139, 581, 100,
+ 55, 55, 53, 33, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581
+ } ;
+
+static yyconst flex_int16_t yy_chk[1134] =
+ { 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, 1, 5,
+ 6, 7, 8, 5, 6, 11, 71, 23, 7, 8,
+ 21, 22, 24, 11, 12, 11, 71, 607, 21, 22,
+ 9, 9, 12, 9, 12, 80, 5, 6, 7, 8,
+ 9, 606, 80, 9, 23, 10, 10, 9, 10, 24,
+
+ 25, 10, 17, 27, 25, 10, 17, 9, 10, 17,
+ 27, 11, 10, 237, 17, 5, 6, 7, 8, 13,
+ 12, 237, 10, 13, 47, 13, 13, 25, 14, 43,
+ 27, 13, 14, 43, 14, 14, 47, 15, 66, 124,
+ 14, 15, 66, 15, 15, 605, 16, 18, 124, 15,
+ 16, 18, 16, 16, 18, 15, 19, 26, 16, 18,
+ 19, 26, 19, 19, 16, 20, 28, 85, 19, 20,
+ 604, 20, 20, 28, 19, 31, 31, 20, 31, 44,
+ 44, 44, 85, 20, 26, 31, 87, 87, 31, 87,
+ 15, 44, 15, 28, 32, 32, 223, 32, 81, 16,
+
+ 32, 16, 97, 223, 32, 113, 97, 32, 603, 19,
+ 81, 19, 45, 45, 45, 113, 602, 44, 20, 81,
+ 20, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 42,
+ 255, 79, 42, 255, 42, 79, 42, 90, 90, 104,
+ 90, 42, 42, 104, 114, 110, 110, 42, 110, 114,
+ 79, 118, 42, 120, 114, 118, 122, 123, 42, 42,
+ 125, 123, 143, 143, 118, 90, 120, 155, 191, 125,
+ 601, 120, 122, 160, 160, 122, 160, 155, 125, 135,
+ 135, 135, 162, 162, 191, 162, 600, 42, 49, 165,
+
+ 165, 49, 165, 49, 187, 49, 253, 167, 167, 110,
+ 167, 168, 168, 253, 168, 187, 49, 171, 171, 195,
+ 171, 49, 173, 173, 227, 173, 182, 49, 49, 199,
+ 182, 178, 178, 199, 178, 216, 216, 232, 195, 227,
+ 220, 220, 182, 220, 221, 599, 222, 222, 221, 222,
+ 225, 195, 224, 224, 295, 224, 49, 59, 226, 226,
+ 59, 226, 225, 221, 232, 258, 59, 59, 579, 228,
+ 228, 225, 228, 295, 59, 229, 229, 59, 229, 308,
+ 59, 578, 258, 59, 59, 178, 230, 230, 59, 230,
+ 231, 231, 329, 231, 332, 59, 359, 371, 308, 59,
+
+ 254, 59, 59, 59, 59, 130, 577, 254, 130, 576,
+ 130, 329, 130, 332, 400, 359, 371, 130, 130, 362,
+ 362, 362, 575, 130, 388, 388, 388, 388, 130, 507,
+ 572, 571, 570, 400, 130, 130, 399, 508, 399, 423,
+ 423, 423, 423, 494, 388, 569, 568, 494, 507, 399,
+ 399, 399, 520, 520, 520, 520, 508, 567, 566, 423,
+ 540, 541, 563, 130, 136, 136, 136, 524, 524, 524,
+ 524, 562, 520, 136, 525, 525, 525, 525, 561, 540,
+ 541, 136, 136, 136, 136, 136, 136, 524, 538, 538,
+ 538, 538, 560, 559, 525, 543, 543, 543, 543, 557,
+
+ 556, 555, 554, 553, 552, 551, 550, 547, 538, 546,
+ 545, 542, 537, 536, 528, 543, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 583,
+ 583, 583, 583, 583, 583, 583, 583, 583, 583, 583,
+ 583, 583, 584, 584, 584, 584, 584, 584, 584, 584,
+ 584, 584, 584, 584, 584, 585, 585, 585, 585, 585,
+ 585, 585, 585, 585, 585, 585, 585, 585, 586, 586,
+ 586, 586, 586, 586, 586, 586, 586, 586, 586, 586,
+ 586, 587, 527, 526, 587, 523, 587, 587, 522, 521,
+ 519, 518, 517, 587, 588, 516, 515, 588, 514, 588,
+
+ 588, 513, 588, 512, 588, 510, 588, 589, 509, 589,
+ 506, 589, 590, 590, 590, 590, 590, 590, 590, 590,
+ 590, 590, 590, 590, 590, 591, 591, 591, 591, 591,
+ 591, 591, 591, 591, 505, 591, 591, 591, 592, 592,
+ 592, 592, 592, 592, 592, 592, 592, 592, 592, 593,
+ 504, 502, 593, 593, 593, 501, 500, 499, 593, 498,
+ 593, 594, 594, 496, 594, 495, 594, 595, 595, 595,
+ 595, 595, 595, 595, 595, 595, 595, 596, 596, 493,
+ 596, 492, 596, 597, 597, 491, 597, 597, 597, 597,
+ 597, 597, 597, 597, 597, 597, 598, 598, 490, 598,
+
+ 489, 598, 608, 608, 488, 608, 608, 608, 608, 608,
+ 608, 608, 608, 608, 608, 487, 486, 485, 484, 483,
+ 482, 479, 478, 477, 476, 475, 472, 471, 470, 469,
+ 468, 467, 466, 465, 463, 462, 461, 460, 459, 456,
+ 454, 453, 452, 451, 450, 448, 447, 446, 445, 444,
+ 443, 442, 441, 440, 439, 438, 437, 436, 433, 432,
+ 431, 429, 428, 426, 425, 422, 421, 420, 419, 418,
+ 417, 416, 415, 414, 413, 412, 411, 410, 409, 408,
+ 407, 406, 405, 404, 403, 402, 398, 397, 396, 395,
+ 394, 393, 392, 391, 390, 389, 387, 386, 385, 384,
+
+ 383, 382, 381, 380, 379, 378, 377, 376, 375, 374,
+ 373, 372, 370, 369, 368, 367, 366, 361, 357, 355,
+ 354, 353, 352, 351, 350, 348, 346, 345, 344, 343,
+ 342, 341, 340, 339, 337, 336, 335, 334, 333, 331,
+ 330, 326, 325, 324, 322, 319, 317, 316, 314, 312,
+ 311, 310, 309, 307, 306, 305, 304, 303, 302, 301,
+ 300, 299, 298, 297, 296, 294, 293, 292, 290, 289,
+ 288, 287, 286, 285, 284, 283, 282, 281, 280, 279,
+ 278, 276, 272, 271, 270, 269, 268, 267, 266, 265,
+ 264, 263, 262, 261, 260, 259, 257, 256, 252, 251,
+
+ 250, 249, 248, 247, 246, 245, 244, 243, 242, 241,
+ 240, 239, 238, 236, 235, 234, 215, 210, 209, 208,
+ 207, 206, 205, 204, 203, 202, 201, 200, 198, 197,
+ 196, 194, 193, 192, 190, 189, 188, 186, 185, 184,
+ 183, 181, 180, 172, 169, 156, 154, 139, 137, 128,
+ 127, 126, 121, 119, 117, 116, 115, 112, 111, 105,
+ 100, 77, 74, 72, 70, 69, 55, 53, 33, 30,
+ 4, 3, 2, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581, 581, 581, 581, 581, 581, 581, 581,
+ 581, 581, 581
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int gram__flex_debug;
+int gram__flex_debug = 1;
+
+static yyconst flex_int16_t yy_rule_linenum[130] =
+ { 0,
+ 179, 182, 183, 184, 192, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 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,
+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
+ 267, 269, 273, 274, 275, 277, 284, 288, 295, 300,
+ 303, 306, 309, 317, 324, 325, 326, 332, 339, 346,
+ 366, 376, 391, 396, 415, 428, 444, 459, 476, 477,
+ 488, 499, 500, 512, 520, 530, 549, 561, 575, 576,
+
+ 587, 596, 606, 607, 608, 609, 610, 611, 612, 615,
+ 617, 625, 643, 648, 649, 655, 656, 667, 673, 679,
+ 685, 701, 702, 706, 713, 730, 751, 784, 785
+ } ;
+
+/* 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 *gram_text;
+#line 1 "../../src/scan-gram.l"
+/* Bison Grammar Scanner -*- C -*-
+
+ Copyright (C) 2002-2013 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 "../../src/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
+
+#define FLEX_PREFIX(Id) gram_ ## Id
+#include <src/flex-scanner.h>
+
+#include <src/complain.h>
+#include <src/files.h>
+#include <src/getargs.h>
+#include <src/gram.h>
+#include <quotearg.h>
+#include <src/reader.h>
+#include <src/uniqstr.h>
+
+#include <c-ctype.h>
+#include <mbswidth.h>
+#include <quote.h>
+
+#include <src/scan-gram.h>
+
+#define YY_DECL GRAM_LEX_DECL
+
+#define YY_USER_INIT \
+ code_start = scanner_cursor = loc->start; \
+
+/* Location of scanner cursor. */
+static boundary scanner_cursor;
+
+#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))
+
+#define RETURN_PERCENT_PARAM(Value) \
+ RETURN_VALUE(PERCENT_PARAM, param, param_ ## Value)
+
+#define RETURN_PERCENT_FLAG(Value) \
+ RETURN_VALUE(PERCENT_FLAG, uniqstr, uniqstr_new (Value))
+
+#define RETURN_VALUE(Token, Field, Value) \
+ do { \
+ val->Field = Value; \
+ return Token; \
+ } while (0)
+
+#define ROLLBACK_CURRENT_TOKEN \
+ do { \
+ scanner_cursor.column -= mbsnwidth (gram_text, gram_leng, 0); \
+ yyless (0); \
+ } while (0)
+
+#define DEPRECATED(Msg) \
+ do { \
+ size_t i; \
+ deprecated_directive (loc, gram_text, Msg); \
+ scanner_cursor.column -= mbsnwidth (Msg, strlen (Msg), 0); \
+ for (i = strlen (Msg); i != 0; --i) \
+ unput (Msg[i - 1]); \
+ } while (0)
+
+/* 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
+gram_scanner_last_string_free (void)
+{
+ STRING_FREE;
+}
+
+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 :'. */
+
+/* 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, as this simplifies our implementation. We match
+angle brackets in nested pairs: several languages use them for
+generics/template types. */
+
+/* Four 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 %%).
+- predicate (code between '%?{' and '{' in middle section); */
+
+/* C and C++ comments in code. */
+
+/* Strings and characters in code. */
+
+/* Bracketed identifiers support. */
+
+/* Zero or more instances of backslash-newline. Following GCC, allow
+ white space between the backslash and the newline. */
+/* An equal sign, with optional leading whitespaces. This is used in some
+ deprecated constructs. */
+#line 1153 "src/scan-gram.c"
+
+#define INITIAL 0
+#define SC_YACC_COMMENT 1
+#define SC_ESCAPED_STRING 2
+#define SC_ESCAPED_CHARACTER 3
+#define SC_AFTER_IDENTIFIER 4
+#define SC_TAG 5
+#define SC_PROLOGUE 6
+#define SC_BRACED_CODE 7
+#define SC_EPILOGUE 8
+#define SC_PREDICATE 9
+#define SC_COMMENT 10
+#define SC_LINE_COMMENT 11
+#define SC_STRING 12
+#define SC_CHARACTER 13
+#define SC_BRACKETED_ID 14
+#define SC_RETURN_BRACKETED_ID 15
+
+#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 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 */
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int gram_wrap (void );
+#else
+extern int gram_wrap (void );
+#endif
+#endif
+
+/* %not-for-header */
+
+ static void yyunput (int c,char *buf_ptr );
+
+/* %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( gram_text, gram_leng, 1, gram_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( gram_in )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( gram_in ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, gram_in))==0 && ferror(gram_in)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(gram_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 gram_lex (void);
+
+#define YY_DECL int gram_lex (void)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after gram_text and gram_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 \
+ if ( gram_leng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (gram_text[gram_leng - 1] == '\n'); \
+ 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 149 "../../src/scan-gram.l"
+
+
+ /* Nesting level. Either for nested braces, or nested angle brackets
+ (but not mixed). */
+ int nesting PACIFY_CC (= 0);
+
+ /* Parent context state, when applicable. */
+ int context_state PACIFY_CC (= 0);
+
+ /* Location of most recent identifier, when applicable. */
+ 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
+ start condition. */
+ boundary code_start = scanner_cursor;
+
+ /* Where containing comment or string or character literal started,
+ when applicable. */
+ boundary token_start PACIFY_CC (= scanner_cursor);
+
+
+
+ /*-----------------------.
+ | Scanning white space. |
+ `-----------------------*/
+
+#line 1441 "src/scan-gram.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 ( ! gram_in )
+/* %if-c-only */
+ gram_in = stdin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! gram_out )
+/* %if-c-only */
+ gram_out = stdout;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ gram_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ gram__create_buffer(gram_in,YY_BUF_SIZE );
+ }
+
+ gram__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 gram_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_current_state += YY_AT_BOL();
+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 >= 582 )
+ 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 != 581 );
+ 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 gram_lineno update goes here */
+
+do_action: /* This label is used only to access EOF actions. */
+
+/* %% [12.0] debug code goes here */
+ if ( gram__flex_debug )
+ {
+ if ( yy_act == 0 )
+ fprintf( stderr, "--scanner backing up\n" );
+ else if ( yy_act < 130 )
+ fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+ (long)yy_rule_linenum[yy_act], gram_text );
+ else if ( yy_act == 130 )
+ fprintf( stderr, "--accepting default rule (\"%s\")\n",
+ gram_text );
+ else if ( yy_act == 131 )
+ 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;
+
+/* Comments and white space. */
+case 1:
+YY_RULE_SETUP
+#line 179 "../../src/scan-gram.l"
+{
+ complain (loc, Wother, _("stray ',' treated as white space"));
+ }
+ YY_BREAK
+case 2:
+/* rule 2 can match eol */
+#line 183 "../../src/scan-gram.l"
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 183 "../../src/scan-gram.l"
+continue;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 184 "../../src/scan-gram.l"
+{
+ token_start = loc->start;
+ context_state = YY_START;
+ BEGIN SC_YACC_COMMENT;
+ }
+ YY_BREAK
+/* #line directives are not documented, and may be withdrawn or
+ modified in future versions of Bison. */
+case 5:
+/* rule 5 can match eol */
+YY_RULE_SETUP
+#line 192 "../../src/scan-gram.l"
+{
+ handle_syncline (gram_text + sizeof "#line " - 1, *loc);
+ }
+ YY_BREAK
+
+/*----------------------------.
+ | 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 210 "../../src/scan-gram.l"
+return PERCENT_NONASSOC;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 211 "../../src/scan-gram.l"
+return PERCENT_CODE;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 212 "../../src/scan-gram.l"
+RETURN_PERCENT_FLAG("parse.trace");
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 213 "../../src/scan-gram.l"
+return PERCENT_DEFAULT_PREC;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 214 "../../src/scan-gram.l"
+return PERCENT_DEFINE;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 215 "../../src/scan-gram.l"
+return PERCENT_DEFINES;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 216 "../../src/scan-gram.l"
+return PERCENT_DESTRUCTOR;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 217 "../../src/scan-gram.l"
+return PERCENT_DPREC;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 218 "../../src/scan-gram.l"
+return PERCENT_EMPTY;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 219 "../../src/scan-gram.l"
+return PERCENT_ERROR_VERBOSE;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 220 "../../src/scan-gram.l"
+return PERCENT_EXPECT;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 221 "../../src/scan-gram.l"
+return PERCENT_EXPECT_RR;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 222 "../../src/scan-gram.l"
+return PERCENT_FILE_PREFIX;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 223 "../../src/scan-gram.l"
+return PERCENT_YACC;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 224 "../../src/scan-gram.l"
+return PERCENT_INITIAL_ACTION;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 225 "../../src/scan-gram.l"
+return PERCENT_GLR_PARSER;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 226 "../../src/scan-gram.l"
+return PERCENT_LANGUAGE;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 227 "../../src/scan-gram.l"
+return PERCENT_LEFT;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 228 "../../src/scan-gram.l"
+RETURN_PERCENT_PARAM(lex);
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 229 "../../src/scan-gram.l"
+RETURN_PERCENT_FLAG("locations");
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 230 "../../src/scan-gram.l"
+return PERCENT_MERGE;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 231 "../../src/scan-gram.l"
+return PERCENT_NAME_PREFIX;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 232 "../../src/scan-gram.l"
+return PERCENT_NO_DEFAULT_PREC;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 233 "../../src/scan-gram.l"
+return PERCENT_NO_LINES;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 234 "../../src/scan-gram.l"
+return PERCENT_NONASSOC;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 235 "../../src/scan-gram.l"
+return PERCENT_NONDETERMINISTIC_PARSER;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 236 "../../src/scan-gram.l"
+return PERCENT_NTERM;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 237 "../../src/scan-gram.l"
+return PERCENT_OUTPUT;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 238 "../../src/scan-gram.l"
+RETURN_PERCENT_PARAM(both);
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 239 "../../src/scan-gram.l"
+RETURN_PERCENT_PARAM(parse);
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 240 "../../src/scan-gram.l"
+return PERCENT_PREC;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 241 "../../src/scan-gram.l"
+return PERCENT_PRECEDENCE;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 242 "../../src/scan-gram.l"
+return PERCENT_PRINTER;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 243 "../../src/scan-gram.l"
+RETURN_PERCENT_FLAG("api.pure");
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 244 "../../src/scan-gram.l"
+return PERCENT_REQUIRE;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 245 "../../src/scan-gram.l"
+return PERCENT_RIGHT;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 246 "../../src/scan-gram.l"
+return PERCENT_SKELETON;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 247 "../../src/scan-gram.l"
+return PERCENT_START;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 248 "../../src/scan-gram.l"
+return PERCENT_TOKEN;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 249 "../../src/scan-gram.l"
+return PERCENT_TOKEN;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 250 "../../src/scan-gram.l"
+return PERCENT_TOKEN_TABLE;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 251 "../../src/scan-gram.l"
+return PERCENT_TYPE;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 252 "../../src/scan-gram.l"
+return PERCENT_UNION;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 253 "../../src/scan-gram.l"
+return PERCENT_VERBOSE;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 254 "../../src/scan-gram.l"
+return PERCENT_YACC;
+ YY_BREAK
+/* deprecated */
+case 51:
+YY_RULE_SETUP
+#line 257 "../../src/scan-gram.l"
+DEPRECATED("%default-prec");
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 258 "../../src/scan-gram.l"
+DEPRECATED("%define parse.error verbose");
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 259 "../../src/scan-gram.l"
+DEPRECATED("%expect-rr");
+ YY_BREAK
+case 54:
+/* rule 54 can match eol */
+YY_RULE_SETUP
+#line 260 "../../src/scan-gram.l"
+DEPRECATED("%file-prefix");
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 261 "../../src/scan-gram.l"
+DEPRECATED("%fixed-output-files");
+ YY_BREAK
+case 56:
+/* rule 56 can match eol */
+YY_RULE_SETUP
+#line 262 "../../src/scan-gram.l"
+DEPRECATED("%name-prefix");
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 263 "../../src/scan-gram.l"
+DEPRECATED("%no-default-prec");
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 264 "../../src/scan-gram.l"
+DEPRECATED("%no-lines");
+ YY_BREAK
+case 59:
+/* rule 59 can match eol */
+YY_RULE_SETUP
+#line 265 "../../src/scan-gram.l"
+DEPRECATED("%output");
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 266 "../../src/scan-gram.l"
+DEPRECATED("%pure-parser");
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 267 "../../src/scan-gram.l"
+DEPRECATED("%token-table");
+ YY_BREAK
+case 62:
+/* rule 62 can match eol */
+YY_RULE_SETUP
+#line 269 "../../src/scan-gram.l"
+{
+ complain (loc, complaint, _("invalid directive: %s"), quote (gram_text));
+ }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 273 "../../src/scan-gram.l"
+return EQUAL;
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 274 "../../src/scan-gram.l"
+return PIPE;
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 275 "../../src/scan-gram.l"
+return SEMICOLON;
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 277 "../../src/scan-gram.l"
+{
+ val->uniqstr = uniqstr_new (gram_text);
+ id_loc = *loc;
+ bracketed_id_str = NULL;
+ BEGIN SC_AFTER_IDENTIFIER;
+ }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 284 "../../src/scan-gram.l"
+{
+ val->integer = scan_integer (gram_text, 10, *loc);
+ return INT;
+ }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 288 "../../src/scan-gram.l"
+{
+ val->integer = scan_integer (gram_text, 16, *loc);
+ return INT;
+ }
+ YY_BREAK
+/* Identifiers may not start with a digit. Yet, don't silently
+ accept "1FOO" as "1 FOO". */
+case 69:
+YY_RULE_SETUP
+#line 295 "../../src/scan-gram.l"
+{
+ complain (loc, complaint, _("invalid identifier: %s"), quote (gram_text));
+ }
+ YY_BREAK
+/* Characters. */
+case 70:
+YY_RULE_SETUP
+#line 300 "../../src/scan-gram.l"
+token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
+ YY_BREAK
+/* Strings. */
+case 71:
+YY_RULE_SETUP
+#line 303 "../../src/scan-gram.l"
+token_start = loc->start; BEGIN SC_ESCAPED_STRING;
+ YY_BREAK
+/* Prologue. */
+case 72:
+YY_RULE_SETUP
+#line 306 "../../src/scan-gram.l"
+code_start = loc->start; BEGIN SC_PROLOGUE;
+ YY_BREAK
+/* Code in between braces. */
+case 73:
+YY_RULE_SETUP
+#line 309 "../../src/scan-gram.l"
+{
+ STRING_GROW;
+ nesting = 0;
+ code_start = loc->start;
+ BEGIN SC_BRACED_CODE;
+ }
+ YY_BREAK
+/* Semantic predicate. */
+case 74:
+/* rule 74 can match eol */
+YY_RULE_SETUP
+#line 317 "../../src/scan-gram.l"
+{
+ nesting = 0;
+ code_start = loc->start;
+ BEGIN SC_PREDICATE;
+ }
+ YY_BREAK
+/* A type. */
+case 75:
+YY_RULE_SETUP
+#line 324 "../../src/scan-gram.l"
+return TAG_ANY;
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 325 "../../src/scan-gram.l"
+return TAG_NONE;
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 326 "../../src/scan-gram.l"
+{
+ nesting = 0;
+ token_start = loc->start;
+ BEGIN SC_TAG;
+ }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 332 "../../src/scan-gram.l"
+{
+ static int percent_percent_count;
+ if (++percent_percent_count == 2)
+ BEGIN SC_EPILOGUE;
+ return PERCENT_PERCENT;
+ }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 339 "../../src/scan-gram.l"
+{
+ bracketed_id_str = NULL;
+ bracketed_id_start = loc->start;
+ bracketed_id_context_state = YY_START;
+ BEGIN SC_BRACKETED_ID;
+ }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 346 "../../src/scan-gram.l"
+{
+ complain (loc, complaint, "%s: %s",
+ ngettext ("invalid character", "invalid characters", gram_leng),
+ quote_mem (gram_text, gram_leng));
+ }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 352 "../../src/scan-gram.l"
+{
+ loc->start = loc->end = scanner_cursor;
+ yyterminate ();
+ }
+ YY_BREAK
+
+/*--------------------------------------------------------------.
+ | Supporting \0 complexifies our implementation for no expected |
+ | added value. |
+ `--------------------------------------------------------------*/
+
+
+case 81:
+YY_RULE_SETUP
+#line 366 "../../src/scan-gram.l"
+complain (loc, complaint, _("invalid null character"));
+ YY_BREAK
+
+/*-----------------------------------------------------------------.
+ | Scanning after an identifier, checking whether a colon is next. |
+ `-----------------------------------------------------------------*/
+
+
+case 82:
+YY_RULE_SETUP
+#line 376 "../../src/scan-gram.l"
+{
+ 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 83:
+YY_RULE_SETUP
+#line 391 "../../src/scan-gram.l"
+{
+ BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
+ *loc = id_loc;
+ return ID_COLON;
+ }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 396 "../../src/scan-gram.l"
+{
+ ROLLBACK_CURRENT_TOKEN;
+ BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
+ *loc = id_loc;
+ return ID;
+ }
+ YY_BREAK
+case YY_STATE_EOF(SC_AFTER_IDENTIFIER):
+#line 402 "../../src/scan-gram.l"
+{
+ BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
+ *loc = id_loc;
+ return ID;
+ }
+ YY_BREAK
+
+/*--------------------------------.
+ | Scanning bracketed identifiers. |
+ `--------------------------------*/
+
+
+case 85:
+YY_RULE_SETUP
+#line 415 "../../src/scan-gram.l"
+{
+ if (bracketed_id_str)
+ {
+ complain (loc, complaint,
+ _("unexpected identifier in bracketed name: %s"),
+ quote (gram_text));
+ }
+ else
+ {
+ bracketed_id_str = uniqstr_new (gram_text);
+ bracketed_id_loc = *loc;
+ }
+ }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 428 "../../src/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 (loc, complaint, _("an identifier expected"));
+ }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 444 "../../src/scan-gram.l"
+{
+ complain (loc, complaint, "%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 451 "../../src/scan-gram.l"
+{
+ BEGIN bracketed_id_context_state;
+ unexpected_eof (bracketed_id_start, "]");
+ }
+ YY_BREAK
+
+
+
+case 88:
+YY_RULE_SETUP
+#line 459 "../../src/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. |
+ `---------------------------------------------------------------*/
+
+
+case 89:
+YY_RULE_SETUP
+#line 476 "../../src/scan-gram.l"
+BEGIN context_state;
+ YY_BREAK
+case 90:
+/* rule 90 can match eol */
+YY_RULE_SETUP
+#line 477 "../../src/scan-gram.l"
+continue;
+ YY_BREAK
+case YY_STATE_EOF(SC_YACC_COMMENT):
+#line 478 "../../src/scan-gram.l"
+unexpected_eof (token_start, "*/"); BEGIN context_state;
+ YY_BREAK
+
+/*------------------------------------------------------------.
+ | Scanning a C comment. The initial '/ *' is already eaten. |
+ `------------------------------------------------------------*/
+
+
+case 91:
+/* rule 91 can match eol */
+YY_RULE_SETUP
+#line 488 "../../src/scan-gram.l"
+STRING_GROW; BEGIN context_state;
+ YY_BREAK
+case YY_STATE_EOF(SC_COMMENT):
+#line 489 "../../src/scan-gram.l"
+unexpected_eof (token_start, "*/"); BEGIN context_state;
+ YY_BREAK
+
+/*--------------------------------------------------------------.
+ | Scanning a line comment. The initial '//' is already eaten. |
+ `--------------------------------------------------------------*/
+
+
+case 92:
+/* rule 92 can match eol */
+YY_RULE_SETUP
+#line 499 "../../src/scan-gram.l"
+STRING_GROW; BEGIN context_state;
+ YY_BREAK
+case 93:
+/* rule 93 can match eol */
+YY_RULE_SETUP
+#line 500 "../../src/scan-gram.l"
+STRING_GROW;
+ YY_BREAK
+case YY_STATE_EOF(SC_LINE_COMMENT):
+#line 501 "../../src/scan-gram.l"
+BEGIN context_state;
+ YY_BREAK
+
+/*------------------------------------------------.
+ | Scanning a Bison string, including its escapes. |
+ | The initial quote is already eaten. |
+ `------------------------------------------------*/
+
+
+case 94:
+YY_RULE_SETUP
+#line 512 "../../src/scan-gram.l"
+{
+ STRING_FINISH;
+ loc->start = token_start;
+ val->code = last_string;
+ BEGIN INITIAL;
+ return STRING;
+ }
+ YY_BREAK
+case YY_STATE_EOF(SC_ESCAPED_STRING):
+#line 519 "../../src/scan-gram.l"
+unexpected_eof (token_start, "\"");
+ YY_BREAK
+case 95:
+/* rule 95 can match eol */
+YY_RULE_SETUP
+#line 520 "../../src/scan-gram.l"
+unexpected_newline (token_start, "\"");
+ YY_BREAK
+
+/*----------------------------------------------------------.
+ | Scanning a Bison character literal, decoding its escapes. |
+ | The initial quote is already eaten. |
+ `----------------------------------------------------------*/
+
+
+case 96:
+YY_RULE_SETUP
+#line 530 "../../src/scan-gram.l"
+{
+ STRING_FINISH;
+ loc->start = token_start;
+ val->character = last_string[0];
+
+ /* FIXME: Eventually, make these errors. */
+ if (last_string[0] == '\0')
+ {
+ complain (loc, Wother, _("empty character literal"));
+ /* '\0' seems dangerous even if we are about to complain. */
+ val->character = '\'';
+ }
+ else if (last_string[1] != '\0')
+ complain (loc, Wother,
+ _("extra characters in character literal"));
+ STRING_FREE;
+ BEGIN INITIAL;
+ return CHAR;
+ }
+ YY_BREAK
+case 97:
+/* rule 97 can match eol */
+YY_RULE_SETUP
+#line 549 "../../src/scan-gram.l"
+unexpected_newline (token_start, "'");
+ YY_BREAK
+case YY_STATE_EOF(SC_ESCAPED_CHARACTER):
+#line 550 "../../src/scan-gram.l"
+unexpected_eof (token_start, "'");
+ YY_BREAK
+
+/*--------------------------------------------------------------.
+ | Scanning a tag. The initial angle bracket is already eaten. |
+ `--------------------------------------------------------------*/
+
+
+case 98:
+YY_RULE_SETUP
+#line 561 "../../src/scan-gram.l"
+{
+ --nesting;
+ if (nesting < 0)
+ {
+ STRING_FINISH;
+ loc->start = token_start;
+ val->uniqstr = uniqstr_new (last_string);
+ STRING_FREE;
+ BEGIN INITIAL;
+ return TAG;
+ }
+ STRING_GROW;
+ }
+ YY_BREAK
+case 99:
+/* rule 99 can match eol */
+YY_RULE_SETUP
+#line 575 "../../src/scan-gram.l"
+STRING_GROW;
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 576 "../../src/scan-gram.l"
+STRING_GROW; nesting += gram_leng;
+ YY_BREAK
+case YY_STATE_EOF(SC_TAG):
+#line 578 "../../src/scan-gram.l"
+unexpected_eof (token_start, ">");
+ YY_BREAK
+
+/*----------------------------.
+ | Decode escaped characters. |
+ `----------------------------*/
+
+
+case 101:
+YY_RULE_SETUP
+#line 587 "../../src/scan-gram.l"
+{
+ unsigned long int c = strtoul (gram_text + 1, NULL, 8);
+ if (!c || UCHAR_MAX < c)
+ complain (loc, complaint, _("invalid number after \\-escape: %s"),
+ gram_text+1);
+ else
+ obstack_1grow (&obstack_for_string, c);
+ }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 596 "../../src/scan-gram.l"
+{
+ verify (UCHAR_MAX < ULONG_MAX);
+ unsigned long int c = strtoul (gram_text + 2, NULL, 16);
+ if (!c || UCHAR_MAX < c)
+ complain (loc, complaint, _("invalid number after \\-escape: %s"),
+ gram_text+1);
+ else
+ obstack_1grow (&obstack_for_string, c);
+ }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 606 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\a');
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 607 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\b');
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 608 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\f');
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 609 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\n');
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 610 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\r');
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 611 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\t');
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 612 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, '\v');
+ YY_BREAK
+/* \\[\"\'?\\] would be shorter, but it confuses xgettext. */
+case 110:
+YY_RULE_SETUP
+#line 615 "../../src/scan-gram.l"
+obstack_1grow (&obstack_for_string, gram_text[1]);
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 617 "../../src/scan-gram.l"
+{
+ int c = convert_ucn_to_byte (gram_text);
+ if (c <= 0)
+ complain (loc, complaint, _("invalid number after \\-escape: %s"),
+ gram_text+1);
+ else
+ obstack_1grow (&obstack_for_string, c);
+ }
+ YY_BREAK
+case 112:
+/* rule 112 can match eol */
+YY_RULE_SETUP
+#line 625 "../../src/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 (loc, complaint, _("invalid character after \\-escape: %s"),
+ p);
+ }
+ YY_BREAK
+
+/*--------------------------------------------.
+ | Scanning user-code characters and strings. |
+ `--------------------------------------------*/
+
+
+case 113:
+/* rule 113 can match eol */
+YY_RULE_SETUP
+#line 643 "../../src/scan-gram.l"
+STRING_GROW;
+ YY_BREAK
+
+
+
+case 114:
+YY_RULE_SETUP
+#line 648 "../../src/scan-gram.l"
+STRING_GROW; BEGIN context_state;
+ YY_BREAK
+case 115:
+/* rule 115 can match eol */
+YY_RULE_SETUP
+#line 649 "../../src/scan-gram.l"
+unexpected_newline (token_start, "'");
+ YY_BREAK
+case YY_STATE_EOF(SC_CHARACTER):
+#line 650 "../../src/scan-gram.l"
+unexpected_eof (token_start, "'");
+ YY_BREAK
+
+
+
+case 116:
+YY_RULE_SETUP
+#line 655 "../../src/scan-gram.l"
+STRING_GROW; BEGIN context_state;
+ YY_BREAK
+case 117:
+/* rule 117 can match eol */
+YY_RULE_SETUP
+#line 656 "../../src/scan-gram.l"
+unexpected_newline (token_start, "\"");
+ YY_BREAK
+case YY_STATE_EOF(SC_STRING):
+#line 657 "../../src/scan-gram.l"
+unexpected_eof (token_start, "\"");
+ YY_BREAK
+
+/*---------------------------------------------------.
+ | Strings, comments etc. can be found in user code. |
+ `---------------------------------------------------*/
+
+
+case 118:
+YY_RULE_SETUP
+#line 667 "../../src/scan-gram.l"
+{
+ STRING_GROW;
+ context_state = YY_START;
+ token_start = loc->start;
+ BEGIN SC_CHARACTER;
+ }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 673 "../../src/scan-gram.l"
+{
+ STRING_GROW;
+ context_state = YY_START;
+ token_start = loc->start;
+ BEGIN SC_STRING;
+ }
+ YY_BREAK
+case 120:
+/* rule 120 can match eol */
+YY_RULE_SETUP
+#line 679 "../../src/scan-gram.l"
+{
+ STRING_GROW;
+ context_state = YY_START;
+ token_start = loc->start;
+ BEGIN SC_COMMENT;
+ }
+ YY_BREAK
+case 121:
+/* rule 121 can match eol */
+YY_RULE_SETUP
+#line 685 "../../src/scan-gram.l"
+{
+ STRING_GROW;
+ context_state = YY_START;
+ BEGIN SC_LINE_COMMENT;
+ }
+ YY_BREAK
+
+/*-----------------------------------------------------------.
+ | Scanning some code in braces (actions, predicates). The |
+ | initial "{" is already eaten. |
+ `-----------------------------------------------------------*/
+
+
+case 122:
+/* rule 122 can match eol */
+YY_RULE_SETUP
+#line 701 "../../src/scan-gram.l"
+STRING_GROW; nesting++;
+ YY_BREAK
+case 123:
+/* rule 123 can match eol */
+YY_RULE_SETUP
+#line 702 "../../src/scan-gram.l"
+STRING_GROW; nesting--;
+ YY_BREAK
+/* Tokenize '<<%' correctly (as '<<' '%') rather than incorrrectly
+ (as '<' '<%'). */
+case 124:
+/* rule 124 can match eol */
+YY_RULE_SETUP
+#line 706 "../../src/scan-gram.l"
+STRING_GROW;
+ YY_BREAK
+case YY_STATE_EOF(SC_BRACED_CODE):
+case YY_STATE_EOF(SC_PREDICATE):
+#line 708 "../../src/scan-gram.l"
+unexpected_eof (code_start, "}");
+ YY_BREAK
+
+
+
+case 125:
+YY_RULE_SETUP
+#line 713 "../../src/scan-gram.l"
+{
+ obstack_1grow (&obstack_for_string, '}');
+
+ --nesting;
+ if (nesting < 0)
+ {
+ STRING_FINISH;
+ loc->start = code_start;
+ val->code = last_string;
+ BEGIN INITIAL;
+ return BRACED_CODE;
+ }
+ }
+ YY_BREAK
+
+
+
+case 126:
+YY_RULE_SETUP
+#line 730 "../../src/scan-gram.l"
+{
+ --nesting;
+ if (nesting < 0)
+ {
+ STRING_FINISH;
+ loc->start = code_start;
+ val->code = last_string;
+ BEGIN INITIAL;
+ return BRACED_PREDICATE;
+ }
+ else
+ obstack_1grow (&obstack_for_string, '}');
+ }
+ YY_BREAK
+
+/*--------------------------------------------------------------.
+ | Scanning some prologue: from "%{" (already scanned) to "%}". |
+ `--------------------------------------------------------------*/
+
+
+case 127:
+YY_RULE_SETUP
+#line 751 "../../src/scan-gram.l"
+{
+ STRING_FINISH;
+ loc->start = code_start;
+ val->code = last_string;
+ BEGIN INITIAL;
+ return PROLOGUE;
+ }
+ YY_BREAK
+case YY_STATE_EOF(SC_PROLOGUE):
+#line 759 "../../src/scan-gram.l"
+unexpected_eof (code_start, "%}");
+ YY_BREAK
+
+/*---------------------------------------------------------------.
+ | Scanning the epilogue (everything after the second "%%", which |
+ | has already been eaten). |
+ `---------------------------------------------------------------*/
+
+
+case YY_STATE_EOF(SC_EPILOGUE):
+#line 770 "../../src/scan-gram.l"
+{
+ STRING_FINISH;
+ loc->start = code_start;
+ val->code = last_string;
+ BEGIN INITIAL;
+ return EPILOGUE;
+ }
+ YY_BREAK
+
+/*-----------------------------------------------------.
+ | By default, grow the string obstack with the input. |
+ `-----------------------------------------------------*/
+case 128:
+#line 785 "../../src/scan-gram.l"
+case 129:
+/* rule 129 can match eol */
+YY_RULE_SETUP
+#line 785 "../../src/scan-gram.l"
+STRING_GROW;
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 787 "../../src/scan-gram.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 2661 "src/scan-gram.c"
+case YY_STATE_EOF(SC_RETURN_BRACKETED_ID):
+ yyterminate();
+
+ 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 gram_in at a new source and called
+ * gram_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 = gram_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 ( gram_wrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * gram_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 gram_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. */
+ gram_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;
+ gram_restart(gram_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 *) 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;
+
+ (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);
+ yy_current_state += YY_AT_BOL();
+
+ 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)] : 59);
+ 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 >= 582 )
+ 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 = 59;
+ 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 >= 582 )
+ 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 == 581);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+/* %if-c-only */
+
+ static void yyunput (int c, register char * yy_bp )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up gram_text */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register yy_size_t number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+/* %% [18.0] update gram_lineno here */
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+/* %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. */
+ gram_restart(gram_in );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( gram_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 gram_text */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+/* %% [19.0] update BOL and gram_lineno */
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ 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 gram_restart (FILE * input_file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ gram_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ gram__create_buffer(gram_in,YY_BUF_SIZE );
+ }
+
+ gram__init_buffer(YY_CURRENT_BUFFER,input_file );
+ gram__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+/* %if-c-only */
+ void gram__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
+ * gram_pop_buffer_state();
+ * gram_push_buffer_state(new_buffer);
+ */
+ gram_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;
+ gram__load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (gram_wrap()) processing, but the only time this flag
+ * is looked at is after gram_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 gram__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;
+ gram_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 gram__create_buffer (FILE * file, int size )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) gram_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in gram__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 *) gram_alloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in gram__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ gram__init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with gram__create_buffer()
+ *
+ */
+/* %if-c-only */
+ void gram__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 )
+ gram_free((void *) b->yy_ch_buf );
+
+ gram_free((void *) b );
+}
+
+/* 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.
+ */
+/* %if-c-only */
+ static void gram__init_buffer (YY_BUFFER_STATE b, FILE * file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+{
+ int oerrno = errno;
+
+ gram__flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then gram__init_buffer was _probably_
+ * called from gram_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 gram__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 )
+ gram__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 gram_push_buffer_state (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (new_buffer == NULL)
+ return;
+
+ gram_ensure_buffer_stack();
+
+ /* This block is copied from gram__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 gram__switch_to_buffer. */
+ gram__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 gram_pop_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ gram__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ gram__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 gram_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**)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;
+ (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**)gram_realloc
+ ((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*));
+ (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 gram__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) gram_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in gram__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;
+
+ gram__switch_to_buffer(b );
+
+ return b;
+}
+/* %endif */
+
+/* %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 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 * yystr )
+{
+
+ 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 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 * 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 *) gram_alloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in gram__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 = gram__scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in gram__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 gram_text. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ gram_text[gram_leng] = (yy_hold_char); \
+ (yy_c_buf_p) = gram_text + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ gram_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 gram_get_lineno (void)
+{
+
+ return gram_lineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *gram_get_in (void)
+{
+ return gram_in;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *gram_get_out (void)
+{
+ return gram_out;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t gram_get_leng (void)
+{
+ return gram_leng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *gram_get_text (void)
+{
+ return gram_text;
+}
+
+/* %if-reentrant */
+/* %endif */
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void gram_set_lineno (int line_number )
+{
+
+ gram_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see gram__switch_to_buffer
+ */
+void gram_set_in (FILE * in_str )
+{
+ gram_in = in_str ;
+}
+
+void gram_set_out (FILE * out_str )
+{
+ gram_out = out_str ;
+}
+
+int gram_get_debug (void)
+{
+ return gram__flex_debug;
+}
+
+void gram_set_debug (int bdebug )
+{
+ gram__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 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 */
+/* gram_lex_destroy is for both reentrant and non-reentrant scanners. */
+int gram_lex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ gram__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ gram_pop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ 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;
+}
+/* %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 *gram_alloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *gram_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 gram_free (void * ptr )
+{
+ free( (char *) ptr ); /* see gram_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 787 "../../src/scan-gram.l"
+
+
+
+/* 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. */
+
+static size_t
+no_cr_read (FILE *fp, char *buf, size_t size)
+{
+ size_t bytes_read = fread (buf, 1, size, fp);
+ if (bytes_read)
+ {
+ char *w = memchr (buf, '\r', bytes_read);
+ if (w)
+ {
+ char const *r = ++w;
+ char const *lim = buf + bytes_read;
+
+ for (;;)
+ {
+ /* Found an '\r'. Treat it like '\n', but ignore any
+ '\n' that immediately follows. */
+ w[-1] = '\n';
+ if (r == lim)
+ {
+ int ch = getc (fp);
+ if (ch != '\n' && ungetc (ch, fp) != ch)
+ break;
+ }
+ else if (*r == '\n')
+ r++;
+
+ /* Copy until the next '\r'. */
+ do
+ {
+ if (r == lim)
+ return w - buf;
+ }
+ while ((*w++ = *r++) != '\r');
+ }
+
+ return w - buf;
+ }
+ }
+
+ return bytes_read;
+}
+
+
+
+/*------------------------------------------------------.
+| Scan NUMBER for a base-BASE integer at location LOC. |
+`------------------------------------------------------*/
+
+static unsigned long int
+scan_integer (char const *number, int base, location loc)
+{
+ verify (INT_MAX < ULONG_MAX);
+ unsigned long int num = strtoul (number, NULL, base);
+
+ if (INT_MAX < num)
+ {
+ complain (&loc, complaint, _("integer out of range: %s"),
+ quote (number));
+ num = INT_MAX;
+ }
+
+ return num;
+}
+
+
+/*------------------------------------------------------------------.
+| Convert universal character name UCN to a single-byte character, |
+| and return that character. Return -1 if UCN does not correspond |
+| to a single-byte character. |
+`------------------------------------------------------------------*/
+
+static int
+convert_ucn_to_byte (char const *ucn)
+{
+ verify (UCHAR_MAX <= INT_MAX);
+ unsigned long int code = strtoul (ucn + 2, NULL, 16);
+
+ /* FIXME: Currently we assume Unicode-compatible unibyte characters
+ on ASCII hosts (i.e., Latin-1 on hosts with 8-bit bytes). On
+ non-ASCII hosts we support only the portable C character set.
+ These limitations should be removed once we add support for
+ multibyte characters. */
+
+ if (UCHAR_MAX < code)
+ return -1;
+
+#if ! ('$' == 0x24 && '@' == 0x40 && '`' == 0x60 && '~' == 0x7e)
+ {
+ /* A non-ASCII host. Use CODE to index into a table of the C
+ basic execution character set, which is guaranteed to exist on
+ all Standard C platforms. This table also includes '$', '@',
+ and '`', which are not in the basic execution character set but
+ which are unibyte characters on all the platforms that we know
+ about. */
+ static signed char const table[] =
+ {
+ '\0', -1, -1, -1, -1, -1, -1, '\a',
+ '\b', '\t', '\n', '\v', '\f', '\r', -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ ' ', '!', '"', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', '{', '|', '}', '~'
+ };
+
+ code = code < sizeof table ? table[code] : -1;
+ }
+#endif
+
+ return code;
+}
+
+
+/*---------------------------------------------------------------------.
+| Handle '#line INT( "FILE")?\n'. ARGS has already skipped '#line '. |
+`---------------------------------------------------------------------*/
+
+static void
+handle_syncline (char *args, location loc)
+{
+ char *file;
+ unsigned long int lineno = strtoul (args, &file, 10);
+ if (INT_MAX <= lineno)
+ {
+ complain (&loc, Wother, _("line number overflow"));
+ lineno = INT_MAX;
+ }
+
+ file = strchr (file, '"');
+ if (file)
+ {
+ *strchr (file + 1, '"') = '\0';
+ current_file = uniqstr_new (file + 1);
+ }
+ boundary_set (&scanner_cursor, current_file, lineno, 1);
+}
+
+
+/*----------------------------------------------------------------.
+| For a token or comment starting at START, report message MSGID, |
+| which should say that an end marker was found before the |
+| expected TOKEN_END. Then, pretend that TOKEN_END was found. |
+`----------------------------------------------------------------*/
+
+static void
+unexpected_end (boundary start, char const *msgid, char const *token_end)
+{
+ location loc;
+ size_t i;
+ loc.start = start;
+ loc.end = scanner_cursor;
+ i = strlen (token_end);
+
+/* Adjust scanner cursor so that any later message does not count
+ the characters about to be inserted. */
+ scanner_cursor.column -= i;
+
+ while (i != 0)
+ unput (token_end[--i]);
+
+ token_end = quote (token_end);
+ /* Instead of '\'', display "'". */
+ if (STREQ (token_end, "'\\''"))
+ token_end = "\"'\"";
+ complain (&loc, complaint, _(msgid), token_end);
+}
+
+
+/*------------------------------------------------------------------------.
+| Report an unexpected EOF in a token or comment starting at START. |
+| An end of file was encountered and the expected TOKEN_END was missing. |
+| After reporting the problem, pretend that TOKEN_END was found. |
+`------------------------------------------------------------------------*/
+
+static void
+unexpected_eof (boundary start, char const *token_end)
+{
+ unexpected_end (start, N_("missing %s at end of file"), token_end);
+}
+
+
+/*----------------------------------------.
+| Likewise, but for unexpected newlines. |
+`----------------------------------------*/
+
+static void
+unexpected_newline (boundary start, char const *token_end)
+{
+ unexpected_end (start, N_("missing %s at end of line"), token_end);
+}
+
+
+/*-------------------------.
+| Initialize the scanner. |
+`-------------------------*/
+
+void
+gram_scanner_initialize (void)
+{
+ obstack_init (&obstack_for_string);
+}
+
+
+/*-----------------------------------------------.
+| Free all the memory allocated to the scanner. |
+`-----------------------------------------------*/
+
+void
+gram_scanner_free (void)
+{
+ obstack_free (&obstack_for_string, 0);
+ /* Reclaim Flex's buffers. */
+ gram_lex_destroy ();
+}
+
diff --git a/contrib/tools/bison/src/scan-gram.h b/contrib/tools/bison/src/scan-gram.h
new file mode 100644
index 0000000000..ee397ed2e7
--- /dev/null
+++ b/contrib/tools/bison/src/scan-gram.h
@@ -0,0 +1,38 @@
+/* Bison Grammar Scanner
+
+ Copyright (C) 2006-2007, 2009-2013 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/contrib/tools/bison/src/scan-skel-c.c b/contrib/tools/bison/src/scan-skel-c.c
new file mode 100644
index 0000000000..3e1e73deb0
--- /dev/null
+++ b/contrib/tools/bison/src/scan-skel-c.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#include "system.h"
+#include "src/scan-skel.c"
diff --git a/contrib/tools/bison/src/scan-skel.c b/contrib/tools/bison/src/scan-skel.c
new file mode 100644
index 0000000000..1e116da14d
--- /dev/null
+++ b/contrib/tools/bison/src/scan-skel.c
@@ -0,0 +1,2435 @@
+#line 2 "lex.yy.c"
+
+#line 4 "lex.yy.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 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 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* %if-c++-only */
+#define BISON_FALLTHROUGH [[fallthrough]]
+/* %endif */
+
+/* %if-c-only */
+#define BISON_FALLTHROUGH
+/* %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 skel_restart(skel_in )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#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
+
+/* %if-not-reentrant */
+extern int skel_leng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+extern FILE *skel_in, *skel_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 skel_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 skel_text again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#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.
+ */
+ int 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 skel_restart()), so that the user can continue scanning by
+ * just pointing skel_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 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;
+
+/* 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 skel_wrap()'s to do buffer switches
+ * instead of setting up a fresh skel_in. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+/* %ok-for-header */
+
+/* %endif */
+
+void skel_restart (FILE *input_file );
+void skel__switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE skel__create_buffer (FILE *file,int size );
+void skel__delete_buffer (YY_BUFFER_STATE b );
+void skel__flush_buffer (YY_BUFFER_STATE b );
+void skel_push_buffer_state (YY_BUFFER_STATE new_buffer );
+void skel_pop_buffer_state (void );
+
+static void skel_ensure_buffer_stack (void );
+static void skel__load_buffer_state (void );
+static void skel__init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER skel__flush_buffer(YY_CURRENT_BUFFER )
+
+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 );
+
+/* %endif */
+
+void *skel_alloc (yy_size_t );
+void *skel_realloc (void *,yy_size_t );
+void skel_free (void * );
+
+#define yy_new_buffer skel__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ skel_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ skel__create_buffer(skel_in,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ skel_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ skel__create_buffer(skel_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] 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 YY_SKIP_YYWRAP
+
+#define FLEX_DEBUG
+
+typedef unsigned char YY_CHAR;
+
+FILE *skel_in = (FILE *) 0, *skel_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int skel_lineno;
+
+int skel_lineno = 1;
+
+extern char *skel_text;
+#define yytext_ptr skel_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 skel_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle skel_text and skel_leng for yymore() goes here \ */\
+ skel_leng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to skel_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 25
+#define YY_END_OF_BUFFER 26
+/* 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[72] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 26, 14, 13, 1,
+ 12, 15, 22, 24, 23, 23, 14, 1, 12, 6,
+ 12, 5, 2, 12, 12, 12, 3, 4, 15, 22,
+ 20, 22, 19, 21, 16, 17, 18, 12, 12, 12,
+ 12, 12, 0, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 8, 7, 12, 12, 12, 11, 12, 12, 9, 10,
+ 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 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, 5, 6,
+ 7, 1, 1, 7, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 8, 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, 9, 10, 11, 1,
+
+ 12, 13, 1, 1, 14, 1, 1, 15, 16, 17,
+ 18, 19, 1, 1, 20, 21, 22, 1, 1, 1,
+ 1, 1, 23, 1, 24, 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[25] =
+ { 0,
+ 1, 1, 2, 1, 1, 3, 1, 4, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[79] =
+ { 0,
+ 0, 2, 68, 67, 9, 12, 74, 0, 109, 69,
+ 14, 0, 36, 109, 109, 109, 0, 68, 58, 109,
+ 17, 109, 109, 62, 52, 13, 109, 109, 0, 109,
+ 109, 26, 109, 109, 109, 109, 109, 49, 52, 53,
+ 51, 43, 30, 50, 39, 42, 39, 36, 37, 38,
+ 40, 39, 28, 40, 39, 39, 38, 24, 26, 22,
+ 109, 109, 25, 15, 6, 109, 3, 1, 109, 109,
+ 109, 82, 86, 90, 94, 97, 101, 104
+ } ;
+
+static yyconst flex_int16_t yy_def[79] =
+ { 0,
+ 72, 72, 73, 73, 74, 74, 71, 75, 71, 75,
+ 76, 77, 78, 71, 71, 71, 75, 75, 76, 71,
+ 19, 71, 71, 19, 19, 19, 71, 71, 77, 71,
+ 71, 71, 71, 71, 71, 71, 71, 19, 19, 19,
+ 19, 19, 71, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 71, 71, 19, 19, 19, 71, 19, 19, 71, 71,
+ 0, 71, 71, 71, 71, 71, 71, 71
+ } ;
+
+static yyconst flex_int16_t yy_nxt[134] =
+ { 0,
+ 71, 71, 9, 10, 9, 10, 70, 11, 69, 11,
+ 15, 16, 15, 15, 16, 15, 20, 21, 22, 20,
+ 21, 23, 68, 24, 25, 40, 67, 41, 31, 43,
+ 66, 26, 31, 43, 42, 65, 27, 28, 31, 32,
+ 33, 64, 34, 35, 63, 62, 61, 60, 59, 58,
+ 57, 56, 55, 54, 53, 52, 51, 50, 36, 37,
+ 71, 49, 71, 48, 47, 71, 46, 45, 44, 39,
+ 38, 18, 18, 71, 13, 13, 71, 71, 71, 71,
+ 71, 71, 8, 8, 8, 8, 12, 12, 12, 12,
+ 14, 14, 14, 14, 17, 71, 17, 19, 19, 71,
+
+ 19, 29, 29, 29, 30, 30, 30, 30, 7, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71
+ } ;
+
+static yyconst flex_int16_t yy_chk[134] =
+ { 0,
+ 0, 0, 1, 1, 2, 2, 68, 1, 67, 2,
+ 5, 5, 5, 6, 6, 6, 11, 11, 11, 21,
+ 21, 11, 65, 11, 11, 26, 64, 26, 32, 32,
+ 63, 11, 43, 43, 26, 60, 11, 11, 13, 13,
+ 13, 59, 13, 13, 58, 57, 56, 55, 54, 53,
+ 52, 51, 50, 49, 48, 47, 46, 45, 13, 13,
+ 19, 44, 19, 42, 41, 19, 40, 39, 38, 25,
+ 24, 18, 10, 7, 4, 3, 0, 0, 0, 0,
+ 19, 19, 72, 72, 72, 72, 73, 73, 73, 73,
+ 74, 74, 74, 74, 75, 0, 75, 76, 76, 0,
+
+ 76, 77, 77, 77, 78, 78, 78, 78, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int skel__flex_debug;
+int skel__flex_debug = 1;
+
+static yyconst flex_int16_t yy_rule_linenum[25] =
+ { 0,
+ 72, 73, 74, 75, 76, 77, 79, 80, 82, 83,
+ 84, 87, 88, 89, 102, 104, 105, 106, 107, 108,
+ 110, 129, 134, 135
+ } ;
+
+/* 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 *skel_text;
+#line 1 "scan-skel.l"
+/* Scan Bison Skeletons. -*- C -*-
+
+ Copyright (C) 2001-2013 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-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
+
+#define FLEX_PREFIX(Id) skel_ ## Id
+#include <src/flex-scanner.h>
+
+#include <dirname.h>
+#include <error.h>
+#include <quotearg.h>
+
+#include <src/complain.h>
+#include <src/getargs.h>
+#include <src/files.h>
+#include <src/scan-skel.h>
+
+#define YY_DECL static int skel_lex (void)
+YY_DECL;
+
+typedef void (*at_directive)(int, char**, char **, int*);
+static void at_init (int *argc, char *argv[], at_directive *at_ptr, at_directive fun);
+static void at_basename (int argc, char *argv[], char**, int*);
+static void at_complain (int argc, char *argv[], char**, int*);
+static void at_output (int argc, char *argv[], char **name, int *lineno);
+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 671 "lex.yy.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
+ * 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 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 );
+
+int 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 */
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int skel_wrap (void );
+#else
+extern int skel_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
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#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( skel_text, skel_leng, 1, skel_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( skel_in )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( skel_in ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, skel_in))==0 && ferror(skel_in)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(skel_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 skel_lex (void);
+
+#define YY_DECL int skel_lex (void)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after skel_text and skel_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 57 "scan-skel.l"
+
+
+
+ int out_lineno PACIFY_CC (= 0);
+ char *out_name = NULL;
+
+ /* Currently, only the @complain directive takes multiple arguments, and
+ never more than 7, with argv[0] being the directive name and argv[1]
+ being the type of complaint to dispatch. */
+#define ARGC_MAX 9
+ int argc = 0;
+ char *argv[ARGC_MAX];
+ at_directive at_ptr = NULL;
+
+
+#line 934 "lex.yy.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 ( ! skel_in )
+/* %if-c-only */
+ skel_in = stdin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! skel_out )
+/* %if-c-only */
+ skel_out = stdout;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ skel_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ skel__create_buffer(skel_in,YY_BUF_SIZE );
+ }
+
+ skel__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 skel_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 >= 72 )
+ 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 != 71 );
+ 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 skel_lineno update goes here */
+
+do_action: /* This label is used only to access EOF actions. */
+
+/* %% [12.0] debug code goes here */
+ if ( skel__flex_debug )
+ {
+ if ( yy_act == 0 )
+ fprintf( stderr, "--scanner backing up\n" );
+ else if ( yy_act < 25 )
+ fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+ (long)yy_rule_linenum[yy_act], skel_text );
+ else if ( yy_act == 25 )
+ fprintf( stderr, "--accepting default rule (\"%s\")\n",
+ skel_text );
+ else if ( yy_act == 26 )
+ 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:
+YY_RULE_SETUP
+#line 72 "scan-skel.l"
+continue;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 73 "scan-skel.l"
+fputc ('@', skel_out);
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 74 "scan-skel.l"
+fputc ('[', skel_out);
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 75 "scan-skel.l"
+fputc (']', skel_out);
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 76 "scan-skel.l"
+continue; /* Used by b4_cat in ../data/bison.m4. */
+ YY_BREAK
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+#line 77 "scan-skel.l"
+continue;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 79 "scan-skel.l"
+fprintf (skel_out, "%d", out_lineno + 1);
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 80 "scan-skel.l"
+fputs (quotearg_style (c_quoting_style, out_name), skel_out);
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 82 "scan-skel.l"
+at_init (&argc, argv, &at_ptr, &at_basename);
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 83 "scan-skel.l"
+at_init (&argc, argv, &at_ptr, &at_complain);
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 84 "scan-skel.l"
+at_init (&argc, argv, &at_ptr, &at_output);
+ YY_BREAK
+/* This pattern must not match more than the previous @ patterns. */
+case 12:
+YY_RULE_SETUP
+#line 87 "scan-skel.l"
+fail_for_invalid_at (skel_text);
+ YY_BREAK
+case 13:
+/* rule 13 can match eol */
+YY_RULE_SETUP
+#line 88 "scan-skel.l"
+out_lineno++; ECHO;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 89 "scan-skel.l"
+ECHO;
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 91 "scan-skel.l"
+{
+ if (out_name)
+ {
+ free (out_name);
+ xfclose (skel_out);
+ }
+ return EOF;
+}
+ YY_BREAK
+
+
+case 15:
+/* rule 15 can match eol */
+YY_RULE_SETUP
+#line 102 "scan-skel.l"
+STRING_GROW;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 104 "scan-skel.l"
+obstack_1grow (&obstack_for_string, '@');
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 105 "scan-skel.l"
+obstack_1grow (&obstack_for_string, '[');
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 106 "scan-skel.l"
+obstack_1grow (&obstack_for_string, ']');
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 107 "scan-skel.l"
+continue; /* For starting an argument that begins with whitespace. */
+ YY_BREAK
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 108 "scan-skel.l"
+continue;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 110 "scan-skel.l"
+{
+ if (argc >= ARGC_MAX)
+ fail_for_at_directive_too_many_args (argv[0]);
+
+ argv[argc++] = obstack_finish0 (&obstack_for_string);
+
+ /* Like M4, skip whitespace after a comma. */
+ if (skel_text[1] == ',')
+ BEGIN SC_AT_DIRECTIVE_SKIP_WS;
+ else
+ {
+ aver (at_ptr);
+ at_ptr (argc, argv, &out_name, &out_lineno);
+ obstack_free (&obstack_for_string, argv[0]);
+ argc = 0;
+ BEGIN INITIAL;
+ }
+ }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 129 "scan-skel.l"
+fail_for_invalid_at (skel_text);
+ YY_BREAK
+
+
+
+case 23:
+/* rule 23 can match eol */
+YY_RULE_SETUP
+#line 134 "scan-skel.l"
+continue;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 135 "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 140 "scan-skel.l"
+complain (NULL, fatal, _("unclosed %s directive in skeleton"), argv[0]);
+ YY_BREAK
+
+case 25:
+YY_RULE_SETUP
+#line 143 "scan-skel.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 1217 "lex.yy.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 skel_in at a new source and called
+ * skel_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 = skel_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 ( skel_wrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * skel_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 skel_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
+ {
+ int 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;
+
+ 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;
+
+ 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. */
+ skel_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), (size_t) 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;
+ skel_restart(skel_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 *) 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;
+
+ (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)] : 1);
+ 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 >= 72 )
+ 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 = 1;
+ 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 >= 72 )
+ 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 == 71);
+
+ 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 */
+ int 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. */
+ skel_restart(skel_in );
+
+ BISON_FALLTHROUGH;
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( skel_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 skel_text */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+/* %% [19.0] update BOL and skel_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 skel_restart (FILE * input_file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ skel_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ skel__create_buffer(skel_in,YY_BUF_SIZE );
+ }
+
+ skel__init_buffer(YY_CURRENT_BUFFER,input_file );
+ skel__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+/* %if-c-only */
+ void skel__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
+ * skel_pop_buffer_state();
+ * skel_push_buffer_state(new_buffer);
+ */
+ skel_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;
+ skel__load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (skel_wrap()) processing, but the only time this flag
+ * is looked at is after skel_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 skel__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;
+ skel_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 skel__create_buffer (FILE * file, int size )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) skel_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in skel__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 *) skel_alloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in skel__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ skel__init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with skel__create_buffer()
+ *
+ */
+/* %if-c-only */
+ void skel__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 )
+ skel_free((void *) b->yy_ch_buf );
+
+ 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.
+ */
+/* %if-c-only */
+ static void skel__init_buffer (YY_BUFFER_STATE b, FILE * file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+{
+ int oerrno = errno;
+
+ skel__flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then skel__init_buffer was _probably_
+ * called from skel_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 skel__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 )
+ skel__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 skel_push_buffer_state (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (new_buffer == NULL)
+ return;
+
+ skel_ensure_buffer_stack();
+
+ /* This block is copied from skel__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 skel__switch_to_buffer. */
+ skel__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 skel_pop_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ skel__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ skel__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 skel_ensure_buffer_stack (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int 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**)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;
+ (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**)skel_realloc
+ ((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*));
+ (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 skel__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) skel_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in skel__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;
+
+ skel__switch_to_buffer(b );
+
+ return b;
+}
+/* %endif */
+
+/* %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 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 * yystr )
+{
+
+ 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 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 * yybytes, int _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 *) skel_alloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in skel__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 = skel__scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in skel__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 skel_text. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ skel_text[skel_leng] = (yy_hold_char); \
+ (yy_c_buf_p) = skel_text + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ skel_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 skel_get_lineno (void)
+{
+
+ return skel_lineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *skel_get_in (void)
+{
+ return skel_in;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *skel_get_out (void)
+{
+ return skel_out;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int skel_get_leng (void)
+{
+ return skel_leng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *skel_get_text (void)
+{
+ return skel_text;
+}
+
+/* %if-reentrant */
+/* %endif */
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void skel_set_lineno (int line_number )
+{
+
+ skel_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see skel__switch_to_buffer
+ */
+void skel_set_in (FILE * in_str )
+{
+ skel_in = in_str ;
+}
+
+void skel_set_out (FILE * out_str )
+{
+ skel_out = out_str ;
+}
+
+int skel_get_debug (void)
+{
+ return skel__flex_debug;
+}
+
+void skel_set_debug (int bdebug )
+{
+ skel__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 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 */
+/* skel_lex_destroy is for both reentrant and non-reentrant scanners. */
+int skel_lex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ skel__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ skel_pop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ 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;
+}
+/* %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 *skel_alloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *skel_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 skel_free (void * ptr )
+{
+ free( (char *) ptr ); /* see skel_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 143 "scan-skel.l"
+
+
+
+static void
+at_init (int *argc, char *argv[], at_directive *at_ptr, at_directive fun)
+{
+ *at_ptr = fun;
+ skel_text[skel_leng-1] = '\0';
+ obstack_grow (&obstack_for_string, skel_text, skel_leng);
+ argv[(*argc)++] = obstack_finish (&obstack_for_string);
+ BEGIN SC_AT_DIRECTIVE_ARGS;
+}
+
+/*------------------------.
+| Scan a Bison skeleton. |
+`------------------------*/
+
+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_lex_destroy ();
+}
+
+static inline warnings
+flag (const char *arg)
+{
+ /* compare with values issued from b4_error */
+ if (STREQ (arg, "complain"))
+ return complaint;
+ else if (STREQ (arg, "deprecated"))
+ return Wdeprecated;
+ else if (STREQ (arg, "fatal"))
+ return fatal;
+ else if (STREQ (arg, "note"))
+ return silent | complaint | no_caret;
+ else if (STREQ (arg, "warn"))
+ return Wother;
+ else
+ aver (false);
+}
+
+static void
+at_basename (int argc, char *argv[], char **out_namep, int *out_linenop)
+{
+ (void) out_namep;
+ (void) out_linenop;
+ if (2 < argc)
+ fail_for_at_directive_too_many_args (argv[0]);
+ fputs (last_component (argv[1]), skel_out);
+}
+
+static void
+at_complain (int argc, char *argv[], char **out_namep, int *out_linenop)
+{
+ static unsigned indent;
+ warnings w = flag (argv[1]);
+ location loc;
+ location *locp = NULL;
+
+ (void) out_namep;
+ (void) out_linenop;
+
+ if (argc < 4)
+ fail_for_at_directive_too_few_args (argv[0]);
+ if (argv[2] && argv[2][0])
+ {
+ boundary_set_from_string (&loc.start, argv[2]);
+ boundary_set_from_string (&loc.end, argv[3]);
+ locp = &loc;
+ }
+ if (w & silent)
+ indent += SUB_INDENT;
+ else
+ indent = 0;
+ complain_args (locp, w, &indent, argc - 4, argv + 4);
+ if (w & silent)
+ indent -= SUB_INDENT;
+}
+
+static void
+at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
+{
+ if (2 < argc)
+ fail_for_at_directive_too_many_args (argv[0]);
+ if (*out_namep)
+ {
+ free (*out_namep);
+ xfclose (skel_out);
+ }
+ *out_namep = xstrdup (argv[1]);
+ output_file_name_check (out_namep);
+ skel_out = xfopen (*out_namep, "wb");
+ *out_linenop = 1;
+}
+
+static void
+fail_for_at_directive_too_few_args (char const *at_directive_name)
+{
+ complain (NULL, 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)
+{
+ complain (NULL, fatal, _("too many arguments for %s directive in skeleton"),
+ at_directive_name);
+}
+
+static void
+fail_for_invalid_at (char const *at)
+{
+ complain (NULL, fatal, "invalid @ in skeleton: %s", at);
+}
+
diff --git a/contrib/tools/bison/src/scan-skel.h b/contrib/tools/bison/src/scan-skel.h
new file mode 100644
index 0000000000..019d38af5a
--- /dev/null
+++ b/contrib/tools/bison/src/scan-skel.h
@@ -0,0 +1,27 @@
+/* Scan Bison Skeletons.
+
+ Copyright (C) 2005-2007, 2009-2013 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/>. */
+
+void scan_skel (FILE *);
+
+/* Pacify "make syntax-check". */
+extern FILE *skel_in;
+extern FILE *skel_out;
+extern int skel__flex_debug;
+extern int skel_lineno;
+void skel_scanner_free (void);
diff --git a/contrib/tools/bison/src/state.c b/contrib/tools/bison/src/state.c
new file mode 100644
index 0000000000..c11b10f7dd
--- /dev/null
+++ b/contrib/tools/bison/src/state.c
@@ -0,0 +1,466 @@
+/* Type definitions for the finite state machine for Bison.
+
+ Copyright (C) 2001-2007, 2009-2013 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 "gram.h"
+#include "state.h"
+#include "print-xml.h"
+
+
+ /*-------------------.
+ | Shifts and Gotos. |
+ `-------------------*/
+
+
+/*-----------------------------------------.
+| Create a new array of NUM shifts/gotos. |
+`-----------------------------------------*/
+
+static transitions *
+transitions_new (int num, state **the_states)
+{
+ size_t states_size = num * sizeof *the_states;
+ transitions *res = xmalloc (offsetof (transitions, states) + states_size);
+ res->num = num;
+ memcpy (res->states, the_states, states_size);
+ return res;
+}
+
+
+/*-------------------------------------------------------.
+| Return the state such that SHIFTS contain a shift/goto |
+| to it on SYM. Abort if none found. |
+`-------------------------------------------------------*/
+
+state *
+transitions_to (transitions *shifts, symbol_number sym)
+{
+ int j;
+ for (j = 0; ; j++)
+ {
+ aver (j < shifts->num);
+ if (TRANSITION_SYMBOL (shifts, j) == sym)
+ return shifts->states[j];
+ }
+}
+
+
+ /*--------------------.
+ | Error transitions. |
+ `--------------------*/
+
+
+/*---------------------------------.
+| Create a new array of NUM errs. |
+`---------------------------------*/
+
+errs *
+errs_new (int num, symbol **tokens)
+{
+ size_t symbols_size = num * sizeof *tokens;
+ errs *res = xmalloc (offsetof (errs, symbols) + symbols_size);
+ res->num = num;
+ memcpy (res->symbols, tokens, symbols_size);
+ return res;
+}
+
+
+
+
+ /*-------------.
+ | Reductions. |
+ `-------------*/
+
+
+/*---------------------------------------.
+| Create a new array of NUM reductions. |
+`---------------------------------------*/
+
+static reductions *
+reductions_new (int num, rule **reds)
+{
+ size_t rules_size = num * sizeof *reds;
+ reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
+ res->num = num;
+ res->lookahead_tokens = NULL;
+ memcpy (res->rules, reds, rules_size);
+ return res;
+}
+
+
+
+ /*---------.
+ | States. |
+ `---------*/
+
+
+state_number nstates = 0;
+/* FINAL_STATE is properly set by new_state when it recognizes its
+ accessing symbol: $end. */
+state *final_state = NULL;
+
+
+/*------------------------------------------------------------------.
+| Create a new state with ACCESSING_SYMBOL, for those items. Store |
+| it in the state hash table. |
+`------------------------------------------------------------------*/
+
+state *
+state_new (symbol_number accessing_symbol,
+ size_t nitems, item_number *core)
+{
+ state *res;
+ size_t items_size = nitems * sizeof *core;
+
+ aver (nstates < STATE_NUMBER_MAXIMUM);
+
+ res = xmalloc (offsetof (state, items) + items_size);
+ res->number = nstates++;
+ res->accessing_symbol = accessing_symbol;
+ 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);
+
+ state_hash_insert (res);
+
+ 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. |
+`---------*/
+
+static void
+state_free (state *s)
+{
+ free (s->transitions);
+ free (s->reductions);
+ free (s->errs);
+ free (s);
+}
+
+
+/*---------------------------.
+| Set the transitions of S. |
+`---------------------------*/
+
+void
+state_transitions_set (state *s, int num, state **trans)
+{
+ aver (!s->transitions);
+ s->transitions = transitions_new (num, trans);
+}
+
+
+/*--------------------------.
+| Set the reductions of S. |
+`--------------------------*/
+
+void
+state_reductions_set (state *s, int num, rule **reds)
+{
+ aver (!s->reductions);
+ s->reductions = reductions_new (num, reds);
+}
+
+
+int
+state_reduction_find (state *s, rule *r)
+{
+ int i;
+ reductions *reds = s->reductions;
+ for (i = 0; i < reds->num; ++i)
+ if (reds->rules[i] == r)
+ return i;
+ return -1;
+}
+
+
+/*--------------------.
+| Set the errs of S. |
+`--------------------*/
+
+void
+state_errs_set (state *s, int num, symbol **tokens)
+{
+ aver (!s->errs);
+ s->errs = errs_new (num, tokens);
+}
+
+
+
+/*--------------------------------------------------.
+| Print on OUT all the lookahead tokens such that S |
+| wants to reduce R. |
+`--------------------------------------------------*/
+
+void
+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->lookahead_tokens && red != -1)
+ {
+ bitset_iterator biter;
+ int k;
+ char const *sep = "";
+ fprintf (out, " [");
+ BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
+ {
+ fprintf (out, "%s%s", sep, symbols[k]->tag);
+ sep = ", ";
+ }
+ fprintf (out, "]");
+ }
+}
+
+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. |
+`---------------------*/
+
+/* Initial capacity of states hash table. */
+#define HT_INITIAL_CAPACITY 257
+
+static struct hash_table *state_table = NULL;
+
+/* Two states are equal if they have the same core items. */
+static inline bool
+state_compare (state const *s1, state const *s2)
+{
+ size_t i;
+
+ if (s1->nitems != s2->nitems)
+ return false;
+
+ for (i = 0; i < s1->nitems; ++i)
+ if (s1->items[i] != s2->items[i])
+ return false;
+
+ return true;
+}
+
+static bool
+state_comparator (void const *s1, void const *s2)
+{
+ return state_compare (s1, s2);
+}
+
+static inline size_t
+state_hash (state const *s, size_t tablesize)
+{
+ /* Add up the state's item numbers to get a hash key. */
+ size_t key = 0;
+ size_t i;
+ for (i = 0; i < s->nitems; ++i)
+ key += s->items[i];
+ return key % tablesize;
+}
+
+static size_t
+state_hasher (void const *s, size_t tablesize)
+{
+ return state_hash (s, tablesize);
+}
+
+
+/*-------------------------------.
+| Create the states hash table. |
+`-------------------------------*/
+
+void
+state_hash_new (void)
+{
+ state_table = hash_initialize (HT_INITIAL_CAPACITY,
+ NULL,
+ state_hasher,
+ state_comparator,
+ NULL);
+}
+
+
+/*---------------------------------------------.
+| Free the states hash table, not the states. |
+`---------------------------------------------*/
+
+void
+state_hash_free (void)
+{
+ hash_free (state_table);
+}
+
+
+/*-----------------------------------.
+| Insert S in the state hash table. |
+`-----------------------------------*/
+
+void
+state_hash_insert (state *s)
+{
+ if (!hash_insert (state_table, s))
+ xalloc_die ();
+}
+
+
+/*------------------------------------------------------------------.
+| Find the state associated to the CORE, and return it. If it does |
+| not exist yet, return NULL. |
+`------------------------------------------------------------------*/
+
+state *
+state_hash_lookup (size_t nitems, item_number *core)
+{
+ size_t items_size = nitems * sizeof *core;
+ state *probe = xmalloc (offsetof (state, items) + items_size);
+ state *entry;
+
+ probe->nitems = nitems;
+ memcpy (probe->items, core, items_size);
+ entry = hash_lookup (state_table, probe);
+ free (probe);
+ 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;
+
+
+/*----------------------.
+| Free all the states. |
+`----------------------*/
+
+void
+states_free (void)
+{
+ state_number i;
+ for (i = 0; i < nstates; ++i)
+ state_free (states[i]);
+ free (states);
+}
diff --git a/contrib/tools/bison/src/state.h b/contrib/tools/bison/src/state.h
new file mode 100644
index 0000000000..37cd9bf9ec
--- /dev/null
+++ b/contrib/tools/bison/src/state.h
@@ -0,0 +1,274 @@
+/* Type definitions for the finite state machine for Bison.
+
+ Copyright (C) 1984, 1989, 2000-2004, 2007, 2009-2013 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/>. */
+
+
+/* These type definitions are used to represent a nondeterministic
+ finite state machine that parses the specified grammar. This
+ information is generated by the function generate_states in the
+ file LR0.
+
+ Each state of the machine is described by a set of items --
+ particular positions in particular rules -- that are the possible
+ places where parsing could continue when the machine is in this
+ state. These symbols at these items are the allowable inputs that
+ can follow now.
+
+ A core represents one state. States are numbered in the NUMBER
+ field. When generate_states is finished, the starting state is
+ state 0 and NSTATES is the number of states. (FIXME: This sentence
+ is no longer true: A transition to a state whose state number is
+ NSTATES indicates termination.) All the cores are chained together
+ and FIRST_STATE points to the first one (state 0).
+
+ For each state there is a particular symbol which must have been
+ the last thing accepted to reach that state. It is the
+ ACCESSING_SYMBOL of the core.
+
+ Each core contains a vector of NITEMS items which are the indices
+ in the RITEM vector of the items that are selected in this state.
+
+ 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
+ lookahead token alone). When the states are generated, these
+ actions are represented in two other lists.
+
+ Each transition structure describes the possible transitions out
+ of one state, the state whose number is in the number field. Each
+ contains a vector of numbers of the states that transitions can go
+ to. The accessing_symbol fields of those states' cores say what
+ kind of input leads to them.
+
+ A transition to state zero should be ignored: conflict resolution
+ 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. 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).
+ For each state, the tokens that are errors for this reason are
+ recorded in an errs structure, which holds the token numbers.
+
+ There is at least one goto transition present in state zero. It
+ leads to a next-to-final state whose accessing_symbol is the
+ grammar's start symbol. The next-to-final state has one shift to
+ the final state, whose accessing_symbol is zero (end of input).
+ The final state has one shift, which goes to the termination state.
+ The reason for the extra state at the end is to placate the
+ parser's strategy of making all decisions one token ahead of its
+ actions. */
+
+#ifndef STATE_H_
+# define STATE_H_
+
+# include <bitset.h>
+
+# include "gram.h"
+# include "symtab.h"
+
+
+/*-------------------.
+| Numbering states. |
+`-------------------*/
+
+typedef int state_number;
+# define STATE_NUMBER_MAXIMUM INT_MAX
+
+/* Be ready to map a state_number to an int. */
+static inline int
+state_number_as_int (state_number s)
+{
+ return s;
+}
+
+
+typedef struct state state;
+
+/*--------------.
+| Transitions. |
+`--------------*/
+
+typedef struct
+{
+ int num;
+ state *states[1];
+} transitions;
+
+
+/* What is the symbol labelling the transition to
+ TRANSITIONS->states[Num]? Can be a token (amongst which the error
+ token), or non terminals in case of gotos. */
+
+# define TRANSITION_SYMBOL(Transitions, Num) \
+ (Transitions->states[Num]->accessing_symbol)
+
+/* Is the TRANSITIONS->states[Num] a shift? (as opposed to gotos). */
+
+# define TRANSITION_IS_SHIFT(Transitions, Num) \
+ (ISTOKEN (TRANSITION_SYMBOL (Transitions, Num)))
+
+/* Is the TRANSITIONS->states[Num] a goto?. */
+
+# define TRANSITION_IS_GOTO(Transitions, Num) \
+ (!TRANSITION_IS_SHIFT (Transitions, Num))
+
+/* Is the TRANSITIONS->states[Num] labelled by the error token? */
+
+# define TRANSITION_IS_ERROR(Transitions, Num) \
+ (TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
+
+/* When resolving a SR conflicts, if the reduction wins, the shift is
+ disabled. */
+
+# define TRANSITION_DISABLE(Transitions, Num) \
+ (Transitions->states[Num] = NULL)
+
+# define TRANSITION_IS_DISABLED(Transitions, Num) \
+ (Transitions->states[Num] == NULL)
+
+
+/* Iterate over each transition over a token (shifts). */
+# define FOR_EACH_SHIFT(Transitions, Iter) \
+ for (Iter = 0; \
+ Iter < Transitions->num \
+ && (TRANSITION_IS_DISABLED (Transitions, Iter) \
+ || TRANSITION_IS_SHIFT (Transitions, Iter)); \
+ ++Iter) \
+ if (!TRANSITION_IS_DISABLED (Transitions, Iter))
+
+
+/* Return the state such SHIFTS contain a shift/goto to it on SYM.
+ Abort if none found. */
+struct state *transitions_to (transitions *shifts, symbol_number sym);
+
+
+/*-------.
+| Errs. |
+`-------*/
+
+typedef struct
+{
+ int num;
+ symbol *symbols[1];
+} errs;
+
+errs *errs_new (int num, symbol **tokens);
+
+
+/*-------------.
+| Reductions. |
+`-------------*/
+
+typedef struct
+{
+ int num;
+ bitset *lookahead_tokens;
+ /* Sorted ascendingly on rule number. */
+ rule *rules[1];
+} reductions;
+
+
+
+/*---------.
+| states. |
+`---------*/
+
+struct state_list;
+
+struct state
+{
+ state_number number;
+ symbol_number accessing_symbol;
+ transitions *transitions;
+ reductions *reductions;
+ errs *errs;
+
+ /* 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. Sorted
+ ascendingly on item index in RITEM, which is sorted on rule number. */
+ size_t nitems;
+ item_number items[1];
+};
+
+extern state_number nstates;
+extern state *final_state;
+
+/* 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);
+
+/* Set the reductions of STATE. */
+void state_reductions_set (state *s, int num, rule **reds);
+
+int state_reduction_find (state *s, rule *r);
+
+/* Set the errs of STATE. */
+void state_errs_set (state *s, int num, symbol **errors);
+
+/* Print on OUT all the lookahead tokens such that this STATE wants to
+ reduce R. */
+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);
+void state_hash_free (void);
+
+/* Find the state associated to the CORE, and return it. If it does
+ not exist yet, return NULL. */
+state *state_hash_lookup (size_t core_size, item_number *core);
+
+/* 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/contrib/tools/bison/src/symlist.c b/contrib/tools/bison/src/symlist.c
new file mode 100644
index 0000000000..531ec52fb8
--- /dev/null
+++ b/contrib/tools/bison/src/symlist.c
@@ -0,0 +1,239 @@
+/* Lists of symbols for Bison
+
+ Copyright (C) 2002, 2005-2007, 2009-2013 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 "complain.h"
+#include "symlist.h"
+
+/*--------------------------------------.
+| Create a list containing SYM at LOC. |
+`--------------------------------------*/
+
+symbol_list *
+symbol_list_sym_new (symbol *sym, location loc)
+{
+ symbol_list *res = xmalloc (sizeof *res);
+
+ res->content_type = SYMLIST_SYMBOL;
+ res->content.sym = sym;
+ res->location = res->sym_loc = loc;
+ res->named_ref = NULL;
+
+ res->midrule = NULL;
+ res->midrule_parent_rule = NULL;
+ res->midrule_parent_rhs_index = 0;
+
+ /* Members used for LHS only. */
+ res->ruleprec = NULL;
+ res->percent_empty_loc = empty_location;
+ code_props_none_init (&res->action_props);
+ res->dprec = 0;
+ res->dprec_location = empty_location;
+ res->merger = 0;
+ res->merger_declaration_location = empty_location;
+
+ res->next = NULL;
+
+ return res;
+}
+
+
+/*--------------------------------------------.
+| 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.sem_type = xmalloc (sizeof (semantic_type));
+ res->content.sem_type->tag = type_name;
+ res->content.sem_type->location = loc;
+ res->content.sem_type->status = undeclared;
+
+ 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_syms_print (const symbol_list *l, FILE *f)
+{
+ char const *sep = "";
+ for (/* Nothing. */; l && l->content.sym; l = l->next)
+ {
+ fputs (sep, f);
+ fputs (l->content_type == SYMLIST_SYMBOL ? "symbol: "
+ : l->content_type == SYMLIST_TYPE ? "type: "
+ : "invalid content_type: ",
+ f);
+ symbol_print (l->content.sym, f);
+ fputs (l->action_props.is_value_used ? " used" : " unused", f);
+ sep = ", ";
+ }
+}
+
+
+/*---------------------------.
+| Prepend NODE to the LIST. |
+`---------------------------*/
+
+symbol_list *
+symbol_list_prepend (symbol_list *list, symbol_list *node)
+{
+ node->next = list;
+ return node;
+}
+
+
+/*-------------------------.
+| Append NODE to the LIST. |
+`-------------------------*/
+
+symbol_list *
+symbol_list_append (symbol_list *list, symbol_list *node)
+{
+ symbol_list* next;
+ if (!list)
+ return node;
+ next = list;
+ while (next->next)
+ next = next->next;
+ next->next = node;
+ return list;
+}
+
+
+/*-----------------------------------------------.
+| Free the LIST, but not the items it contains. |
+`-----------------------------------------------*/
+
+void
+symbol_list_free (symbol_list *list)
+{
+ symbol_list *node, *next;
+ for (node = list; node; node = next)
+ {
+ next = node->next;
+ named_ref_free (node->named_ref);
+ if (node->content_type == SYMLIST_TYPE)
+ free (node->content.sem_type);
+ free (node);
+ }
+}
+
+
+/*--------------------.
+| Return its length. |
+`--------------------*/
+
+int
+symbol_list_length (symbol_list const *l)
+{
+ int res = 0;
+ for (/* Nothing. */;
+ l && !(l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL);
+ l = l->next)
+ ++res;
+ return res;
+}
+
+
+/*------------------------------.
+| Get item N in symbol list L. |
+`------------------------------*/
+
+symbol_list *
+symbol_list_n_get (symbol_list *l, int n)
+{
+ int i;
+
+ if (n < 0)
+ return NULL;
+
+ for (i = 0; i < n; ++i)
+ {
+ l = l->next;
+ if (l == NULL
+ || (l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL))
+ return NULL;
+ }
+
+ return l;
+}
+
+
+/*--------------------------------------------------------------.
+| Get the data type (alternative in the union) of the value for |
+| symbol N in symbol list L. |
+`--------------------------------------------------------------*/
+
+uniqstr
+symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
+{
+ l = symbol_list_n_get (l, n);
+ if (!l)
+ {
+ complain (&loc, complaint, _("invalid $ value: $%d"), n);
+ return NULL;
+ }
+ aver (l->content_type == SYMLIST_SYMBOL);
+ return l->content.sym->type_name;
+}
+
+bool
+symbol_list_null (symbol_list *node)
+{
+ return !node ||
+ (node->content_type == SYMLIST_SYMBOL && !(node->content.sym));
+}
+
+void
+symbol_list_code_props_set (symbol_list *node, code_props_type kind,
+ code_props const *cprops)
+{
+ switch (node->content_type)
+ {
+ case SYMLIST_SYMBOL:
+ symbol_code_props_set (node->content.sym, kind, cprops);
+ if (node->content.sym->status == undeclared)
+ node->content.sym->status = used;
+ break;
+ case SYMLIST_TYPE:
+ semantic_type_code_props_set
+ (semantic_type_get (node->content.sem_type->tag,
+ &node->content.sem_type->location),
+ kind, cprops);
+ if (node->content.sem_type->status == undeclared)
+ node->content.sem_type->status = used;
+ break;
+ }
+}
diff --git a/contrib/tools/bison/src/symlist.h b/contrib/tools/bison/src/symlist.h
new file mode 100644
index 0000000000..c369f69bb1
--- /dev/null
+++ b/contrib/tools/bison/src/symlist.h
@@ -0,0 +1,133 @@
+/* Lists of symbols for Bison
+
+ Copyright (C) 2002, 2005-2007, 2009-2013 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 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
+{
+ /**
+ * Whether this node contains a symbol, a semantic type, a \c <*>, or a
+ * \c <>.
+ */
+ enum {
+ SYMLIST_SYMBOL,
+ SYMLIST_TYPE
+ } 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>.
+ */
+ semantic_type *sem_type;
+ } content;
+ location location;
+
+ /* Named reference. */
+ named_ref *named_ref;
+
+ /* 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;
+
+ /* 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;
+
+ /* ---------------------------------------------- */
+ /* Apply to the rule (attached to the LHS only). */
+ /* ---------------------------------------------- */
+
+ /* Precedence/associativity. */
+ symbol *ruleprec;
+
+ /* The action is attached to the LHS of a rule, but action properties for
+ * each RHS are also stored here. */
+ code_props action_props;
+
+ /* The location of the first %empty for this rule, or \a
+ empty_location. */
+ location percent_empty_loc;
+
+ int dprec;
+ location dprec_location;
+ int merger;
+ location merger_declaration_location;
+
+ /* The list. */
+ struct symbol_list *next;
+} symbol_list;
+
+
+/** Create a list containing \c sym at \c loc. */
+symbol_list *symbol_list_sym_new (symbol *sym, location loc);
+
+/** Create a list containing \c type_name at \c loc. */
+symbol_list *symbol_list_type_new (uniqstr type_name, location loc);
+
+/** Print this list.
+
+ \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);
+
+/** Prepend \c node to \c list. */
+symbol_list *symbol_list_prepend (symbol_list *list, symbol_list *node);
+
+/** Append \c node to \c list. */
+symbol_list *symbol_list_append (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);
+
+/* Check whether the node is a border element of a rule. */
+bool symbol_list_null (symbol_list *node);
+
+/** Set the \c \%destructor or \c \%printer for \c node as \c cprops. */
+void symbol_list_code_props_set (symbol_list *node, code_props_type kind,
+ code_props const *cprops);
+
+#endif /* !SYMLIST_H_ */
diff --git a/contrib/tools/bison/src/symtab.c b/contrib/tools/bison/src/symtab.c
new file mode 100644
index 0000000000..c06fcd2621
--- /dev/null
+++ b/contrib/tools/bison/src/symtab.c
@@ -0,0 +1,1178 @@
+/* Symbol table manager for Bison.
+
+ Copyright (C) 1984, 1989, 2000-2002, 2004-2013 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 "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;
+static symbol **semantic_types_sorted = NULL;
+
+/*------------------------.
+| Distinguished symbols. |
+`------------------------*/
+
+symbol *errtoken = NULL;
+symbol *undeftoken = NULL;
+symbol *endtoken = NULL;
+symbol *accept = NULL;
+symbol *startsymbol = NULL;
+location startsymbol_location;
+
+/*---------------------------.
+| Precedence relation graph. |
+`---------------------------*/
+
+static symgraph **prec_nodes;
+
+/*-----------------------------------.
+| Store which associativity is used. |
+`-----------------------------------*/
+
+bool *used_assoc = NULL;
+
+/*---------------------------------.
+| Create a new symbol, named TAG. |
+`---------------------------------*/
+
+static symbol *
+symbol_new (uniqstr tag, location loc)
+{
+ 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] != '\'' && strchr (tag, '-'))
+ complain (&loc, Wyacc,
+ _("POSIX Yacc forbids dashes in symbol names: %s"), tag);
+
+ res->tag = tag;
+ res->location = loc;
+
+ res->type_name = NULL;
+ {
+ int i;
+ for (i = 0; i < CODE_PROPS_SIZE; ++i)
+ code_props_none_init (&res->props[i]);
+ }
+
+ res->number = NUMBER_UNDEFINED;
+ res->prec = 0;
+ res->assoc = undef_assoc;
+ res->user_token_number = USER_NUMBER_UNDEFINED;
+
+ res->alias = NULL;
+ res->class = unknown_sym;
+ res->status = undeclared;
+
+ if (nsyms == SYMBOL_NUMBER_MAXIMUM)
+ complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
+ SYMBOL_NUMBER_MAXIMUM);
+ nsyms++;
+ return res;
+}
+
+char const *
+code_props_type_string (code_props_type kind)
+{
+ switch (kind)
+ {
+ case destructor:
+ return "%destructor";
+ case printer:
+ return "%printer";
+ }
+ assert (0);
+}
+
+/*----------------------------------------.
+| Create a new semantic type, named TAG. |
+`----------------------------------------*/
+
+static semantic_type *
+semantic_type_new (uniqstr tag, const location *loc)
+{
+ semantic_type *res = xmalloc (sizeof *res);
+
+ uniqstr_assert (tag);
+ res->tag = tag;
+ res->location = loc ? *loc : empty_location;
+ res->status = undeclared;
+ {
+ int i;
+ for (i = 0; i < CODE_PROPS_SIZE; ++i)
+ code_props_none_init (&res->props[i]);
+ }
+
+ return res;
+}
+
+
+/*-----------------.
+| Print a symbol. |
+`-----------------*/
+
+#define SYMBOL_ATTR_PRINT(Attr) \
+ if (s->Attr) \
+ fprintf (f, " %s { %s }", #Attr, s->Attr)
+
+#define SYMBOL_CODE_PRINT(Attr) \
+ if (s->props[Attr].code) \
+ fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
+
+void
+symbol_print (symbol const *s, FILE *f)
+{
+ if (s)
+ {
+ fputs (s->tag, f);
+ SYMBOL_ATTR_PRINT (type_name);
+ SYMBOL_CODE_PRINT (destructor);
+ SYMBOL_CODE_PRINT (printer);
+ }
+ else
+ fputs ("<NULL>", f);
+}
+
+#undef SYMBOL_ATTR_PRINT
+#undef SYMBOL_CODE_PRINT
+
+
+/*----------------------------------.
+| Whether S is a valid identifier. |
+`----------------------------------*/
+
+static bool
+is_identifier (uniqstr s)
+{
+ static char const alphanum[26 + 26 + 1 + 10 + 1] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_"
+ "0123456789";
+ if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10))
+ return false;
+ for (++s; *s; ++s)
+ if (! memchr (alphanum, *s, sizeof alphanum))
+ return false;
+ return true;
+}
+
+
+/*-----------------------------------------------.
+| Get the identifier associated to this symbol. |
+`-----------------------------------------------*/
+uniqstr
+symbol_id_get (symbol const *sym)
+{
+ aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
+ if (sym->alias)
+ sym = sym->alias;
+ return is_identifier (sym->tag) ? sym->tag : 0;
+}
+
+
+/*------------------------------------------------------------------.
+| Complain that S's WHAT is redeclared at SECOND, and was first set |
+| at FIRST. |
+`------------------------------------------------------------------*/
+
+static void
+symbol_redeclaration (symbol *s, const char *what, location first,
+ location second)
+{
+ unsigned i = 0;
+ complain_indent (&second, complaint, &i,
+ _("%s redeclaration for %s"), what, s->tag);
+ i += SUB_INDENT;
+ complain_indent (&first, complaint, &i,
+ _("previous declaration"));
+}
+
+static void
+semantic_type_redeclaration (semantic_type *s, const char *what, location first,
+ location second)
+{
+ unsigned i = 0;
+ complain_indent (&second, complaint, &i,
+ _("%s redeclaration for <%s>"), what, s->tag);
+ i += SUB_INDENT;
+ complain_indent (&first, complaint, &i,
+ _("previous declaration"));
+}
+
+
+
+/*-----------------------------------------------------------------.
+| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
+| as TYPE_NAME. |
+`-----------------------------------------------------------------*/
+
+void
+symbol_type_set (symbol *sym, uniqstr type_name, location loc)
+{
+ if (type_name)
+ {
+ if (sym->type_name)
+ symbol_redeclaration (sym, "%type", sym->type_location, loc);
+ else
+ {
+ uniqstr_assert (type_name);
+ sym->type_name = type_name;
+ sym->type_location = loc;
+ }
+ }
+}
+
+/*--------------------------------------------------------.
+| Set the DESTRUCTOR or PRINTER associated with the SYM. |
+`--------------------------------------------------------*/
+
+void
+symbol_code_props_set (symbol *sym, code_props_type kind,
+ code_props const *code)
+{
+ if (sym->props[kind].code)
+ symbol_redeclaration (sym, code_props_type_string (kind),
+ sym->props[kind].location,
+ code->location);
+ else
+ sym->props[kind] = *code;
+}
+
+/*-----------------------------------------------------.
+| Set the DESTRUCTOR or PRINTER associated with TYPE. |
+`-----------------------------------------------------*/
+
+void
+semantic_type_code_props_set (semantic_type *type,
+ code_props_type kind,
+ code_props const *code)
+{
+ if (type->props[kind].code)
+ semantic_type_redeclaration (type, code_props_type_string (kind),
+ type->props[kind].location,
+ code->location);
+ else
+ type->props[kind] = *code;
+}
+
+/*---------------------------------------------------.
+| Get the computed %destructor or %printer for SYM. |
+`---------------------------------------------------*/
+
+code_props *
+symbol_code_props_get (symbol *sym, code_props_type kind)
+{
+ /* Per-symbol code props. */
+ if (sym->props[kind].code)
+ return &sym->props[kind];
+
+ /* Per-type code props. */
+ if (sym->type_name)
+ {
+ code_props *code =
+ &semantic_type_get (sym->type_name, NULL)->props[kind];
+ if (code->code)
+ return code;
+ }
+
+ /* Apply default code props's only to user-defined symbols. */
+ if (sym->tag[0] != '$' && sym != errtoken)
+ {
+ code_props *code =
+ &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
+ if (code->code)
+ return code;
+ }
+ return &code_props_none;
+}
+
+/*-----------------------------------------------------------------.
+| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
+| with UNDEF_ASSOC as ASSOC. |
+`-----------------------------------------------------------------*/
+
+void
+symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
+{
+ if (a != undef_assoc)
+ {
+ if (sym->prec)
+ symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
+ loc);
+ else
+ {
+ sym->prec = prec;
+ sym->assoc = a;
+ sym->prec_location = loc;
+ }
+ }
+
+ /* Only terminals have a precedence. */
+ symbol_class_set (sym, token_sym, loc, false);
+}
+
+
+/*------------------------------------.
+| Set the CLASS associated with SYM. |
+`------------------------------------*/
+
+void
+symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
+{
+ bool warned = false;
+ if (sym->class != unknown_sym && sym->class != class)
+ {
+ complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
+ /* Don't report both "redefined" and "redeclared". */
+ warned = true;
+ }
+
+ if (class == nterm_sym && sym->class != nterm_sym)
+ sym->number = nvars++;
+ else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
+ sym->number = ntokens++;
+
+ sym->class = class;
+
+ if (declaring)
+ {
+ if (sym->status == declared && !warned)
+ complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
+ else
+ sym->status = declared;
+ }
+}
+
+
+/*------------------------------------------------.
+| Set the USER_TOKEN_NUMBER associated with SYM. |
+`------------------------------------------------*/
+
+void
+symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
+{
+ int *user_token_numberp;
+
+ 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 (&loc, complaint, _("redefining user token number of %s"),
+ sym->tag);
+
+ *user_token_numberp = user_token_number;
+ /* User defined $end token? */
+ if (user_token_number == 0)
+ {
+ endtoken = sym;
+ /* It is always mapped to 0, so it was already counted in
+ NTOKENS. */
+ if (endtoken->number != NUMBER_UNDEFINED)
+ --ntokens;
+ endtoken->number = 0;
+ }
+}
+
+
+/*----------------------------------------------------------.
+| If SYM is not defined, report an error, and consider it a |
+| nonterminal. |
+`----------------------------------------------------------*/
+
+static inline bool
+symbol_check_defined (symbol *sym)
+{
+ if (sym->class == unknown_sym)
+ {
+ assert (sym->status != declared);
+ complain (&sym->location,
+ sym->status == needed ? complaint : Wother,
+ _("symbol %s is used, but is not defined as a token"
+ " and has no rules"),
+ sym->tag);
+ sym->class = nterm_sym;
+ sym->number = nvars++;
+ }
+
+ {
+ int i;
+ for (i = 0; i < 2; ++i)
+ symbol_code_props_get (sym, i)->is_used = true;
+ }
+
+ /* Set the semantic type status associated to the current symbol to
+ 'declared' so that we could check semantic types unnecessary uses. */
+ if (sym->type_name)
+ {
+ semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
+ if (sem_type)
+ sem_type->status = declared;
+ }
+
+ return true;
+}
+
+static inline bool
+semantic_type_check_defined (semantic_type *sem_type)
+{
+ /* <*> and <> do not have to be "declared". */
+ if (sem_type->status == declared
+ || !*sem_type->tag
+ || STREQ (sem_type->tag, "*"))
+ {
+ int i;
+ for (i = 0; i < 2; ++i)
+ if (sem_type->props[i].kind != CODE_PROPS_NONE
+ && ! sem_type->props[i].is_used)
+ complain (&sem_type->location, Wother,
+ _("useless %s for type <%s>"),
+ code_props_type_string (i), sem_type->tag);
+ }
+ else
+ complain (&sem_type->location, Wother,
+ _("type <%s> is used, but is not associated to any symbol"),
+ sem_type->tag);
+
+ return true;
+}
+
+static bool
+symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
+{
+ return symbol_check_defined (sym);
+}
+
+static bool
+semantic_type_check_defined_processor (void *sem_type,
+ void *null ATTRIBUTE_UNUSED)
+{
+ return semantic_type_check_defined (sem_type);
+}
+
+
+void
+symbol_make_alias (symbol *sym, symbol *str, location loc)
+{
+ if (str->alias)
+ complain (&loc, Wother,
+ _("symbol %s used more than once as a literal string"), str->tag);
+ else if (sym->alias)
+ complain (&loc, Wother,
+ _("symbol %s given more than one literal string"), sym->tag);
+ else
+ {
+ 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);
+ }
+}
+
+
+/*---------------------------------------------------------.
+| Check that THIS, and its alias, have same precedence and |
+| associativity. |
+`---------------------------------------------------------*/
+
+static inline void
+symbol_check_alias_consistency (symbol *this)
+{
+ symbol *sym = this;
+ symbol *str = this->alias;
+
+ /* Check only the symbol in the symbol-string pair. */
+ if (!(this->alias
+ && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
+ return;
+
+ if (str->type_name != sym->type_name)
+ {
+ if (str->type_name)
+ symbol_type_set (sym, str->type_name, str->type_location);
+ else
+ symbol_type_set (str, sym->type_name, sym->type_location);
+ }
+
+
+ {
+ int i;
+ for (i = 0; i < CODE_PROPS_SIZE; ++i)
+ if (str->props[i].code)
+ symbol_code_props_set (sym, i, &str->props[i]);
+ else if (sym->props[i].code)
+ symbol_code_props_set (str, i, &sym->props[i]);
+ }
+
+ if (sym->prec || str->prec)
+ {
+ if (str->prec)
+ symbol_precedence_set (sym, str->prec, str->assoc,
+ str->prec_location);
+ else
+ symbol_precedence_set (str, sym->prec, sym->assoc,
+ sym->prec_location);
+ }
+}
+
+static bool
+symbol_check_alias_consistency_processor (void *this,
+ void *null ATTRIBUTE_UNUSED)
+{
+ symbol_check_alias_consistency (this);
+ return true;
+}
+
+
+/*-------------------------------------------------------------------.
+| Assign a symbol number, and write the definition of the token name |
+| into FDEFINES. Put in SYMBOLS. |
+`-------------------------------------------------------------------*/
+
+static inline bool
+symbol_pack (symbol *this)
+{
+ aver (this->number != NUMBER_UNDEFINED);
+ if (this->class == nterm_sym)
+ this->number += ntokens;
+ else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
+ return true;
+
+ symbols[this->number] = this;
+ return true;
+}
+
+static bool
+symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
+{
+ return symbol_pack (this);
+}
+
+
+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_indent (&second->location, complaint, &i,
+ _("user token number %d redeclaration for %s"),
+ num, second->tag);
+ i += SUB_INDENT;
+ complain_indent (&first->location, complaint, &i,
+ _("previous declaration for %s"),
+ first->tag);
+}
+
+/*--------------------------------------------------.
+| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
+`--------------------------------------------------*/
+
+static inline bool
+symbol_translation (symbol *this)
+{
+ /* Non-terminal? */
+ if (this->class == token_sym
+ && 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)
+ user_token_number_redeclaration
+ (this->user_token_number,
+ symbols[token_translations[this->user_token_number]],
+ this);
+ else
+ token_translations[this->user_token_number] = this->number;
+ }
+
+ return true;
+}
+
+static bool
+symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
+{
+ return symbol_translation (this);
+}
+
+
+/*---------------------------------------.
+| Symbol and semantic type hash tables. |
+`---------------------------------------*/
+
+/* 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)
+{
+ /* Since tags are unique, we can compare the pointers themselves. */
+ 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)
+{
+ /* Since tags are unique, we can hash the pointer itself. */
+ 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. |
+`-------------------------------*/
+
+void
+symbols_new (void)
+{
+ symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
+ NULL,
+ 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, const location *loc)
+{
+ 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, loc);
+ if (!hash_insert (semantic_type_table, entry))
+ xalloc_die ();
+ }
+ return entry;
+}
+
+
+/*----------------------------------------------------------------.
+| Find the symbol named KEY, and return it. If it does not exist |
+| yet, create it. |
+`----------------------------------------------------------------*/
+
+symbol *
+symbol_get (const char *key, location loc)
+{
+ return symbol_from_uniqstr (uniqstr_new (key), loc);
+}
+
+
+/*-----------------------------------------------------------------------.
+| 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, const location *loc)
+{
+ return semantic_type_from_uniqstr (uniqstr_new (key), loc);
+}
+
+
+/*------------------------------------------------------------------.
+| Generate a dummy nonterminal, whose name cannot conflict with the |
+| user's names. |
+`------------------------------------------------------------------*/
+
+symbol *
+dummy_symbol_get (location loc)
+{
+ /* Incremented for each generated symbol. */
+ static int dummy_count = 0;
+ static char buf[256];
+
+ symbol *sym;
+
+ 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. |
+`-------------------*/
+
+void
+symbols_free (void)
+{
+ hash_free (symbol_table);
+ hash_free (semantic_type_table);
+ free (symbols);
+ free (symbols_sorted);
+ free (semantic_types_sorted);
+}
+
+
+/*---------------------------------------------------------------.
+| Look for undefined symbols, report an error, and consider them |
+| 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,
+ struct hash_table *table, symbol ***sorted)
+{
+ size_t count = hash_get_n_entries (table);
+ if (!*sorted)
+ {
+ *sorted = xnmalloc (count, sizeof **sorted);
+ hash_get_entries (table, (void**)*sorted, count);
+ qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
+ }
+ {
+ size_t i;
+ for (i = 0; i < count; ++i)
+ processor ((*sorted)[i], processor_data);
+ }
+}
+
+/*--------------------------------------------------------------.
+| Check that all the symbols are defined. Report any undefined |
+| symbols and consider them nonterminals. |
+`--------------------------------------------------------------*/
+
+void
+symbols_check_defined (void)
+{
+ symbols_do (symbol_check_defined_processor, NULL,
+ symbol_table, &symbols_sorted);
+ symbols_do (semantic_type_check_defined_processor, NULL,
+ semantic_type_table, &semantic_types_sorted);
+}
+
+/*------------------------------------------------------------------.
+| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
+| number. |
+`------------------------------------------------------------------*/
+
+static void
+symbols_token_translations_init (void)
+{
+ bool num_256_available_p = true;
+ int i;
+
+ /* Find the highest user token number, and whether 256, the POSIX
+ preferred user token number for the error token, is used. */
+ max_user_token_number = 0;
+ for (i = 0; i < ntokens; ++i)
+ {
+ symbol *this = symbols[i];
+ if (this->user_token_number != USER_NUMBER_UNDEFINED)
+ {
+ if (this->user_token_number > max_user_token_number)
+ max_user_token_number = this->user_token_number;
+ if (this->user_token_number == 256)
+ num_256_available_p = false;
+ }
+ }
+
+ /* If 256 is not used, assign it to error, to follow POSIX. */
+ if (num_256_available_p
+ && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
+ errtoken->user_token_number = 256;
+
+ /* Set the missing user numbers. */
+ if (max_user_token_number < 256)
+ max_user_token_number = 256;
+
+ for (i = 0; i < ntokens; ++i)
+ {
+ symbol *this = symbols[i];
+ if (this->user_token_number == USER_NUMBER_UNDEFINED)
+ this->user_token_number = ++max_user_token_number;
+ if (this->user_token_number > max_user_token_number)
+ max_user_token_number = this->user_token_number;
+ }
+
+ token_translations = xnmalloc (max_user_token_number + 1,
+ sizeof *token_translations);
+
+ /* Initialize all entries for literal tokens to the internal token
+ number for $undefined, which represents all invalid inputs. */
+ for (i = 0; i < max_user_token_number + 1; i++)
+ token_translations[i] = undeftoken->number;
+ symbols_do (symbol_translation_processor, NULL,
+ symbol_table, &symbols_sorted);
+}
+
+
+/*----------------------------------------------------------------.
+| Assign symbol numbers, and write definition of token names into |
+| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
+`----------------------------------------------------------------*/
+
+void
+symbols_pack (void)
+{
+ symbols_do (symbol_check_alias_consistency_processor, NULL,
+ symbol_table, &symbols_sorted);
+
+ symbols = xcalloc (nsyms, sizeof *symbols);
+ symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
+
+ /* 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)
+ complain (&startsymbol_location, fatal,
+ _("the start symbol %s is undefined"),
+ startsymbol->tag);
+ else if (startsymbol->class == token_sym)
+ complain (&startsymbol_location, fatal,
+ _("the start symbol %s is a token"),
+ startsymbol->tag);
+}
+
+/*---------------------------------.
+| Initialize relation graph nodes. |
+`---------------------------------*/
+
+static void
+init_prec_nodes (void)
+{
+ int i;
+ symgraph* s;
+ prec_nodes = xcalloc (nsyms, sizeof *prec_nodes);
+ for (i = 0; i < nsyms; ++i)
+ {
+ prec_nodes[i] = xmalloc (sizeof *prec_nodes[i]);
+ s = prec_nodes[i];
+ s->id = i;
+ s->succ = 0;
+ s->pred = 0;
+ }
+}
+
+/*----------------.
+| Create a link. |
+`----------------*/
+
+static symgraphlink *
+symgraphlink_new (graphid id, symgraphlink *next)
+{
+ symgraphlink *l = xmalloc (sizeof *l);
+ l->id = id;
+ l->next = next;
+ return l;
+}
+
+
+/*------------------------------------------------------------------.
+| Register the second symbol of the precedence relation, and return |
+| whether this relation is new. Use only in register_precedence. |
+`------------------------------------------------------------------*/
+
+static bool
+register_precedence_second_symbol (symgraphlink **first, graphid sym)
+{
+ if (!*first || sym < (*first)->id)
+ *first = symgraphlink_new (sym, *first);
+ else
+ {
+ symgraphlink *slist = *first;
+
+ while (slist->next && slist->next->id <= sym)
+ slist = slist->next;
+
+ if (slist->id == sym)
+ /* Relation already present. */
+ return false;
+
+ slist->next = symgraphlink_new (sym, slist->next);
+ }
+ return true;
+}
+
+/*------------------------------------------------------------------.
+| Register a new relation between symbols as used. The first symbol |
+| has a greater precedence than the second one. |
+`------------------------------------------------------------------*/
+
+void
+register_precedence (graphid first, graphid snd)
+{
+ if (!prec_nodes)
+ init_prec_nodes ();
+ register_precedence_second_symbol (&(prec_nodes[first]->succ), snd);
+ register_precedence_second_symbol (&(prec_nodes[snd]->pred), first);
+}
+
+
+/*---------------------------------------.
+| Deep clear a linked / adjacency list). |
+`---------------------------------------*/
+
+static void
+linkedlist_free (symgraphlink *node)
+{
+ if (node)
+ {
+ while (node->next)
+ {
+ symgraphlink *tmp = node->next;
+ free (node);
+ node = tmp;
+ }
+ free (node);
+ }
+}
+
+/*----------------------------------------------.
+| Clear and destroy association tracking table. |
+`----------------------------------------------*/
+
+static void
+assoc_free (void)
+{
+ int i;
+ for (i = 0; i < nsyms; ++i)
+ {
+ linkedlist_free (prec_nodes[i]->pred);
+ linkedlist_free (prec_nodes[i]->succ);
+ free (prec_nodes[i]);
+ }
+ free (prec_nodes);
+}
+
+/*---------------------------------------.
+| Initialize association tracking table. |
+`---------------------------------------*/
+
+static void
+init_assoc (void)
+{
+ graphid i;
+ used_assoc = xcalloc (nsyms, sizeof *used_assoc);
+ for (i = 0; i < nsyms; ++i)
+ used_assoc[i] = false;
+}
+
+/*------------------------------------------------------------------.
+| Test if the associativity for the symbols is defined and useless. |
+`------------------------------------------------------------------*/
+
+static inline bool
+is_assoc_useless (symbol *s)
+{
+ return s
+ && s->assoc != undef_assoc
+ && s->assoc != precedence_assoc
+ && !used_assoc[s->number];
+}
+
+/*-------------------------------.
+| Register a used associativity. |
+`-------------------------------*/
+
+void
+register_assoc (graphid i, graphid j)
+{
+ if (!used_assoc)
+ init_assoc ();
+ used_assoc[i] = true;
+ used_assoc[j] = true;
+}
+
+/*--------------------------------------------------.
+| Print a warning for unused precedence relations. |
+`--------------------------------------------------*/
+
+void
+print_precedence_warnings (void)
+{
+ int i;
+ if (!prec_nodes)
+ init_prec_nodes ();
+ if (!used_assoc)
+ init_assoc ();
+ for (i = 0; i < nsyms; ++i)
+ {
+ symbol *s = symbols[i];
+ if (s
+ && s->prec != 0
+ && !prec_nodes[i]->pred
+ && !prec_nodes[i]->succ)
+ {
+ if (is_assoc_useless (s))
+ complain (&s->prec_location, Wprecedence,
+ _("useless precedence and associativity for %s"), s->tag);
+ else if (s->assoc == precedence_assoc)
+ complain (&s->prec_location, Wprecedence,
+ _("useless precedence for %s"), s->tag);
+ }
+ else if (is_assoc_useless (s))
+ complain (&s->prec_location, Wprecedence,
+ _("useless associativity for %s, use %%precedence"), s->tag);
+ }
+ free (used_assoc);
+ assoc_free ();
+}
diff --git a/contrib/tools/bison/src/symtab.h b/contrib/tools/bison/src/symtab.h
new file mode 100644
index 0000000000..bcc749511c
--- /dev/null
+++ b/contrib/tools/bison/src/symtab.h
@@ -0,0 +1,338 @@
+/* Definitions for symtab.c and callers, part of Bison.
+
+ Copyright (C) 1984, 1989, 1992, 2000-2002, 2004-2013 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/>. */
+
+/**
+ * \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. */
+typedef enum
+{
+ unknown_sym, /**< Undefined. */
+ token_sym, /**< Terminal. */
+ nterm_sym /**< Non-terminal. */
+} symbol_class;
+
+
+/** Internal token numbers. */
+typedef int symbol_number;
+# define SYMBOL_NUMBER_MAXIMUM INT_MAX
+
+
+typedef struct symbol symbol;
+
+/* Declaration status of a symbol.
+
+ First, it is "undeclared". Then, if "undeclared" and used in a
+ %printer/%destructor, it is "used". If not "declared" but used in
+ a rule, it is "needed". Finally, if declared (via a rule for
+ nonterminals, or %token), it is "declared".
+
+ When status are checked at the end, "declared" symbols are fine,
+ "used" symbols trigger warnings, otherwise it's an error. */
+
+typedef enum
+ {
+ /** Used in the input file for an unknown reason (error). */
+ undeclared,
+ /** Used by %destructor/%printer but not defined (warning). */
+ used,
+ /** Used in the gramar (rules) but not defined (error). */
+ needed,
+ /** Defined with %type or %token (good). */
+ declared,
+ } status;
+
+typedef enum code_props_type code_props_type;
+enum code_props_type
+ {
+ destructor = 0,
+ printer = 1,
+ };
+
+enum { CODE_PROPS_SIZE = 2 };
+
+/* When extending this structure, be sure to complete
+ symbol_check_alias_consistency. */
+struct symbol
+{
+ /** The key, name of the symbol. */
+ uniqstr tag;
+ /** The location of its first occurrence. */
+ location location;
+
+ /** 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;
+
+ /** Any \c \%destructor (resp. \%printer) declared specificially for this
+ symbol.
+
+ Access this field only through <tt>symbol</tt>'s interface functions. For
+ example, if <tt>symbol::destructor = NULL</tt> (resp. <tt>symbol::printer
+ = NULL</tt>), a default \c \%destructor (resp. \%printer) or a per-type
+ \c symbol_destructor_printer_get will compute the correct one. */
+ code_props props[CODE_PROPS_SIZE];
+
+ symbol_number number;
+ location prec_location;
+ int prec;
+ assoc assoc;
+ int user_token_number;
+
+ /* 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;
+ status status;
+};
+
+/** Undefined user number. */
+# define USER_NUMBER_UNDEFINED -1
+
+/* '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_HAS_STRING_ALIAS. */
+# define USER_NUMBER_HAS_STRING_ALIAS -9991
+
+/* Undefined internal token number. */
+# define NUMBER_UNDEFINED (-1)
+
+/** 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.
+
+ Its name cannot conflict with the user's names. */
+symbol *dummy_symbol_get (location loc);
+
+
+/*--------------------.
+| Methods on symbol. |
+`--------------------*/
+
+/** Print a symbol (for debugging). */
+void symbol_print (symbol const *s, FILE *f);
+
+/** Is this a dummy nonterminal? */
+bool symbol_is_dummy (const symbol *sym);
+
+/** The name of the code_props type: "\%destructor" or "\%printer". */
+char const *code_props_type_string (code_props_type kind);
+
+/** The name of the symbol that can be used as an identifier.
+ ** Consider the alias if needed.
+ ** Return 0 if there is none (e.g., the symbol is only defined as
+ ** a string). */
+uniqstr symbol_id_get (symbol const *sym);
+
+/**
+ * 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 \c \%destructor or \c \%printer associated with \c sym. */
+void symbol_code_props_set (symbol *sym, code_props_type kind,
+ code_props const *destructor);
+
+/** Get the computed \c \%destructor or \c %printer for \c sym, which was
+ initialized with \c code_props_none_init if there's no \c \%destructor or
+ \c %printer. */
+code_props *symbol_code_props_get (symbol *sym, code_props_type kind);
+
+/** 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 \c class associated with \c sym. */
+void symbol_class_set (symbol *sym, symbol_class class, location loc,
+ bool declaring);
+
+/** Set the \c user_token_number associated with \c sym. */
+void symbol_user_token_number_set (symbol *sym, int user_number, location loc);
+
+
+
+/*------------------.
+| Special symbols. |
+`------------------*/
+
+/** 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 Relations. |
+`-------------------*/
+
+/* The symbol relations are represented by a directed graph. */
+
+/* The id of a node */
+typedef int graphid;
+
+typedef struct symgraphlink symgraphlink;
+
+struct symgraphlink
+{
+ /** The second \c symbol or group of a precedence relation.
+ * See \c symgraph. */
+ graphid id;
+
+ symgraphlink *next;
+};
+
+/* Symbol precedence graph, to store the used precedence relations between
+ * symbols. */
+
+typedef struct symgraph symgraph;
+
+struct symgraph
+{
+ /** Identifier for the node: equal to the number of the symbol. */
+ graphid id;
+
+ /** The list of related symbols that have a smaller precedence. */
+ symgraphlink *succ;
+
+ /** The list of related symbols that have a greater precedence. */
+ symgraphlink *pred;
+};
+
+/** Register a new precedence relation as used. */
+
+void register_precedence (graphid first, graphid snd);
+
+/** Print a warning for each symbol whose precedence and/or associativity
+ * is useless. */
+
+void print_precedence_warnings (void);
+
+/*----------------------.
+| Symbol associativity |
+`----------------------*/
+
+void register_assoc (graphid i, graphid j);
+
+/*-----------------.
+| Semantic types. |
+`-----------------*/
+
+/** A semantic type and its associated \c \%destructor and \c \%printer.
+
+ 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;
+
+ /** The location of its first occurence. */
+ location location;
+
+ /** Its status : "undeclared", "used" or "declared".
+ It cannot be "needed". */
+ status status;
+
+ /** Any \c %destructor and %printer declared for this
+ semantic type. */
+ code_props props[CODE_PROPS_SIZE];
+
+} semantic_type;
+
+/** Fetch (or create) the semantic type associated to KEY. */
+semantic_type *semantic_type_from_uniqstr (const uniqstr key,
+ const location *loc);
+
+/** Fetch (or create) the semantic type associated to KEY. */
+semantic_type *semantic_type_get (const char *key, const location *loc);
+
+/** Set the \c destructor or \c printer associated with \c type. */
+void semantic_type_code_props_set (semantic_type *type,
+ code_props_type kind,
+ code_props const *code);
+
+/*----------------------------------.
+| Symbol and semantic type tables. |
+`----------------------------------*/
+
+/** Create the symbol and semantic type tables. */
+void symbols_new (void);
+
+/** 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. */
+void symbols_check_defined (void);
+
+/** Sanity checks and #token_translations construction.
+
+ Perform various sanity checks, assign symbol numbers, and set up
+ #token_translations. */
+void symbols_pack (void);
+
+#endif /* !SYMTAB_H_ */
diff --git a/contrib/tools/bison/src/system.h b/contrib/tools/bison/src/system.h
new file mode 100644
index 0000000000..3267f2d24c
--- /dev/null
+++ b/contrib/tools/bison/src/system.h
@@ -0,0 +1,261 @@
+/* System-dependent definitions for Bison.
+
+ Copyright (C) 2000-2007, 2009-2013 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/>. */
+
+#ifndef 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
+
+# include <limits.h>
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+
+# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
+# define STREQ(L, R) (strcmp(L, R) == 0)
+# define STRNEQ(L, R) (!STREQ(L, R))
+
+/* Just like strncmp, but the second argument must be a literal string
+ and you don't specify the length. */
+# define STRNCMP_LIT(S, Literal) \
+ strncmp (S, "" Literal "", sizeof (Literal) - 1)
+
+/* Whether Literal is a prefix of S. */
+# define STRPREFIX_LIT(Literal, S) \
+ (STRNCMP_LIT (S, Literal) == 0)
+
+# include <unistd.h>
+# include <inttypes.h>
+
+# 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
+
+/* Version mismatch. */
+# define EX_MISMATCH 63
+
+/*---------.
+| Gnulib. |
+`---------*/
+
+# include <unlocked-io.h>
+# include <verify.h>
+# include <xalloc.h>
+
+
+/*-----------------.
+| GCC extensions. |
+`-----------------*/
+
+/* 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.
+
+ 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))
+# define __attribute__(Spec) /* empty */
+# 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
+
+# ifndef ATTRIBUTE_NORETURN
+# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+# endif
+
+# ifndef ATTRIBUTE_UNUSED
+# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# endif
+
+
+/*------.
+| NLS. |
+`------*/
+
+# include <locale.h>
+
+# include <gettext.h>
+# define _(Msgid) gettext (Msgid)
+# define N_(Msgid) (Msgid)
+
+
+/*-----------.
+| Booleans. |
+`-----------*/
+
+# 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>
+
+/* String-grow: append Str to Obs. */
+
+# define obstack_sgrow(Obs, Str) \
+ obstack_grow (Obs, Str, strlen (Str))
+
+/* Output Str escaped for our postprocessing (i.e., escape M4 special
+ characters).
+
+ For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][". */
+
+# 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)
+
+
+/* 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 TAB_EXT
+# define TAB_EXT ".tab"
+# endif
+
+
+
+/*---------------------.
+| 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)
+
+
+/*---------------------------------------------.
+| Debugging memory allocation (must be last). |
+`---------------------------------------------*/
+
+# if WITH_DMALLOC
+# define DMALLOC_FUNC_CHECK
+# include <dmalloc.h>
+# endif /* WITH_DMALLOC */
+
+#endif /* ! BISON_SYSTEM_H */
diff --git a/contrib/tools/bison/src/tables.c b/contrib/tools/bison/src/tables.c
new file mode 100644
index 0000000000..f06cba86b9
--- /dev/null
+++ b/contrib/tools/bison/src/tables.c
@@ -0,0 +1,863 @@
+/* Output the generated parsing program for Bison.
+
+ Copyright (C) 1984, 1986, 1989, 1992, 2000-2006, 2009-2013 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 <bitsetv.h>
+
+#include "complain.h"
+#include "conflicts.h"
+#include "files.h"
+#include "getargs.h"
+#include "gram.h"
+#include "lalr.h"
+#include "muscle-tab.h"
+#include "reader.h"
+#include "symtab.h"
+#include "tables.h"
+
+/* Several tables are indexed both by state and nonterminal numbers.
+ We call such an index a 'vector'; i.e., a vector is either a state
+ or a nonterminal number.
+
+ Of course vector_number_t ought to be wide enough to contain
+ state_number and symbol_number. */
+typedef int vector_number;
+
+#if 0 /* Not currently used. */
+static inline vector_number
+state_number_to_vector_number (state_number s)
+{
+ return s;
+}
+#endif
+
+static inline vector_number
+symbol_number_to_vector_number (symbol_number sym)
+{
+ return state_number_as_int (nstates) + sym - ntokens;
+}
+
+int nvectors;
+
+
+/* FROMS and TOS are indexed by vector_number.
+
+ If VECTOR is a nonterminal, (FROMS[VECTOR], TOS[VECTOR]) form an
+ array of state numbers of the non defaulted GOTO on VECTOR.
+
+ If VECTOR is a state, TOS[VECTOR] is the array of actions to do on
+ the (array of) symbols FROMS[VECTOR].
+
+ In both cases, TALLY[VECTOR] is the size of the arrays
+ FROMS[VECTOR], TOS[VECTOR]; and WIDTH[VECTOR] =
+ (FROMS[VECTOR][SIZE] - FROMS[VECTOR][0] + 1) where SIZE =
+ TALLY[VECTOR].
+
+ FROMS therefore contains symbol_number and action_number,
+ TOS state_number and action_number,
+ TALLY sizes,
+ WIDTH differences of FROMS.
+
+ Let base_number be the type of FROMS, TOS, and WIDTH. */
+#define BASE_MAXIMUM INT_MAX
+#define BASE_MINIMUM INT_MIN
+
+static base_number **froms;
+static base_number **tos;
+static unsigned int **conflict_tos;
+static size_t *tally;
+static base_number *width;
+
+
+/* For a given state, N = ACTROW[SYMBOL]:
+
+ If N = 0, stands for 'run the default action'.
+ If N = MIN, stands for 'raise a syntax error'.
+ If N > 0, stands for 'shift SYMBOL and go to n'.
+ If N < 0, stands for 'reduce -N'. */
+typedef int action_number;
+#define ACTION_NUMBER_MINIMUM INT_MIN
+
+static action_number *actrow;
+
+/* FROMS and TOS are reordered to be compressed. ORDER[VECTOR] is the
+ new vector number of VECTOR. We skip 'empty' vectors (i.e.,
+ TALLY[VECTOR] = 0), and call these 'entries'. */
+static vector_number *order;
+static int nentries;
+
+base_number *base = NULL;
+/* A distinguished value of BASE, negative infinite. During the
+ computation equals to BASE_MINIMUM, later mapped to BASE_NINF to
+ keep parser tables small. */
+base_number base_ninf = 0;
+static base_number *pos = NULL;
+
+static unsigned int *conflrow;
+unsigned int *conflict_table;
+unsigned int *conflict_list;
+int conflict_list_cnt;
+static int conflict_list_free;
+
+/* TABLE_SIZE is the allocated size of both TABLE and CHECK. We start
+ with more or less the original hard-coded value (which was
+ SHRT_MAX). */
+static int table_size = 32768;
+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_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;
+static int lowzero;
+int high;
+
+state_number *yydefgoto;
+rule_number *yydefact;
+
+/*-------------------------------------------------------------------.
+| If TABLE, CONFLICT_TABLE, and CHECK are too small to be addressed |
+| at DESIRED, grow them. TABLE[DESIRED] can be used, so the desired |
+| size is at least DESIRED + 1. |
+`-------------------------------------------------------------------*/
+
+static void
+table_grow (int desired)
+{
+ int old_size = table_size;
+
+ while (table_size <= desired)
+ table_size *= 2;
+
+ if (trace_flag & trace_resource)
+ fprintf (stderr, "growing table and check from: %d to %d\n",
+ old_size, table_size);
+
+ table = xnrealloc (table, table_size, sizeof *table);
+ conflict_table = xnrealloc (conflict_table, table_size,
+ sizeof *conflict_table);
+ check = xnrealloc (check, table_size, sizeof *check);
+
+ for (/* Nothing. */; old_size < table_size; ++old_size)
+ {
+ table[old_size] = 0;
+ conflict_table[old_size] = 0;
+ check[old_size] = -1;
+ }
+}
+
+
+
+
+/*-------------------------------------------------------------------.
+| For GLR parsers, for each conflicted token in S, as indicated |
+| by non-zero entries in CONFLROW, create a list of possible |
+| reductions that are alternatives to the shift or reduction |
+| currently recorded for that token in S. Store the alternative |
+| reductions followed by a 0 in CONFLICT_LIST, updating |
+| CONFLICT_LIST_CNT, and storing an index to the start of the list |
+| back into CONFLROW. |
+`-------------------------------------------------------------------*/
+
+static void
+conflict_row (state *s)
+{
+ int i, j;
+ reductions *reds = s->reductions;
+
+ if (!nondeterministic_parser)
+ return;
+
+ for (j = 0; j < ntokens; j += 1)
+ if (conflrow[j])
+ {
+ conflrow[j] = conflict_list_cnt;
+
+ /* 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->lookahead_tokens[i], j)
+ && (actrow[j]
+ != rule_number_as_item_number (reds->rules[i]->number)))
+ {
+ 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. */
+ aver (0 < conflict_list_free);
+ conflict_list[conflict_list_cnt] = 0;
+ conflict_list_cnt += 1;
+ conflict_list_free -= 1;
+ }
+}
+
+
+/*------------------------------------------------------------------.
+| Decide what to do for each type of token if seen 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 |
+| ACTION_NUMBER_MINIMUM, a very negative number, means this |
+| situation is an error. The parser recognizes this value |
+| specially. |
+| |
+| 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. |
+| |
+| For GLR parsers, also sets CONFLROW[SYM] to an index into |
+| CONFLICT_LIST iff there is an unresolved conflict (s/r or r/r) |
+| with symbol SYM. The default reduction is not used for a symbol |
+| that has any such conflicts. |
+`------------------------------------------------------------------*/
+
+static rule *
+action_row (state *s)
+{
+ int i;
+ rule *default_reduction = NULL;
+ reductions *reds = s->reductions;
+ transitions *trans = s->transitions;
+ errs *errp = s->errs;
+ /* Set to nonzero to inhibit having any default reduction. */
+ bool nodefault = false;
+ bool conflicted = false;
+
+ for (i = 0; i < ntokens; i++)
+ actrow[i] = conflrow[i] = 0;
+
+ if (reds->lookahead_tokens)
+ {
+ int j;
+ bitset_iterator biter;
+ /* loop over all the rules available here which require
+ 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->lookahead_tokens[i], j, 0)
+ {
+ /* and record this rule as the rule to use if that
+ token follows. */
+ if (actrow[j] != 0)
+ {
+ conflicted = true;
+ conflrow[j] = 1;
+ }
+ actrow[j] = rule_number_as_item_number (reds->rules[i]->number);
+ }
+ }
+
+ /* Now see which tokens are allowed for shifts in this state. For
+ them, record the shift as the thing to do. So shift is preferred
+ to reduce. */
+ FOR_EACH_SHIFT (trans, i)
+ {
+ symbol_number sym = TRANSITION_SYMBOL (trans, i);
+ state *shift_state = trans->states[i];
+
+ if (actrow[sym] != 0)
+ {
+ conflicted = true;
+ conflrow[sym] = 1;
+ }
+ actrow[sym] = state_number_as_int (shift_state->number);
+
+ /* Do not use any default reduction if there is a shift for
+ error */
+ if (sym == errtoken->number)
+ nodefault = true;
+ }
+
+ /* See which tokens are an explicit error in this state (due to
+ %nonassoc). For them, record ACTION_NUMBER_MINIMUM as the
+ action. */
+ for (i = 0; i < errp->num; i++)
+ {
+ symbol *sym = errp->symbols[i];
+ 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-reduction");
+ if (STRNEQ (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_reduction = reds->rules[0];
+ else
+ {
+ int max = 0;
+ for (i = 0; i < reds->num; i++)
+ {
+ int count = 0;
+ rule *r = reds->rules[i];
+ symbol_number j;
+
+ for (j = 0; j < ntokens; j++)
+ if (actrow[j] == rule_number_as_item_number (r->number))
+ count++;
+
+ if (count > max)
+ {
+ max = count;
+ default_reduction = r;
+ }
+ }
+
+ /* GLR parsers need space for conflict lists, so we can't
+ default conflicted entries. For non-conflicted entries
+ or as long as we are not building a GLR parser,
+ actions that match the default are replaced with zero,
+ which means "use the default". */
+
+ if (max > 0)
+ {
+ int j;
+ for (j = 0; j < ntokens; j++)
+ if (actrow[j]
+ == rule_number_as_item_number (default_reduction->number)
+ && ! (nondeterministic_parser && conflrow[j]))
+ actrow[j] = 0;
+ }
+ }
+ }
+
+ /* If have no default reduction, the default is an error.
+ So replace any action which says "error" with "use default". */
+
+ if (!default_reduction)
+ for (i = 0; i < ntokens; i++)
+ if (actrow[i] == ACTION_NUMBER_MINIMUM)
+ actrow[i] = 0;
+
+ if (conflicted)
+ conflict_row (s);
+
+ return default_reduction;
+}
+
+
+/*----------------------------------------.
+| Set FROMS, TOS, TALLY and WIDTH for S. |
+`----------------------------------------*/
+
+static void
+save_row (state_number s)
+{
+ symbol_number i;
+
+ /* Number of non default actions in S. */
+ size_t count = 0;
+ for (i = 0; i < ntokens; i++)
+ if (actrow[i] != 0)
+ count++;
+
+ if (count)
+ {
+ /* Allocate non defaulted actions. */
+ base_number *sp1 = froms[s] = xnmalloc (count, sizeof *sp1);
+ base_number *sp2 = tos[s] = xnmalloc (count, sizeof *sp2);
+ unsigned int *sp3 = conflict_tos[s] =
+ nondeterministic_parser ? xnmalloc (count, sizeof *sp3) : NULL;
+
+ /* Store non defaulted actions. */
+ for (i = 0; i < ntokens; i++)
+ if (actrow[i] != 0)
+ {
+ *sp1++ = i;
+ *sp2++ = actrow[i];
+ if (nondeterministic_parser)
+ *sp3++ = conflrow[i];
+ }
+
+ tally[s] = count;
+ width[s] = sp1[-1] - froms[s][0] + 1;
+ }
+}
+
+
+/*------------------------------------------------------------------.
+| Figure out the actions for the specified state, indexed by |
+| lookahead token type. |
+| |
+| The YYDEFACT table is output now. The detailed info is saved for |
+| putting into YYTABLE later. |
+`------------------------------------------------------------------*/
+
+static void
+token_actions (void)
+{
+ int nconflict = nondeterministic_parser ? conflicts_total_count () : 0;
+
+ yydefact = xnmalloc (nstates, sizeof *yydefact);
+
+ actrow = xnmalloc (ntokens, sizeof *actrow);
+ conflrow = xnmalloc (ntokens, sizeof *conflrow);
+
+ conflict_list = xnmalloc (1 + 2 * nconflict, sizeof *conflict_list);
+ conflict_list_free = 2 * nconflict;
+ conflict_list_cnt = 1;
+
+ /* Find the rules which are reduced. */
+ if (!nondeterministic_parser)
+ {
+ rule_number r;
+ for (r = 0; r < nrules; ++r)
+ rules[r].useful = false;
+ }
+
+ {
+ state_number i;
+ for (i = 0; i < nstates; ++i)
+ {
+ 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
+ really reduced, and which are not because of SR or RR
+ conflicts. */
+ if (!nondeterministic_parser)
+ {
+ symbol_number j;
+ for (j = 0; j < ntokens; ++j)
+ if (actrow[j] < 0 && actrow[j] != ACTION_NUMBER_MINIMUM)
+ rules[item_number_as_rule_number (actrow[j])].useful = true;
+ if (yydefact[i])
+ rules[yydefact[i] - 1].useful = true;
+ }
+ }
+ }
+ free (actrow);
+ free (conflrow);
+}
+
+
+/*------------------------------------------------------------------.
+| Compute FROMS[VECTOR], TOS[VECTOR], TALLY[VECTOR], WIDTH[VECTOR], |
+| i.e., the information related to non defaulted GOTO on the nterm |
+| SYM. |
+| |
+| DEFAULT_STATE is the principal destination on SYM, i.e., the |
+| default GOTO destination on SYM. |
+`------------------------------------------------------------------*/
+
+static void
+save_column (symbol_number sym, state_number default_state)
+{
+ goto_number i;
+ goto_number begin = goto_map[sym - ntokens];
+ goto_number end = goto_map[sym - ntokens + 1];
+
+ /* Number of non default GOTO. */
+ size_t count = 0;
+ for (i = begin; i < end; i++)
+ if (to_state[i] != default_state)
+ count++;
+
+ if (count)
+ {
+ /* Allocate room for non defaulted gotos. */
+ vector_number symno = symbol_number_to_vector_number (sym);
+ base_number *sp1 = froms[symno] = xnmalloc (count, sizeof *sp1);
+ base_number *sp2 = tos[symno] = xnmalloc (count, sizeof *sp2);
+
+ /* Store the state numbers of the non defaulted gotos. */
+ for (i = begin; i < end; i++)
+ if (to_state[i] != default_state)
+ {
+ *sp1++ = from_state[i];
+ *sp2++ = to_state[i];
+ }
+
+ tally[symno] = count;
+ width[symno] = sp1[-1] - froms[symno][0] + 1;
+ }
+}
+
+
+/*----------------------------------------------------------------.
+| The default state for SYM: the state which is 'the' most common |
+| GOTO destination on SYM (an nterm). |
+`----------------------------------------------------------------*/
+
+static state_number
+default_goto (symbol_number sym, size_t state_count[])
+{
+ goto_number begin = goto_map[sym - ntokens];
+ goto_number end = goto_map[sym - ntokens + 1];
+ state_number res = -1;
+
+ if (begin != end)
+ {
+ size_t max = 0;
+ goto_number i;
+ state_number s;
+
+ for (s = 0; s < nstates; s++)
+ state_count[s] = 0;
+
+ for (i = begin; i < end; i++)
+ state_count[to_state[i]]++;
+
+ for (s = 0; s < nstates; s++)
+ if (max < state_count[s])
+ {
+ max = state_count[s];
+ res = s;
+ }
+ }
+ return res;
+}
+
+
+/*-------------------------------------------------------------------.
+| Figure out what to do after reducing with each rule, depending on |
+| the saved state from before the beginning of parsing the data that |
+| matched this rule. |
+| |
+| The YYDEFGOTO table is output now. The detailed info is saved for |
+| putting into YYTABLE later. |
+`-------------------------------------------------------------------*/
+
+static void
+goto_actions (void)
+{
+ symbol_number i;
+ size_t *state_count = xnmalloc (nstates, sizeof *state_count);
+ yydefgoto = xnmalloc (nvars, sizeof *yydefgoto);
+
+ /* For a given nterm I, STATE_COUNT[S] is the number of times there
+ is a GOTO to S on I. */
+ for (i = ntokens; i < nsyms; ++i)
+ {
+ state_number default_state = default_goto (i, state_count);
+ save_column (i, default_state);
+ yydefgoto[i - ntokens] = default_state;
+ }
+ free (state_count);
+}
+
+
+/*------------------------------------------------------------------.
+| Compute ORDER, a reordering of vectors, in order to decide how to |
+| pack the actions and gotos information into yytable. |
+`------------------------------------------------------------------*/
+
+static void
+sort_actions (void)
+{
+ int i;
+
+ nentries = 0;
+
+ for (i = 0; i < nvectors; i++)
+ if (0 < tally[i])
+ {
+ int k;
+ size_t t = tally[i];
+ int w = width[i];
+ int j = nentries - 1;
+
+ while (0 <= j && width[order[j]] < w)
+ j--;
+
+ while (0 <= j && width[order[j]] == w && tally[order[j]] < t)
+ j--;
+
+ for (k = nentries - 1; k > j; k--)
+ order[k + 1] = order[k];
+
+ order[j + 1] = i;
+ nentries++;
+ }
+}
+
+
+/* If VECTOR is a state whose actions (reflected by FROMS, TOS, TALLY
+ and WIDTH of VECTOR) are common to a previous state, return this
+ state number.
+
+ In any other case, return -1. */
+
+static state_number
+matching_state (vector_number vector)
+{
+ vector_number i = order[vector];
+ /* If VECTOR is a nterm, return -1. */
+ if (i < nstates)
+ {
+ size_t t = tally[i];
+ int w = width[i];
+ int prev;
+
+ /* If VECTOR has GLR conflicts, return -1 */
+ if (conflict_tos[i] != NULL)
+ {
+ int j;
+ for (j = 0; j < t; j += 1)
+ if (conflict_tos[i][j] != 0)
+ return -1;
+ }
+
+ for (prev = vector - 1; 0 <= prev; prev--)
+ {
+ vector_number j = order[prev];
+ /* Given how ORDER was computed, if the WIDTH or TALLY is
+ different, there cannot be a matching state. */
+ if (width[j] != w || tally[j] != t)
+ return -1;
+ else
+ {
+ bool match = true;
+ int k;
+ for (k = 0; match && k < t; k++)
+ if (tos[j][k] != tos[i][k]
+ || froms[j][k] != froms[i][k]
+ || (conflict_tos[j] != NULL && conflict_tos[j][k] != 0))
+ match = false;
+ if (match)
+ return j;
+ }
+ }
+ }
+ return -1;
+}
+
+
+static base_number
+pack_vector (vector_number vector)
+{
+ base_number res;
+ vector_number i = order[vector];
+ size_t t = tally[i];
+ base_number *from = froms[i];
+ base_number *to = tos[i];
+ unsigned int *conflict_to = conflict_tos[i];
+
+ aver (t != 0);
+
+ for (res = lowzero - from[0]; ; res++)
+ {
+ bool ok = true;
+ aver (res < table_size);
+ {
+ int k;
+ for (k = 0; ok && k < t; k++)
+ {
+ int loc = res + state_number_as_int (from[k]);
+ if (table_size <= loc)
+ table_grow (loc);
+
+ if (table[loc] != 0)
+ ok = false;
+ }
+
+ if (ok)
+ for (k = 0; k < vector; k++)
+ if (pos[k] == res)
+ ok = false;
+ }
+
+ if (ok)
+ {
+ int loc;
+ int k;
+ for (k = 0; k < t; k++)
+ {
+ loc = res + state_number_as_int (from[k]);
+ table[loc] = to[k];
+ if (nondeterministic_parser && conflict_to != NULL)
+ conflict_table[loc] = conflict_to[k];
+ check[loc] = from[k];
+ }
+
+ while (table[lowzero] != 0)
+ lowzero++;
+
+ if (high < loc)
+ high = loc;
+
+ aver (BASE_MINIMUM <= res && res <= BASE_MAXIMUM);
+ return res;
+ }
+ }
+}
+
+
+/*-------------------------------------------------------------.
+| Remap the negative infinite in TAB from NINF to the greatest |
+| possible smallest value. Return it. |
+| |
+| In most case this allows us to use shorts instead of ints in |
+| parsers. |
+`-------------------------------------------------------------*/
+
+static base_number
+table_ninf_remap (base_number tab[], int size, base_number ninf)
+{
+ base_number res = 0;
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (tab[i] < res && tab[i] != ninf)
+ res = tab[i];
+
+ --res;
+
+ for (i = 0; i < size; i++)
+ if (tab[i] == ninf)
+ tab[i] = res;
+
+ return res;
+}
+
+static void
+pack_table (void)
+{
+ int i;
+
+ base = xnmalloc (nvectors, sizeof *base);
+ pos = xnmalloc (nentries, sizeof *pos);
+ table = xcalloc (table_size, sizeof *table);
+ conflict_table = xcalloc (table_size, sizeof *conflict_table);
+ check = xnmalloc (table_size, sizeof *check);
+
+ lowzero = 0;
+ high = 0;
+
+ for (i = 0; i < nvectors; i++)
+ base[i] = BASE_MINIMUM;
+
+ for (i = 0; i < table_size; i++)
+ check[i] = -1;
+
+ for (i = 0; i < nentries; i++)
+ {
+ state_number s = matching_state (i);
+ base_number place;
+
+ if (s < 0)
+ /* A new set of state actions, or a nonterminal. */
+ place = pack_vector (i);
+ else
+ /* Action of I were already coded for S. */
+ place = base[s];
+
+ pos[i] = place;
+ base[order[i]] = place;
+ }
+
+ /* Use the greatest possible negative infinites. */
+ base_ninf = table_ninf_remap (base, nvectors, BASE_MINIMUM);
+ table_ninf = table_ninf_remap (table, high + 1, ACTION_NUMBER_MINIMUM);
+
+ free (pos);
+}
+
+
+
+/*-----------------------------------------------------------------.
+| Compute and output yydefact, yydefgoto, yypact, yypgoto, yytable |
+| and yycheck. |
+`-----------------------------------------------------------------*/
+
+void
+tables_generate (void)
+{
+ int i;
+
+ /* This is a poor way to make sure the sizes are properly
+ correlated. In particular the signedness is not taken into
+ account. But it's not useless. */
+ verify (sizeof nstates <= sizeof nvectors
+ && sizeof nvars <= sizeof nvectors);
+
+ nvectors = state_number_as_int (nstates) + nvars;
+
+ froms = xcalloc (nvectors, sizeof *froms);
+ tos = xcalloc (nvectors, sizeof *tos);
+ conflict_tos = xcalloc (nvectors, sizeof *conflict_tos);
+ tally = xcalloc (nvectors, sizeof *tally);
+ width = xnmalloc (nvectors, sizeof *width);
+
+ token_actions ();
+
+ goto_actions ();
+ free (goto_map);
+ free (from_state);
+ free (to_state);
+
+ order = xcalloc (nvectors, sizeof *order);
+ sort_actions ();
+ pack_table ();
+ free (order);
+
+ free (tally);
+ free (width);
+
+ for (i = 0; i < nvectors; i++)
+ {
+ free (froms[i]);
+ free (tos[i]);
+ free (conflict_tos[i]);
+ }
+
+ free (froms);
+ free (tos);
+ free (conflict_tos);
+}
+
+
+/*-------------------------.
+| Free the parser tables. |
+`-------------------------*/
+
+void
+tables_free (void)
+{
+ free (base);
+ free (conflict_table);
+ free (conflict_list);
+ free (table);
+ free (check);
+ free (yydefgoto);
+ free (yydefact);
+}
diff --git a/contrib/tools/bison/src/tables.h b/contrib/tools/bison/src/tables.h
new file mode 100644
index 0000000000..c631584d6e
--- /dev/null
+++ b/contrib/tools/bison/src/tables.h
@@ -0,0 +1,141 @@
+/* Prepare the LALR and GLR parser tables.
+
+ Copyright (C) 2002, 2004, 2009-2013 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 TABLES_H_
+# define TABLES_H_
+
+# include "state.h"
+
+/* The parser tables consist of these tables.
+
+ YYTRANSLATE = vector mapping yylex's token numbers into bison's
+ token numbers.
+
+ YYTNAME = vector of string-names indexed by bison token number.
+
+ YYTOKNUM = vector of yylex token numbers corresponding to entries
+ in YYTNAME.
+
+ YYRLINE = vector of line-numbers of all rules. For yydebug
+ printouts.
+
+ YYRHS = vector of items of all rules. This is exactly what RITEMS
+ contains. For yydebug and for semantic parser.
+
+ YYPRHS[R] = index in YYRHS of first item for rule R.
+
+ YYR1[R] = symbol number of symbol that rule R derives.
+
+ YYR2[R] = number of symbols composing right hand side of rule R.
+
+ YYSTOS[S] = the symbol number of the symbol that leads to state S.
+
+ YYFINAL = the state number of the termination state.
+
+ YYTABLE = a vector filled with portions for different uses, found
+ 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
+ examine.
+
+ Suppose that the portion of YYTABLE starts at index P and the index
+ to be examined within the portion is I. Then if YYCHECK[P+I] != I,
+ I is outside the bounds of what is actually allocated, and the
+ default (from YYDEFACT or YYDEFGOTO) should be used. Otherwise,
+ YYTABLE[P+I] should be used.
+
+ 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.
+
+ 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;
+
+typedef int base_number;
+extern base_number *base;
+/* A distinguished value of BASE, negative infinite. During the
+ computation equals to BASE_MINIMUM, later mapped to BASE_NINF to
+ keep parser tables small. */
+extern base_number base_ninf;
+
+extern unsigned int *conflict_table;
+extern unsigned int *conflict_list;
+extern int conflict_list_cnt;
+
+extern base_number *table;
+extern base_number *check;
+/* The value used in TABLE to denote explicit syntax errors
+ (%nonassoc), a negative infinite. */
+extern base_number table_ninf;
+
+extern state_number *yydefgoto;
+extern rule_number *yydefact;
+extern int high;
+
+void tables_generate (void);
+void tables_free (void);
+
+#endif /* !TABLES_H_ */
diff --git a/contrib/tools/bison/src/uniqstr.c b/contrib/tools/bison/src/uniqstr.c
new file mode 100644
index 0000000000..4a62e989c9
--- /dev/null
+++ b/contrib/tools/bison/src/uniqstr.c
@@ -0,0 +1,184 @@
+/* Keep a unique copy of strings.
+
+ Copyright (C) 2002-2005, 2009-2013 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 <error.h>
+#include <hash.h>
+#include <quotearg.h>
+#include <stdarg.h>
+#include <xmalloca.h>
+
+#include "uniqstr.h"
+
+/*-----------------------.
+| A uniqstr hash table. |
+`-----------------------*/
+
+/* Initial capacity of uniqstr hash table. */
+#define HT_INITIAL_CAPACITY 257
+
+static struct hash_table *uniqstrs_table = NULL;
+
+/*-------------------------------------.
+| Create the uniqstr for S if needed. |
+`-------------------------------------*/
+
+uniqstr
+uniqstr_new (char const *str)
+{
+ uniqstr res = (uniqstr) hash_lookup (uniqstrs_table, str);
+ if (!res)
+ {
+ /* First insertion in the hash. */
+ res = xstrdup (str);
+ if (!hash_insert (uniqstrs_table, res))
+ xalloc_die ();
+ }
+ return res;
+}
+
+uniqstr
+uniqstr_vsprintf (char const *format, ...)
+{
+ va_list args;
+ size_t length;
+ char* res;
+ uniqstr str;
+ va_start (args, format);
+ length = vsnprintf (NULL, 0, format, args);
+ va_end (args);
+
+ res = xmalloca(length + 1);
+ va_start (args, format);
+ vsprintf (res, format, args);
+ va_end (args);
+ str = uniqstr_new (res);
+ freea(res);
+ return str;
+}
+
+/*------------------------------.
+| Abort if S is not a uniqstr. |
+`------------------------------*/
+
+void
+uniqstr_assert (char const *str)
+{
+ if (!hash_lookup (uniqstrs_table, str))
+ {
+ error (0, 0,
+ "not a uniqstr: %s", quotearg (str));
+ abort ();
+ }
+}
+
+
+/*--------------------.
+| Print the uniqstr. |
+`--------------------*/
+
+static inline bool
+uniqstr_print (uniqstr ustr)
+{
+ fprintf (stderr, "%s\n", ustr);
+ return true;
+}
+
+static bool
+uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED)
+{
+ return uniqstr_print (ustr);
+}
+
+
+int
+uniqstr_cmp (uniqstr l, uniqstr r)
+{
+ return (l == r ? 0
+ : !l ? -1
+ : !r ? +1
+ : strcmp (l, r));
+}
+
+
+/*-----------------------.
+| A uniqstr hash table. |
+`-----------------------*/
+
+static bool
+hash_compare_uniqstr (void const *m1, void const *m2)
+{
+ return STREQ (m1, m2);
+}
+
+static size_t
+hash_uniqstr (void const *m, size_t tablesize)
+{
+ return hash_string (m, tablesize);
+}
+
+
+/*----------------------------.
+| Create the uniqstrs table. |
+`----------------------------*/
+
+void
+uniqstrs_new (void)
+{
+ uniqstrs_table = hash_initialize (HT_INITIAL_CAPACITY,
+ NULL,
+ hash_uniqstr,
+ hash_compare_uniqstr,
+ free);
+}
+
+
+/*-------------------------------------.
+| Perform a task on all the uniqstrs. |
+`-------------------------------------*/
+
+static void
+uniqstrs_do (Hash_processor processor, void *processor_data)
+{
+ hash_do_for_each (uniqstrs_table, processor, processor_data);
+}
+
+
+/*-----------------.
+| Print them all. |
+`-----------------*/
+
+void
+uniqstrs_print (void)
+{
+ uniqstrs_do (uniqstr_print_processor, NULL);
+}
+
+
+/*--------------------.
+| Free the uniqstrs. |
+`--------------------*/
+
+void
+uniqstrs_free (void)
+{
+ hash_free (uniqstrs_table);
+}
diff --git a/contrib/tools/bison/src/uniqstr.h b/contrib/tools/bison/src/uniqstr.h
new file mode 100644
index 0000000000..f8e59ab24f
--- /dev/null
+++ b/contrib/tools/bison/src/uniqstr.h
@@ -0,0 +1,103 @@
+/* Keeping a unique copy of strings.
+
+ Copyright (C) 2002-2003, 2008-2013 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 UNIQSTR_H_
+# define UNIQSTR_H_
+
+#include "system.h"
+
+/*-----------------------------------------.
+| Pointers to unique copies of C strings. |
+`-----------------------------------------*/
+
+typedef char const *uniqstr;
+
+/* 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)))
+
+/* Compare two uniqstr a la strcmp: negative for <, nul for =, and
+ positive for >. Undefined order, relies on addresses. */
+int uniqstr_cmp (uniqstr u1, uniqstr u2);
+
+/* Die if STR is not a uniqstr. */
+void uniqstr_assert (char const *str);
+
+#if 0
+ // msvc still does not support __VA_ARGS__
+/*----------------.
+| 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
+/*--------------------.
+| Table of uniqstrs. |
+`--------------------*/
+
+/* Create the string table. */
+void uniqstrs_new (void);
+
+/* Free all the memory allocated for symbols. */
+void uniqstrs_free (void);
+
+/* Report them all. */
+void uniqstrs_print (void);
+
+#endif /* ! defined UNIQSTR_H_ */