aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/bison/data/skeletons
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-07-08 15:54:05 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-07-08 15:54:05 +0000
commitfc7be18c76af2e700641f3598c4856baeef1428e (patch)
tree11dbca45eb321c3a4dd08b12152acc6ef5dd3fa9 /contrib/tools/bison/data/skeletons
parentec0e7ed6da6fb317741fd8468602949a1362eca5 (diff)
parentc92cb9d3a19331916f0c274d80e67f02a62caa9b (diff)
downloadydb-fc7be18c76af2e700641f3598c4856baeef1428e.tar.gz
Merge branch 'rightlib' into mergelibs-240708-1553
Diffstat (limited to 'contrib/tools/bison/data/skeletons')
-rw-r--r--contrib/tools/bison/data/skeletons/README-D.txt60
-rw-r--r--contrib/tools/bison/data/skeletons/bison.m41111
-rw-r--r--contrib/tools/bison/data/skeletons/c++-skel.m427
-rw-r--r--contrib/tools/bison/data/skeletons/c++.m4663
-rw-r--r--contrib/tools/bison/data/skeletons/c-like.m466
-rw-r--r--contrib/tools/bison/data/skeletons/c-skel.m427
-rw-r--r--contrib/tools/bison/data/skeletons/c.m4883
-rw-r--r--contrib/tools/bison/data/skeletons/glr.cc369
-rw-r--r--contrib/tools/bison/data/skeletons/lalr1.cc1247
-rw-r--r--contrib/tools/bison/data/skeletons/location.cc363
-rw-r--r--contrib/tools/bison/data/skeletons/stack.hh163
-rw-r--r--contrib/tools/bison/data/skeletons/variant.hh453
-rw-r--r--contrib/tools/bison/data/skeletons/yacc.c1927
13 files changed, 7359 insertions, 0 deletions
diff --git a/contrib/tools/bison/data/skeletons/README-D.txt b/contrib/tools/bison/data/skeletons/README-D.txt
new file mode 100644
index 0000000000..214e309923
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/README-D.txt
@@ -0,0 +1,60 @@
+Some usage notes for the D Parser:
+
+- it is a port of the Java parser, so interface is very similar.
+
+- the lexer class needs to implement the interface 'Lexer' (similar to
+ java). It typically (depending on options) looks like this:
+
+public interface Lexer
+{
+ /**
+ * Method to retrieve the beginning position of the last scanned token.
+ * @return the position at which the last scanned token starts. */
+ @property YYPosition startPos ();
+
+ /**
+ * Method to retrieve the ending position of the last scanned token.
+ * @return the first position beyond the last scanned token. */
+ @property YYPosition endPos ();
+
+ /**
+ * Method to retrieve the semantic value of the last scanned token.
+ * @return the semantic value of the last scanned token. */
+ @property YYSemanticType semanticVal ();
+
+ /**
+ * Entry point for the scanner. Returns the token identifier corresponding
+ * to the next token and prepares to return the semantic value
+ * and beginning/ending positions of the token.
+ * @return the token identifier corresponding to the next token. */
+ YYTokenType yylex ();
+
+ /**
+ * Entry point for error reporting. Emits an error
+ * referring to the given location in a user-defined way.
+ *
+ * @param loc The location of the element to which the
+ * error message is related
+ * @param s The string for the error message. */
+ void yyerror (YYLocation loc, string s);
+}
+
+- semantic types are handled by D usions (same as for C/C++ parsers)
+
+- the following (non-standard) %defines are supported:
+
+ %define package "<package_name>"
+ %define api.parser.class "my_class_name>"
+ %define position_type "my_position_type"
+ %define location_type "my_location_type"
+
+- the following declarations basically work like in C/C++:
+
+ %locations
+ %error-verbose
+ %parse-param
+ %initial-action
+ %code
+ %union
+
+- %destructor is not yet supported
diff --git a/contrib/tools/bison/data/skeletons/bison.m4 b/contrib/tools/bison/data/skeletons/bison.m4
new file mode 100644
index 0000000000..e3591875c0
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/bison.m4
@@ -0,0 +1,1111 @@
+ -*- Autoconf -*-
+
+# Language-independent M4 Macros for Bison.
+
+# Copyright (C) 2002, 2004-2015, 2018-2019 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/>.
+
+
+## ---------------- ##
+## Identification. ##
+## ---------------- ##
+
+# b4_generated_by
+# ---------------
+m4_define([b4_generated_by],
+[b4_comment([A Bison parser, made by GNU Bison b4_version.])
+])
+
+# b4_copyright(TITLE, [YEARS])
+# ----------------------------
+# If YEARS are not defined, use b4_copyright_years.
+m4_define([b4_copyright],
+[b4_generated_by
+b4_comment([$1
+
+]m4_dquote(m4_text_wrap([Copyright (C)
+]m4_ifval([$2], [[$2]], [m4_defn([b4_copyright_years])])[
+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/>.])
+
+b4_comment([As a special exception, you may create a larger work that contains
+part or all of the Bison parser skeleton and distribute that work
+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.])
+])
+
+
+# b4_disclaimer
+# -------------
+# Issue a warning about private implementation details.
+m4_define([b4_disclaimer],
+[b4_comment([Undocumented macros, especially those whose name start with YY_,
+are private implementation details. Do not rely on them.])
+])
+
+
+
+# b4_required_version_if(VERSION, IF_NEWER, IF_OLDER)
+# ---------------------------------------------------
+# If the version %require'd by the user is VERSION (or newer) expand
+# IF_NEWER, otherwise IF_OLDER. VERSION should be an integer, e.g.,
+# 302 for 3.2.
+m4_define([b4_required_version_if],
+[m4_if(m4_eval($1 <= b4_required_version),
+ [1], [$2], [$3])])
+
+
+## -------- ##
+## Output. ##
+## -------- ##
+
+# b4_output_begin(FILE1, FILE2)
+# -----------------------------
+# Enable output, i.e., send to diversion 0, expand after "#", and
+# generate the tag to output into FILE. Must be followed by EOL.
+# FILE is FILE1 concatenated to FILE2. FILE2 can be empty, or be
+# absolute: do the right thing.
+m4_define([b4_output_begin],
+[m4_changecom()
+m4_divert_push(0)dnl
+@output(m4_unquote([$1])@,m4_unquote([$2])@)@dnl
+])
+
+
+# b4_output_end
+# -------------
+# Output nothing, restore # as comment character (no expansions after #).
+m4_define([b4_output_end],
+[m4_divert_pop(0)
+m4_changecom([#])
+])
+
+
+# b4_divert_kill(CODE)
+# --------------------
+# Expand CODE for its side effects, discard its output.
+m4_define([b4_divert_kill],
+[m4_divert_text([KILL], [$1])])
+
+
+# b4_define_silent(MACRO, CODE)
+# -----------------------------
+# Same as m4_define, but throw away the expansion of CODE.
+m4_define([b4_define_silent],
+[m4_define([$1], [b4_divert_kill([$2])])])
+
+
+## ---------------- ##
+## Error handling. ##
+## ---------------- ##
+
+# The following error handling macros print error directives that should not
+# become arguments of other macro invocations since they would likely then be
+# mangled. Thus, they print to stdout directly.
+
+# b4_cat(TEXT)
+# ------------
+# Write TEXT to stdout. Precede the final newline with an @ so that it's
+# escaped. For example:
+#
+# b4_cat([[@complain(invalid input@)]])
+m4_define([b4_cat],
+[m4_syscmd([cat <<'_m4eof'
+]m4_bpatsubst(m4_dquote($1), [_m4eof], [_m4@`eof])[@
+_m4eof
+])dnl
+m4_if(m4_sysval, [0], [], [m4_fatal([$0: cannot write to stdout])])])
+
+# b4_error(KIND, START, END, FORMAT, [ARG1], [ARG2], ...)
+# -------------------------------------------------------
+# Write @KIND(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
+#
+# For example:
+#
+# b4_error([[complain]], [[input.y:2.3]], [[input.y:5.4]],
+# [[invalid %s]], [[foo]])
+m4_define([b4_error],
+[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
+[m4_if([$#], [4], [],
+ [m4_foreach([b4_arg],
+ m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
+ [[@,]b4_arg])])[@)]])])
+
+# b4_warn(FORMAT, [ARG1], [ARG2], ...)
+# ------------------------------------
+# Write @warn(FORMAT@,ARG1@,ARG2@,...@) to stdout.
+#
+# For example:
+#
+# b4_warn([[invalid value for '%s': %s]], [[foo]], [[3]])
+#
+# As a simple test suite, this:
+#
+# m4_divert(-1)
+# m4_define([asdf], [ASDF])
+# m4_define([fsa], [FSA])
+# m4_define([fdsa], [FDSA])
+# b4_warn_at([[[asdf), asdf]]], [[[fsa), fsa]]], [[[fdsa), fdsa]]])
+# b4_warn_at([[asdf), asdf]], [[fsa), fsa]], [[fdsa), fdsa]])
+# b4_warn_at()
+# b4_warn_at(1)
+# b4_warn_at(1, 2)
+#
+# Should produce this without newlines:
+#
+# @warn_at([asdf), asdf]@,@,@,[fsa), fsa]@,[fdsa), fdsa]@)
+# @warn(asdf), asdf@,@,@,fsa), fsa@,fdsa), fdsa@)
+# @warn(@)
+# @warn(1@)
+# @warn(1@,2@)
+m4_define([b4_warn],
+[b4_error([[warn]], [], [], $@)])
+
+# b4_warn_at(START, END, FORMAT, [ARG1], [ARG2], ...)
+# ---------------------------------------------------
+# Write @warn(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
+#
+# For example:
+#
+# b4_warn_at([[input.y:2.3]], [[input.y:5.4]], [[invalid %s]], [[foo]])
+m4_define([b4_warn_at],
+[b4_error([[warn]], $@)])
+
+# b4_complain(FORMAT, [ARG1], [ARG2], ...)
+# ----------------------------------------
+# Bounce to b4_complain_at.
+#
+# See b4_warn example.
+m4_define([b4_complain],
+[b4_error([[complain]], [], [], $@)])
+
+# b4_complain_at(START, END, FORMAT, [ARG1], [ARG2], ...)
+# -------------------------------------------------------
+# Write @complain(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
+#
+# See b4_warn_at example.
+m4_define([b4_complain_at],
+[b4_error([[complain]], $@)])
+
+# b4_fatal(FORMAT, [ARG1], [ARG2], ...)
+# -------------------------------------
+# Bounce to b4_fatal_at.
+#
+# See b4_warn example.
+m4_define([b4_fatal],
+[b4_error([[fatal]], [], [], $@)dnl
+m4_exit(1)])
+
+# b4_fatal_at(START, END, FORMAT, [ARG1], [ARG2], ...)
+# ----------------------------------------------------
+# Write @fatal(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout and exit.
+#
+# See b4_warn_at example.
+m4_define([b4_fatal_at],
+[b4_error([[fatal]], $@)dnl
+m4_exit(1)])
+
+
+## ------------ ##
+## Data Types. ##
+## ------------ ##
+
+# b4_ints_in(INT1, INT2, LOW, HIGH)
+# ---------------------------------
+# Return 1 iff both INT1 and INT2 are in [LOW, HIGH], 0 otherwise.
+m4_define([b4_ints_in],
+[m4_eval([$3 <= $1 && $1 <= $4 && $3 <= $2 && $2 <= $4])])
+
+
+# b4_subtract(LHS, RHS)
+# ---------------------
+# Evaluate LHS - RHS if they are integer literals, otherwise expand
+# to (LHS) - (RHS).
+m4_define([b4_subtract],
+[m4_bmatch([$1$2], [^[0123456789]*$],
+ [m4_eval([$1 - $2])],
+ [($1) - ($2)])])
+
+# b4_join(ARG1, ...)
+# _b4_join(ARG1, ...)
+# -------------------
+# Join with comma, skipping empty arguments.
+# b4_join calls itself recursively until it sees the first non-empty
+# argument, then calls _b4_join (i.e., `_$0`) which prepends each
+# non-empty argument with a comma.
+m4_define([b4_join],
+[m4_if([$#$1],
+ [1], [],
+ [m4_ifval([$1],
+ [$1[]_$0(m4_shift($@))],
+ [$0(m4_shift($@))])])])
+
+# _b4_join(ARGS1, ...)
+# --------------------
+m4_define([_b4_join],
+[m4_if([$#$1],
+ [1], [],
+ [m4_ifval([$1], [, $1])[]$0(m4_shift($@))])])
+
+
+
+
+# b4_integral_parser_tables_map(MACRO)
+# -------------------------------------
+# Map MACRO on all the integral tables. MACRO is expected to have
+# the signature MACRO(TABLE-NAME, CONTENT, COMMENT).
+m4_define([b4_integral_parser_tables_map],
+[$1([pact], [b4_pact],
+ [[YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+STATE-NUM.]])
+
+$1([defact], [b4_defact],
+ [[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.]])
+
+$1([pgoto], [b4_pgoto], [[YYPGOTO[NTERM-NUM].]])
+
+$1([defgoto], [b4_defgoto], [[YYDEFGOTO[NTERM-NUM].]])
+
+$1([table], [b4_table],
+ [[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.]])
+
+$1([check], [b4_check])
+
+$1([stos], [b4_stos],
+ [[YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+symbol of state STATE-NUM.]])
+
+$1([r1], [b4_r1],
+ [[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]])
+
+$1([r2], [b4_r2],
+ [[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]])
+])
+
+
+# b4_parser_tables_declare
+# b4_parser_tables_define
+# ------------------------
+# Define/declare the (deterministic) parser tables.
+m4_define([b4_parser_tables_declare],
+[b4_integral_parser_tables_map([b4_integral_parser_table_declare])])
+
+m4_define([b4_parser_tables_define],
+[b4_integral_parser_tables_map([b4_integral_parser_table_define])])
+
+
+
+## ------------------ ##
+## Decoding options. ##
+## ------------------ ##
+
+# b4_flag_if(FLAG, IF-TRUE, IF-FALSE)
+# -----------------------------------
+# Run IF-TRUE if b4_FLAG_flag is 1, IF-FALSE if FLAG is 0, otherwise fail.
+m4_define([b4_flag_if],
+[m4_case(b4_$1_flag,
+ [0], [$3],
+ [1], [$2],
+ [m4_fatal([invalid $1 value: ]b4_$1_flag)])])
+
+
+# b4_define_flag_if(FLAG)
+# -----------------------
+# Define "b4_FLAG_if(IF-TRUE, IF-FALSE)" that depends on the
+# value of the Boolean FLAG.
+m4_define([b4_define_flag_if],
+[_b4_define_flag_if($[1], $[2], [$1])])
+
+# _b4_define_flag_if($1, $2, FLAG)
+# --------------------------------
+# Work around the impossibility to define macros inside macros,
+# because issuing '[$1]' is not possible in M4. GNU M4 should provide
+# $$1 a la M5/TeX.
+m4_define([_b4_define_flag_if],
+[m4_if([$1$2], $[1]$[2], [],
+ [m4_fatal([$0: Invalid arguments: $@])])dnl
+m4_define([b4_$3_if],
+ [b4_flag_if([$3], [$1], [$2])])])
+
+
+# b4_FLAG_if(IF-TRUE, IF-FALSE)
+# -----------------------------
+# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
+b4_define_flag_if([defines]) # Whether headers are requested.
+b4_define_flag_if([glr]) # Whether a GLR parser is requested.
+b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
+b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
+b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
+
+
+# b4_glr_cc_if([IF-TRUE], [IF-FALSE])
+# -----------------------------------
+m4_define([b4_glr_cc_if],
+ [m4_if(b4_skeleton, ["glr.cc"], $@)])
+
+
+## --------- ##
+## Symbols. ##
+## --------- ##
+
+# For a description of the Symbol handling, see README.
+#
+# The following macros provide access to symbol related values.
+
+# __b4_symbol(NUM, FIELD)
+# -----------------------
+# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
+# undefined.
+m4_define([__b4_symbol],
+[m4_indir([b4_symbol($1, $2)])])
+
+
+# _b4_symbol(NUM, FIELD)
+# ----------------------
+# Recover a FIELD about symbol #NUM (or "orig NUM"). Fails if
+# undefined.
+m4_define([_b4_symbol],
+[m4_ifdef([b4_symbol($1, number)],
+ [__b4_symbol(m4_indir([b4_symbol($1, number)]), $2)],
+ [__b4_symbol([$1], [$2])])])
+
+
+
+# b4_symbol(NUM, FIELD)
+# ---------------------
+# Recover a FIELD about symbol #NUM (or "orig NUM"). Fails if
+# undefined. If FIELD = id, prepend the token prefix.
+m4_define([b4_symbol],
+[m4_case([$2],
+ [id], [m4_do([b4_percent_define_get([api.token.prefix])],
+ [_b4_symbol([$1], [id])])],
+ [_b4_symbol($@)])])
+
+
+# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
+# -------------------------------------------
+# If FIELD about symbol #NUM is 1 expand IF-TRUE, if is 0, expand IF-FALSE.
+# Otherwise an error.
+m4_define([b4_symbol_if],
+[m4_case(b4_symbol([$1], [$2]),
+ [1], [$3],
+ [0], [$4],
+ [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])])
+
+
+# b4_symbol_tag_comment(SYMBOL-NUM)
+# ---------------------------------
+# Issue a comment giving the tag of symbol NUM.
+m4_define([b4_symbol_tag_comment],
+[b4_comment([b4_symbol([$1], [tag])])
+])
+
+
+# b4_symbol_action_location(SYMBOL-NUM, KIND)
+# -------------------------------------------
+# Report the location of the KIND action as FILE:LINE.
+m4_define([b4_symbol_action_location],
+[b4_symbol([$1], [$2_file]):b4_syncline([b4_symbol([$1], [$2_line])])])
+
+
+# b4_symbol_action(SYMBOL-NUM, KIND)
+# ----------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[b4_dollar_pushdef([(*yyvaluep)],
+ [$1],
+ [],
+ [(*yylocationp)])dnl
+ _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
+ b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])
+ break;
+
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_symbol_destructor(SYMBOL-NUM)
+# b4_symbol_printer(SYMBOL-NUM)
+# --------------------------------
+m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
+m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])])
+
+
+# b4_symbol_actions(KIND, [TYPE = yytype])
+# ----------------------------------------
+# Emit the symbol actions for KIND ("printer" or "destructor").
+# Dispatch on TYPE.
+m4_define([b4_symbol_actions],
+[m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl
+m4_ifval(m4_defn([b4_actions_]),
+[switch (m4_default([$2], [yytype]))
+ {
+m4_defn([b4_actions_])[]dnl
+ default:
+ break;
+ }dnl
+],
+[YYUSE (m4_default([$2], [yytype]));])dnl
+m4_popdef([b4_actions_])dnl
+])
+
+# _b4_symbol_case(SYMBOL-NUM)
+# ---------------------------
+# Issue a "case NUM" for SYMBOL-NUM. Ends with its EOL to make it
+# easier to use with m4_map, but then, use []dnl to suppress the last
+# one.
+m4_define([_b4_symbol_case],
+[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])])
+])
+
+
+# b4_symbol_foreach(MACRO)
+# ------------------------
+# Invoke MACRO(SYMBOL-NUM) for each SYMBOL-NUM.
+m4_define([b4_symbol_foreach],
+ [m4_map([$1], m4_defn([b4_symbol_numbers]))])
+
+# b4_symbol_map(MACRO)
+# --------------------
+# Return a list (possibly empty elements) of MACRO invoked for each
+# SYMBOL-NUM.
+m4_define([b4_symbol_map],
+[m4_map_args_sep([$1(], [)], [,], b4_symbol_numbers)])
+
+
+# b4_token_visible_if(NUM, IF-TRUE, IF-FALSE)
+# -------------------------------------------
+# Whether NUM denotes a token that has an exported definition (i.e.,
+# shows in enum yytokentype).
+m4_define([b4_token_visible_if],
+[b4_symbol_if([$1], [is_token],
+ [b4_symbol_if([$1], [has_id], [$2], [$3])],
+ [$3])])
+
+# b4_token_has_definition(NUM)
+# ----------------------------
+# 1 if NUM is visible, nothing otherwise.
+m4_define([b4_token_has_definition],
+[b4_token_visible_if([$1], [1])])
+
+# b4_any_token_visible_if([IF-TRUE], [IF-FALSE])
+# ----------------------------------------------
+# Whether there is a token that needs to be defined.
+m4_define([b4_any_token_visible_if],
+[m4_ifval(b4_symbol_foreach([b4_token_has_definition]),
+ [$1], [$2])])
+
+
+# b4_token_format(FORMAT, NUM)
+# ----------------------------
+m4_define([b4_token_format],
+[b4_token_visible_if([$2],
+[m4_quote(m4_format([$1],
+ [b4_symbol([$2], [id])],
+ [b4_symbol([$2], [user_number])]))])])
+
+
+## ------- ##
+## Types. ##
+## ------- ##
+
+# _b4_type_action(NUMS)
+# ---------------------
+# Run actions for the symbol NUMS that all have the same type-name.
+# Skip NUMS that have no type-name.
+#
+# To specify the action to run, define b4_dollar_dollar(SYMBOL-NUM,
+# TAG, TYPE).
+m4_define([_b4_type_action],
+[b4_symbol_if([$1], [has_type],
+[m4_map([ _b4_symbol_case], [$@])[]dnl
+ b4_dollar_dollar([b4_symbol([$1], [number])],
+ [b4_symbol([$1], [tag])],
+ [b4_symbol([$1], [type])]);
+ break;
+
+])])
+
+# b4_type_foreach(MACRO)
+# ----------------------
+# Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set.
+m4_define([b4_type_foreach],
+ [m4_map([$1], m4_defn([b4_type_names]))])
+
+
+
+## ----------- ##
+## Synclines. ##
+## ----------- ##
+
+# b4_basename(NAME)
+# -----------------
+# Similar to POSIX basename; the differences don't matter here.
+# Beware that NAME is not evaluated.
+m4_define([b4_basename],
+[m4_bpatsubst([$1], [^.*/\([^/]+\)/*$], [\1])])
+
+
+# b4_syncline(LINE, FILE)
+# -----------------------
+m4_define([b4_syncline],
+[b4_flag_if([synclines],
+[b4_sync_start([$1], [$2]) b4_sync_end([__line__],
+ [b4_basename(m4_quote(__file__))])[]dnl
+])])
+
+# b4_sync_start(LINE, FILE)
+# -----------------------
+# Syncline for the new place. Typically a directive for the compiler.
+m4_define([b4_sync_start], [b4_comment([$2:$1])])
+
+# b4_sync_end(LINE, FILE)
+# -----------------------
+# Syncline for the current place, which ends. Typically a comment
+# left for the reader.
+m4_define([b4_sync_end], [b4_comment([$2:$1])])
+
+
+# b4_user_code(USER-CODE)
+# -----------------------
+# Emit code from the user, ending it with synclines.
+m4_define([b4_user_code],
+[$1
+b4_syncline([@oline@], [@ofile@])])
+
+
+# b4_define_user_code(MACRO, COMMENT)
+# -----------------------------------
+# From b4_MACRO, if defined, build b4_user_MACRO that includes the synclines.
+m4_define([b4_define_user_code],
+[m4_define([b4_user_$1],
+ [m4_ifdef([b4_$1],
+ [m4_ifval([$2],
+ [b4_comment([$2])
+])b4_user_code([b4_$1])])])])
+
+# b4_user_actions
+# b4_user_initial_action
+# b4_user_post_prologue
+# b4_user_pre_prologue
+# b4_user_union_members
+# ----------------------
+# Macros that issue user code, ending with synclines.
+b4_define_user_code([actions])
+b4_define_user_code([initial_action], [User initialization code.])
+b4_define_user_code([post_prologue], [Second part of user prologue.])
+b4_define_user_code([pre_prologue], [First part of user prologue.])
+b4_define_user_code([union_members])
+
+
+# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE)
+# -----------------------------------------------------
+# Complain if any name of type WHAT is used by the user (as recorded in
+# USER-LIST) but is not used by Bison (as recorded by macros in the
+# namespace BISON-NAMESPACE).
+#
+# USER-LIST must expand to a list specifying all user occurrences of all names
+# of type WHAT. Each item in the list must be a triplet specifying one
+# occurrence: name, start boundary, and end boundary. Empty string names are
+# fine. An empty list is fine.
+#
+# For example, to define b4_foo_user_names to be used for USER-LIST with three
+# name occurrences and with correct quoting:
+#
+# m4_define([b4_foo_user_names],
+# [[[[[[bar]], [[parser.y:1.7]], [[parser.y:1.16]]]],
+# [[[[bar]], [[parser.y:5.7]], [[parser.y:5.16]]]],
+# [[[[baz]], [[parser.y:8.7]], [[parser.y:8.16]]]]]])
+#
+# The macro BISON-NAMESPACE(bar) must be defined iff the name bar of type WHAT
+# is used by Bison (in the front-end or in the skeleton). Empty string names
+# are fine, but it would be ugly for Bison to actually use one.
+#
+# For example, to use b4_foo_bison_names for BISON-NAMESPACE and define that
+# the names bar and baz are used by Bison:
+#
+# m4_define([b4_foo_bison_names(bar)])
+# m4_define([b4_foo_bison_names(baz)])
+#
+# To invoke b4_check_user_names with TYPE foo, with USER-LIST
+# b4_foo_user_names, with BISON-NAMESPACE b4_foo_bison_names, and with correct
+# quoting:
+#
+# b4_check_user_names([[foo]], [b4_foo_user_names],
+# [[b4_foo_bison_names]])
+m4_define([b4_check_user_names],
+[m4_foreach([b4_occurrence], $2,
+[m4_pushdef([b4_occurrence], b4_occurrence)dnl
+m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
+m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
+m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
+m4_ifndef($3[(]m4_quote(b4_user_name)[)],
+ [b4_complain_at([b4_start], [b4_end],
+ [[%s '%s' is not used]],
+ [$1], [b4_user_name])])[]dnl
+m4_popdef([b4_occurrence])dnl
+m4_popdef([b4_user_name])dnl
+m4_popdef([b4_start])dnl
+m4_popdef([b4_end])dnl
+])])
+
+
+
+## --------------------- ##
+## b4_percent_define_*. ##
+## --------------------- ##
+
+
+# b4_percent_define_use(VARIABLE)
+# -------------------------------
+# Declare that VARIABLE was used.
+m4_define([b4_percent_define_use],
+[m4_define([b4_percent_define_bison_variables(]$1[)])dnl
+])
+
+# b4_percent_define_get(VARIABLE, [DEFAULT])
+# ------------------------------------------
+# Mimic muscle_percent_define_get in ../src/muscle-tab.h. That is, if
+# the %define variable VARIABLE is defined, emit its value. Contrary
+# to its C counterpart, return DEFAULT otherwise. Also, record
+# Bison's usage of VARIABLE by defining
+# b4_percent_define_bison_variables(VARIABLE).
+#
+# For example:
+#
+# b4_percent_define_get([[foo]])
+m4_define([b4_percent_define_get],
+[b4_percent_define_use([$1])dnl
+_b4_percent_define_ifdef([$1],
+ [m4_indir([b4_percent_define(]$1[)])],
+ [$2])])
+
+# b4_percent_define_get_loc(VARIABLE)
+# -----------------------------------
+# Mimic muscle_percent_define_get_loc in ../src/muscle-tab.h exactly. That is,
+# if the %define variable VARIABLE is undefined, complain fatally since that's
+# a Bison or skeleton error. Otherwise, return its definition location in a
+# form appropriate for the first two arguments of b4_warn_at, b4_complain_at, or
+# b4_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.
+#
+# For example:
+#
+# b4_complain_at(b4_percent_define_get_loc([[foo]]), [[invalid foo]])
+m4_define([b4_percent_define_get_loc],
+[m4_ifdef([b4_percent_define_loc(]$1[)],
+ [m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl
+b4_loc[]dnl
+m4_popdef([b4_loc])],
+ [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
+
+# b4_percent_define_get_kind(VARIABLE)
+# ------------------------------------
+# Get the kind (code, keyword, string) of VARIABLE, i.e., how its
+# value was defined (braces, not delimiters, quotes).
+#
+# If the %define variable VARIABLE is undefined, complain fatally
+# since that's a Bison or skeleton error. 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.
+m4_define([b4_percent_define_get_kind],
+[m4_ifdef([b4_percent_define_kind(]$1[)],
+ [m4_indir([b4_percent_define_kind(]$1[)])],
+ [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
+
+# b4_percent_define_get_syncline(VARIABLE)
+# ----------------------------------------
+# Mimic muscle_percent_define_get_syncline in ../src/muscle-tab.h exactly.
+# That is, if the %define variable VARIABLE is undefined, complain fatally
+# since that's a Bison or skeleton 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.
+#
+# For example:
+#
+# b4_percent_define_get_syncline([[foo]])
+m4_define([b4_percent_define_get_syncline],
+[m4_ifdef([b4_percent_define_syncline(]$1[)],
+ [m4_indir([b4_percent_define_syncline(]$1[)])],
+ [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
+
+# _b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE])
+# ------------------------------------------------------
+# If the %define variable VARIABLE is defined, expand IF-TRUE, else expand
+# IF-FALSE. Don't record usage of VARIABLE.
+#
+# For example:
+#
+# _b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
+m4_define([_b4_percent_define_ifdef],
+[m4_ifdef([b4_percent_define(]$1[)],
+ [$2],
+ [$3])])
+
+# b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE])
+# ------------------------------------------------------
+# Mimic muscle_percent_define_ifdef in ../src/muscle-tab.h exactly. That is,
+# if the %define variable VARIABLE is defined, expand IF-TRUE, else expand
+# IF-FALSE. Also, record Bison's usage of VARIABLE by defining
+# b4_percent_define_bison_variables(VARIABLE).
+#
+# For example:
+#
+# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
+m4_define([b4_percent_define_ifdef],
+[_b4_percent_define_ifdef([$1],
+ [b4_percent_define_use([$1])$2],
+ [$3])])
+
+
+# b4_percent_define_check_file_complain(VARIABLE)
+# -----------------------------------------------
+# Warn about %define variable VARIABLE having an incorrect
+# value.
+m4_define([b4_percent_define_check_file_complain],
+[b4_complain_at(b4_percent_define_get_loc([$1]),
+ [[%%define variable '%s' requires 'none' or '"..."' values]],
+ [$1])])
+
+
+# b4_percent_define_check_file(MACRO, VARIABLE, DEFAULT)
+# ------------------------------------------------------
+# If the %define variable VARIABLE:
+# - is undefined, then if DEFAULT is non-empty, define MACRO to DEFAULT
+# - is a string, define MACRO to its value
+# - is the keyword 'none', do nothing
+# - otherwise, warn about the incorrect value.
+m4_define([b4_percent_define_check_file],
+[b4_percent_define_ifdef([$2],
+ [m4_case(b4_percent_define_get_kind([$2]),
+ [string],
+ [m4_define([$1], b4_percent_define_get([$2]))],
+ [keyword],
+ [m4_if(b4_percent_define_get([$2]), [none], [],
+ [b4_percent_define_check_file_complain([$2])])],
+ [b4_percent_define_check_file_complain([$2])])
+ ],
+ [m4_ifval([$3],
+ [m4_define([$1], [$3])])])
+])
+
+
+
+## --------- ##
+## Options. ##
+## --------- ##
+
+
+# b4_percent_define_flag_if(VARIABLE, IF-TRUE, [IF-FALSE])
+# --------------------------------------------------------
+# Mimic muscle_percent_define_flag_if in ../src/muscle-tab.h exactly. That is,
+# if the %define variable VARIABLE is defined to "" or "true", expand IF-TRUE.
+# If it is defined to "false", expand IF-FALSE. Complain if it is undefined
+# (a Bison or skeleton 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).
+#
+# For example:
+#
+# b4_percent_define_flag_if([[foo]], [[it's true]], [[it's false]])
+m4_define([b4_percent_define_flag_if],
+[b4_percent_define_ifdef([$1],
+ [m4_case(b4_percent_define_get([$1]),
+ [], [$2], [true], [$2], [false], [$3],
+ [m4_expand_once([b4_complain_at(b4_percent_define_get_loc([$1]),
+ [[invalid value for %%define Boolean variable '%s']],
+ [$1])],
+ [[b4_percent_define_flag_if($1)]])])],
+ [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
+
+
+# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword])
+# --------------------------------------------------------------
+# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is,
+# if the %define variable VARIABLE is undefined, set its value to DEFAULT.
+# 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.
+#
+# For example:
+#
+# b4_percent_define_default([[foo]], [[default value]])
+m4_define([b4_percent_define_default],
+[_b4_percent_define_ifdef([$1], [],
+ [m4_define([b4_percent_define(]$1[)], [$2])dnl
+ m4_define([b4_percent_define_kind(]$1[)],
+ [m4_default([$3], [keyword])])dnl
+ m4_define([b4_percent_define_loc(]$1[)],
+ [[[[<skeleton default value>:-1.-1]],
+ [[<skeleton default value>:-1.-1]]]])dnl
+ m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
+
+
+# b4_percent_define_if_define(NAME, [VARIABLE = NAME])
+# ----------------------------------------------------
+# Define b4_NAME_if that executes its $1 or $2 depending whether
+# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped
+# to '_'.
+m4_define([_b4_percent_define_if_define],
+[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
+ [b4_percent_define_flag_if(m4_default([$2], [$1]),
+ [$3], [$4])])])
+m4_define([b4_percent_define_if_define],
+[b4_percent_define_default([m4_default([$2], [$1])], [[false]])
+_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
+
+
+# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
+# ---------------------------------------------------------------------
+m4_define([b4_percent_define_check_kind],
+[_b4_percent_define_ifdef([$1],
+ [m4_if(b4_percent_define_get_kind([$1]), [$2], [],
+ [b4_error([m4_default([$3], [complain])],
+ b4_percent_define_get_loc([$1]),
+ [m4_case([$2],
+ [code], [[%%define variable '%s' requires '{...}' values]],
+ [keyword], [[%%define variable '%s' requires keyword values]],
+ [string], [[%%define variable '%s' requires '"..."' values]])],
+ [$1])])])dnl
+])
+
+
+# b4_percent_define_check_values(VALUES)
+# --------------------------------------
+# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
+# except that the VALUES structure is more appropriate for M4. That is, VALUES
+# is a list of sublists of strings. 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.
+#
+# For example:
+#
+# b4_percent_define_check_values([[[[foo]], [[foo-value1]], [[foo-value2]]]],
+# [[[[bar]], [[bar-value1]]]])
+m4_define([b4_percent_define_check_values],
+[m4_foreach([b4_sublist], m4_quote($@),
+ [_b4_percent_define_check_values(b4_sublist)])])
+
+m4_define([_b4_percent_define_check_values],
+[_b4_percent_define_ifdef([$1],
+ [b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl
+ m4_pushdef([b4_good_value], [0])dnl
+ m4_if($#, 1, [],
+ [m4_foreach([b4_value], m4_dquote(m4_shift($@)),
+ [m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,
+ [m4_define([b4_good_value], [1])])])])dnl
+ m4_if(b4_good_value, [0],
+ [b4_complain_at(b4_percent_define_get_loc([$1]),
+ [[invalid value for %%define variable '%s': '%s']],
+ [$1],
+ m4_dquote(m4_indir([b4_percent_define(]$1[)])))
+ m4_foreach([b4_value], m4_dquote(m4_shift($@)),
+ [b4_error([[note]], b4_percent_define_get_loc([$1]), []
+ [[accepted value: '%s']],
+ m4_dquote(b4_value))])])dnl
+ m4_popdef([b4_good_value])],
+ [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
+
+# b4_percent_code_get([QUALIFIER])
+# --------------------------------
+# If any %code blocks for QUALIFIER are defined, emit them beginning with a
+# comment and ending with synclines and a newline. If QUALIFIER is not
+# specified or empty, do this for the unqualified %code blocks. Also, record
+# Bison's usage of QUALIFIER (if specified) by defining
+# b4_percent_code_bison_qualifiers(QUALIFIER).
+#
+# For example, to emit any unqualified %code blocks followed by any %code
+# blocks for the qualifier foo:
+#
+# b4_percent_code_get
+# b4_percent_code_get([[foo]])
+m4_define([b4_percent_code_get],
+[m4_pushdef([b4_macro_name], [[b4_percent_code(]$1[)]])dnl
+m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])dnl
+m4_ifdef(b4_macro_name,
+[b4_comment([m4_if([$#], [0], [[Unqualified %code]],
+ [["%code ]$1["]])[ blocks.]])
+b4_user_code([m4_indir(b4_macro_name)])
+])dnl
+m4_popdef([b4_macro_name])])
+
+# b4_percent_code_ifdef(QUALIFIER, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------
+# If any %code blocks for QUALIFIER (or unqualified %code blocks if
+# QUALIFIER is empty) are defined, expand IF-TRUE, else expand IF-FALSE.
+# Also, record Bison's usage of QUALIFIER (if specified) by defining
+# b4_percent_code_bison_qualifiers(QUALIFIER).
+m4_define([b4_percent_code_ifdef],
+[m4_ifdef([b4_percent_code(]$1[)],
+ [m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])$2],
+ [$3])])
+
+
+## ------------------ ##
+## Common variables. ##
+## ------------------ ##
+
+
+# b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
+# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
+# b4_token_ctor_if([IF-YYLEX-RETURNS-A-TOKEN], [IF-NOT])
+# ----------------------------------------------------------
+b4_percent_define_if_define([token_ctor], [api.token.constructor])
+b4_percent_define_if_define([locations]) # Whether locations are tracked.
+b4_percent_define_if_define([parse.assert])
+b4_percent_define_if_define([parse.trace])
+
+
+# b4_bison_locations_if([IF-TRUE])
+# --------------------------------
+# Expand IF-TRUE if using locations, and using the default location
+# type.
+m4_define([b4_bison_locations_if],
+[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [], [$1])])])
+
+
+# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT])
+# ------------------------------------------------------
+# Map %define parse.error "(simple|verbose)" to b4_error_verbose_if and
+# b4_error_verbose_flag.
+b4_percent_define_default([[parse.error]], [[simple]])
+b4_percent_define_check_values([[[[parse.error]],
+ [[simple]], [[verbose]]]])
+m4_define([b4_error_verbose_flag],
+ [m4_case(b4_percent_define_get([[parse.error]]),
+ [simple], [[0]],
+ [verbose], [[1]])])
+b4_define_flag_if([error_verbose])
+
+# yytoken_table is needed to support verbose errors.
+b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
+
+
+# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
+# ----------------------------------------------
+b4_percent_define_if_define([variant])
+m4_define([b4_variant_flag], [[0]])
+b4_percent_define_ifdef([[api.value.type]],
+ [m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
+ [m4_case(b4_percent_define_get([[api.value.type]]), [variant],
+ [m4_define([b4_variant_flag], [[1]])])])])
+b4_define_flag_if([variant])
+
+
+## ----------------------------------------------------------- ##
+## After processing the skeletons, check that all the user's ##
+## %define variables and %code qualifiers were used by Bison. ##
+## ----------------------------------------------------------- ##
+
+m4_define([b4_check_user_names_wrap],
+[m4_ifdef([b4_percent_]$1[_user_]$2[s],
+ [b4_check_user_names([[%]$1 $2],
+ [b4_percent_]$1[_user_]$2[s],
+ [[b4_percent_]$1[_bison_]$2[s]])])])
+
+m4_wrap_lifo([
+b4_check_user_names_wrap([[define]], [[variable]])
+b4_check_user_names_wrap([[code]], [[qualifier]])
+])
+
+
+## ---------------- ##
+## Default values. ##
+## ---------------- ##
+
+# m4_define_default([b4_lex_param], []) dnl breaks other skeletons
+m4_define_default([b4_epilogue], [])
+m4_define_default([b4_parse_param], [])
+
+# The initial column and line.
+m4_define_default([b4_location_initial_column], [1])
+m4_define_default([b4_location_initial_line], [1])
+
+
+## --------------- ##
+## Sanity checks. ##
+## --------------- ##
+
+# api.location.prefix={...} (Java and C++).
+b4_percent_define_check_kind([api.location.type], [code], [deprecated])
+
+# api.position.prefix={...} (Java).
+b4_percent_define_check_kind([api.position.type], [code], [deprecated])
+
+# api.prefix >< %name-prefix.
+b4_percent_define_check_kind([api.prefix], [code], [deprecated])
+b4_percent_define_ifdef([api.prefix],
+[m4_ifdef([b4_prefix],
+[b4_complain_at(b4_percent_define_get_loc([api.prefix]),
+ [['%s' and '%s' cannot be used together]],
+ [%name-prefix],
+ [%define api.prefix])])])
+
+# api.token.prefix={...}
+# Make it a warning for those who used betas of Bison 3.0.
+b4_percent_define_check_kind([api.token.prefix], [code], [deprecated])
+
+# api.value.type >< %union.
+b4_percent_define_ifdef([api.value.type],
+[m4_ifdef([b4_union_members],
+[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
+ [['%s' and '%s' cannot be used together]],
+ [%union],
+ [%define api.value.type])])])
+
+# api.value.type=union >< %yacc.
+b4_percent_define_ifdef([api.value.type],
+[m4_if(b4_percent_define_get([api.value.type]), [union],
+[b4_yacc_if(dnl
+[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
+ [['%s' and '%s' cannot be used together]],
+ [%yacc],
+ [%define api.value.type "union"])])])])
+
+# api.value.union.name.
+b4_percent_define_check_kind([api.value.union.name], [keyword])
diff --git a/contrib/tools/bison/data/skeletons/c++-skel.m4 b/contrib/tools/bison/data/skeletons/c++-skel.m4
new file mode 100644
index 0000000000..1c3721cdbb
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/c++-skel.m4
@@ -0,0 +1,27 @@
+ -*- Autoconf -*-
+
+# C++ skeleton dispatching for Bison.
+
+# Copyright (C) 2006-2007, 2009-2015, 2018-2019 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/>.
+
+b4_glr_if( [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])])
+b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])])
+
+m4_define_default([b4_used_skeleton], [b4_skeletonsdir/[lalr1.cc]])
+m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
+
+m4_include(b4_used_skeleton)
diff --git a/contrib/tools/bison/data/skeletons/c++.m4 b/contrib/tools/bison/data/skeletons/c++.m4
new file mode 100644
index 0000000000..35008f3745
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/c++.m4
@@ -0,0 +1,663 @@
+ -*- Autoconf -*-
+
+# C++ skeleton for Bison
+
+# Copyright (C) 2002-2019 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/>.
+
+# Sanity checks, before defaults installed by c.m4.
+b4_percent_define_ifdef([[api.value.union.name]],
+ [b4_complain_at(b4_percent_define_get_loc([[api.value.union.name]]),
+ [named %union is invalid in C++])])
+
+m4_include(b4_skeletonsdir/[c.m4])
+
+b4_percent_define_check_kind([api.namespace], [code], [deprecated])
+b4_percent_define_check_kind([api.parser.class], [code], [deprecated])
+
+
+## ----- ##
+## C++. ##
+## ----- ##
+
+# b4_comment(TEXT, [PREFIX])
+# --------------------------
+# Put TEXT in comment. Prefix all the output lines with PREFIX.
+m4_define([b4_comment],
+[_b4_comment([$1], [$2// ], [$2// ])])
+
+
+# b4_inline(hh|cc)
+# ----------------
+# Expand to `inline\n ` if $1 is hh.
+m4_define([b4_inline],
+[m4_case([$1],
+ [cc], [],
+ [hh], [[inline
+ ]],
+ [m4_fatal([$0: invalid argument: $1])])])
+
+
+# b4_cxx_portability
+# ------------------
+m4_define([b4_cxx_portability],
+[#if defined __cplusplus
+# define YY_CPLUSPLUS __cplusplus
+#else
+# define YY_CPLUSPLUS 199711L
+#endif
+
+// Support move semantics when possible.
+#if 201103L <= YY_CPLUSPLUS
+# define YY_MOVE std::move
+# define YY_MOVE_OR_COPY move
+# define YY_MOVE_REF(Type) Type&&
+# define YY_RVREF(Type) Type&&
+# define YY_COPY(Type) Type
+#else
+# define YY_MOVE
+# define YY_MOVE_OR_COPY copy
+# define YY_MOVE_REF(Type) Type&
+# define YY_RVREF(Type) const Type&
+# define YY_COPY(Type) const Type&
+#endif
+
+// Support noexcept when possible.
+#if 201103L <= YY_CPLUSPLUS
+# define YY_NOEXCEPT noexcept
+# define YY_NOTHROW
+#else
+# define YY_NOEXCEPT
+# define YY_NOTHROW throw ()
+#endif
+
+// Support constexpr when possible.
+#if 201703 <= YY_CPLUSPLUS
+# define YY_CONSTEXPR constexpr
+#else
+# define YY_CONSTEXPR
+#endif[]dnl
+])
+
+
+## ---------------- ##
+## Default values. ##
+## ---------------- ##
+
+b4_percent_define_default([[api.parser.class]], [[parser]])
+
+# Don't do that so that we remember whether we're using a user
+# request, or the default value.
+#
+# b4_percent_define_default([[api.location.type]], [[location]])
+
+b4_percent_define_default([[filename_type]], [[std::string]])
+# Make it a warning for those who used betas of Bison 3.0.
+b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
+
+b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
+b4_percent_define_default([[define_location_comparison]],
+ [m4_if(b4_percent_define_get([[filename_type]]),
+ [std::string], [[true]], [[false]])])
+
+
+
+## ----------- ##
+## Namespace. ##
+## ----------- ##
+
+m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
+
+
+# Don't permit an empty b4_namespace_ref. Any '::parser::foo' appended to it
+# would compile as an absolute reference with 'parser' in the global namespace.
+# b4_namespace_open would open an anonymous namespace and thus establish
+# internal linkage. This would compile. However, it's cryptic, and internal
+# linkage for the parser would be specified in all translation units that
+# include the header, which is always generated. If we ever need to permit
+# internal linkage somehow, surely we can find a cleaner approach.
+m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [],
+[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]),
+ [[namespace reference is empty]])])
+
+# Instead of assuming the C++ compiler will do it, Bison should reject any
+# invalid b4_namespace_ref that would be converted to a valid
+# b4_namespace_open. The problem is that Bison doesn't always output
+# b4_namespace_ref to uncommented code but should reserve the ability to do so
+# in future releases without risking breaking any existing user grammars.
+# Specifically, don't allow empty names as b4_namespace_open would just convert
+# those into anonymous namespaces, and that might tempt some users.
+m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*::]), [-1], [],
+[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]),
+ [[namespace reference has consecutive "::"]])])
+m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*$]), [-1], [],
+[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]),
+ [[namespace reference has a trailing "::"]])])
+
+m4_define([b4_namespace_open],
+[b4_user_code([b4_percent_define_get_syncline([[api.namespace]])
+[namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
+ [^\(.\)[ ]*::], [\1])),
+ [::], [ { namespace ])[ {]])])
+
+m4_define([b4_namespace_close],
+[b4_user_code([b4_percent_define_get_syncline([[api.namespace]])
+m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]),
+ [^\(.\)[ ]*\(::\)?\([^][:]\|:[^:]\)*],
+ [\1])),
+ [::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])])
+
+
+# b4_token_enums
+# --------------
+# Output the definition of the tokens as enums.
+m4_define([b4_token_enums],
+[[enum yytokentype
+ {
+ ]m4_join([,
+ ],
+ b4_symbol_map([b4_token_enum]))[
+ };]dnl
+])
+
+
+
+
+## ----------------- ##
+## Semantic Values. ##
+## ----------------- ##
+
+
+
+# b4_value_type_declare
+# ---------------------
+# Declare semantic_type.
+m4_define([b4_value_type_declare],
+[b4_value_type_setup[]dnl
+[ /// Symbol semantic values.
+]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+[code],
+[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
+[m4_bmatch(b4_percent_define_get([[api.value.type]]),
+[union\|union-directive],
+[[ union semantic_type
+ {
+ ]b4_user_union_members[
+ };]])])dnl
+])
+
+
+# b4_public_types_declare
+# -----------------------
+# Define the public types: token, semantic value, location, and so forth.
+# Depending on %define token_lex, may be output in the header or source file.
+m4_define([b4_public_types_declare],
+[[#ifndef ]b4_api_PREFIX[STYPE
+]b4_value_type_declare[
+#else
+ typedef ]b4_api_PREFIX[STYPE semantic_type;
+#endif]b4_locations_if([
+ /// Symbol locations.
+ typedef b4_percent_define_get([[api.location.type]],
+ [[location]]) location_type;])[
+
+ /// Syntax errors thrown from user actions.
+ struct syntax_error : std::runtime_error
+ {
+ syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m)
+ : std::runtime_error (m)]b4_locations_if([
+ , location (l)])[
+ {}
+
+ syntax_error (const syntax_error& s)
+ : std::runtime_error (s.what ())]b4_locations_if([
+ , location (s.location)])[
+ {}
+
+ ~syntax_error () YY_NOEXCEPT YY_NOTHROW;]b4_locations_if([
+
+ location_type location;])[
+ };
+
+ /// Tokens.
+ struct token
+ {
+ ]b4_token_enums[
+ };
+
+ /// (External) token type, as returned by yylex.
+ typedef token::yytokentype token_type;
+
+ /// Symbol type: an internal symbol number.
+ typedef int symbol_number_type;
+
+ /// The symbol type number to denote an empty symbol.
+ enum { empty_symbol = -2 };
+
+ /// Internal symbol number for tokens (subsumed by symbol_number_type).
+ typedef ]b4_int_type_for([b4_translate])[ token_number_type;
+]])
+
+
+# b4_symbol_type_define
+# ---------------------
+# Define symbol_type, the external type for symbols used for symbol
+# constructors.
+m4_define([b4_symbol_type_define],
+[[ /// A complete symbol.
+ ///
+ /// Expects its Base type to provide access to the symbol type
+ /// via type_get ().
+ ///
+ /// Provide access to semantic value]b4_locations_if([ and location])[.
+ template <typename Base>
+ struct basic_symbol : Base
+ {
+ /// Alias to Base.
+ typedef Base super_type;
+
+ /// Default constructor.
+ basic_symbol ()
+ : value ()]b4_locations_if([
+ , location ()])[
+ {}
+
+#if 201103L <= YY_CPLUSPLUS
+ /// Move constructor.
+ basic_symbol (basic_symbol&& that);
+#endif
+
+ /// Copy constructor.
+ basic_symbol (const basic_symbol& that);]b4_variant_if([[
+
+ /// Constructor for valueless symbols, and symbols from each type.
+]b4_type_foreach([b4_basic_symbol_constructor_define])], [[
+ /// Constructor for valueless symbols.
+ basic_symbol (typename Base::kind_type t]b4_locations_if([,
+ YY_MOVE_REF (location_type) l])[);
+
+ /// Constructor for symbols with semantic value.
+ basic_symbol (typename Base::kind_type t,
+ YY_RVREF (semantic_type) v]b4_locations_if([,
+ YY_RVREF (location_type) l])[);
+]])[
+ /// Destroy the symbol.
+ ~basic_symbol ()
+ {
+ clear ();
+ }
+
+ /// Destroy contents, and record that is empty.
+ void clear ()
+ {]b4_variant_if([[
+ // User destructor.
+ symbol_number_type yytype = this->type_get ();
+ basic_symbol<Base>& yysym = *this;
+ (void) yysym;
+ switch (yytype)
+ {
+]b4_symbol_foreach([b4_symbol_destructor])dnl
+[ default:
+ break;
+ }
+
+ // Type destructor.
+]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
+ Base::clear ();
+ }
+
+ /// Whether empty.
+ bool empty () const YY_NOEXCEPT;
+
+ /// Destructive move, \a s is emptied into this.
+ void move (basic_symbol& s);
+
+ /// The semantic value.
+ semantic_type value;]b4_locations_if([
+
+ /// The location.
+ location_type location;])[
+
+ private:
+#if YY_CPLUSPLUS < 201103L
+ /// Assignment operator.
+ basic_symbol& operator= (const basic_symbol& that);
+#endif
+ };
+
+ /// Type access provider for token (enum) based symbols.
+ struct by_type
+ {
+ /// Default constructor.
+ by_type ();
+
+#if 201103L <= YY_CPLUSPLUS
+ /// Move constructor.
+ by_type (by_type&& that);
+#endif
+
+ /// Copy constructor.
+ by_type (const by_type& that);
+
+ /// The symbol type as needed by the constructor.
+ typedef token_type kind_type;
+
+ /// Constructor from (external) token numbers.
+ by_type (kind_type t);
+
+ /// Record that this symbol is empty.
+ void clear ();
+
+ /// Steal the symbol type from \a that.
+ void move (by_type& that);
+
+ /// The (internal) type number (corresponding to \a type).
+ /// \a empty when empty.
+ symbol_number_type type_get () const YY_NOEXCEPT;
+
+ /// The token.
+ token_type token () const YY_NOEXCEPT;
+
+ /// The symbol type.
+ /// \a empty_symbol when empty.
+ /// An int, not token_number_type, to be able to store empty_symbol.
+ int type;
+ };
+
+ /// "External" symbols: returned by the scanner.
+ struct symbol_type : basic_symbol<by_type>
+ {]b4_variant_if([[
+ /// Superclass.
+ typedef basic_symbol<by_type> super_type;
+
+ /// Empty symbol.
+ symbol_type () {}
+
+ /// Constructor for valueless symbols, and symbols from each type.
+]b4_type_foreach([_b4_token_constructor_define])dnl
+ ])[};
+]])
+
+
+# b4_public_types_define(hh|cc)
+# -----------------------------
+# Provide the implementation needed by the public types.
+m4_define([b4_public_types_define],
+[[ // basic_symbol.
+#if 201103L <= YY_CPLUSPLUS
+ template <typename Base>
+ ]b4_parser_class[::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
+ : Base (std::move (that))
+ , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([
+ , location (std::move (that.location))])[
+ {]b4_variant_if([
+ b4_symbol_variant([this->type_get ()], [value], [move],
+ [std::move (that.value)])
+ ])[}
+#endif
+
+ template <typename Base>
+ ]b4_parser_class[::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
+ : Base (that)
+ , value (]b4_variant_if([], [that.value]))b4_locations_if([
+ , location (that.location)])[
+ {]b4_variant_if([
+ b4_symbol_variant([this->type_get ()], [value], [copy],
+ [YY_MOVE (that.value)])
+ ])[}
+
+]b4_variant_if([], [[
+ /// Constructor for valueless symbols.
+ template <typename Base>
+ ]b4_parser_class[::basic_symbol<Base>::basic_symbol (]b4_join(
+ [typename Base::kind_type t],
+ b4_locations_if([YY_MOVE_REF (location_type) l]))[)
+ : Base (t)
+ , value ()]b4_locations_if([
+ , location (l)])[
+ {}
+
+ template <typename Base>
+ ]b4_parser_class[::basic_symbol<Base>::basic_symbol (]b4_join(
+ [typename Base::kind_type t],
+ [YY_RVREF (semantic_type) v],
+ b4_locations_if([YY_RVREF (location_type) l]))[)
+ : Base (t)
+ , value (]b4_variant_if([], [YY_MOVE (v)])[)]b4_locations_if([
+ , location (YY_MOVE (l))])[
+ {]b4_variant_if([[
+ (void) v;
+ ]b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[
+
+ template <typename Base>
+ bool
+ ]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
+ {
+ return Base::type_get () == empty_symbol;
+ }
+
+ template <typename Base>
+ void
+ ]b4_parser_class[::basic_symbol<Base>::move (basic_symbol& s)
+ {
+ super_type::move (s);
+ ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move],
+ [YY_MOVE (s.value)])],
+ [value = YY_MOVE (s.value);])[]b4_locations_if([
+ location = YY_MOVE (s.location);])[
+ }
+
+ // by_type.
+ ]b4_inline([$1])b4_parser_class[::by_type::by_type ()
+ : type (empty_symbol)
+ {}
+
+#if 201103L <= YY_CPLUSPLUS
+ ]b4_inline([$1])b4_parser_class[::by_type::by_type (by_type&& that)
+ : type (that.type)
+ {
+ that.clear ();
+ }
+#endif
+
+ ]b4_inline([$1])b4_parser_class[::by_type::by_type (const by_type& that)
+ : type (that.type)
+ {}
+
+ ]b4_inline([$1])b4_parser_class[::by_type::by_type (token_type t)
+ : type (yytranslate_ (t))
+ {}
+
+ ]b4_inline([$1])[void
+ ]b4_parser_class[::by_type::clear ()
+ {
+ type = empty_symbol;
+ }
+
+ ]b4_inline([$1])[void
+ ]b4_parser_class[::by_type::move (by_type& that)
+ {
+ type = that.type;
+ that.clear ();
+ }
+
+ ]b4_inline([$1])[int
+ ]b4_parser_class[::by_type::type_get () const YY_NOEXCEPT
+ {
+ return type;
+ }
+]b4_token_ctor_if([[
+ ]b4_inline([$1])b4_parser_class[::token_type
+ ]b4_parser_class[::by_type::token () const YY_NOEXCEPT
+ {
+ // YYTOKNUM[NUM] -- (External) token number corresponding to the
+ // (internal) symbol number NUM (which must be that of a token). */
+ static
+ const ]b4_int_type_for([b4_toknum])[
+ yytoken_number_[] =
+ {
+ ]b4_toknum[
+ };
+ return token_type (yytoken_number_[type]);
+ }
+]])[]dnl
+])
+
+
+# b4_token_constructor_define
+# ----------------------------
+# Define symbol constructors for all the value types.
+# Use at class-level. Redefined in variant.hh.
+m4_define([b4_token_constructor_define], [])
+
+
+# b4_yytranslate_define(cc|hh)
+# ----------------------------
+# Define yytranslate_. Sometimes used in the header file ($1=hh),
+# sometimes in the cc file.
+m4_define([b4_yytranslate_define],
+[ b4_inline([$1])b4_parser_class[::token_number_type
+ ]b4_parser_class[::yytranslate_ (]b4_token_ctor_if([token_type],
+ [int])[ t)
+ {
+ // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
+ // TOKEN-NUM as returned by yylex.
+ static
+ const token_number_type
+ translate_table[] =
+ {
+ ]b4_translate[
+ };
+ const unsigned user_token_number_max_ = ]b4_user_token_number_max[;
+ const token_number_type undef_token_ = ]b4_undef_token_number[;
+
+ if (static_cast<int> (t) <= yyeof_)
+ return yyeof_;
+ else if (static_cast<unsigned> (t) <= user_token_number_max_)
+ return translate_table[t];
+ else
+ return undef_token_;
+ }
+]])
+
+
+# b4_lhs_value([TYPE])
+# --------------------
+m4_define([b4_lhs_value],
+[b4_symbol_value([yyval], [$1])])
+
+
+# b4_rhs_value(RULE-LENGTH, POS, [TYPE])
+# --------------------------------------
+# FIXME: Dead code.
+m4_define([b4_rhs_value],
+[b4_symbol_value([yysemantic_stack_@{($1) - ($2)@}], [$3])])
+
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[(yyloc)])
+
+
+# b4_rhs_location(RULE-LENGTH, POS)
+# ---------------------------------
+# Expansion of @POS, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+[(yylocation_stack_@{($1) - ($2)@})])
+
+
+# b4_parse_param_decl
+# -------------------
+# Extra formal arguments of the constructor.
+# Change the parameter names from "foo" into "foo_yyarg", so that
+# there is no collision bw the user chosen attribute name, and the
+# argument name in the constructor.
+m4_define([b4_parse_param_decl],
+[m4_ifset([b4_parse_param],
+ [m4_map_sep([b4_parse_param_decl_1], [, ], [b4_parse_param])])])
+
+m4_define([b4_parse_param_decl_1],
+[$1_yyarg])
+
+
+
+# b4_parse_param_cons
+# -------------------
+# Extra initialisations of the constructor.
+m4_define([b4_parse_param_cons],
+ [m4_ifset([b4_parse_param],
+ [
+ b4_cc_constructor_calls(b4_parse_param)])])
+m4_define([b4_cc_constructor_calls],
+ [m4_map_sep([b4_cc_constructor_call], [,
+ ], [$@])])
+m4_define([b4_cc_constructor_call],
+ [$2 ($2_yyarg)])
+
+# b4_parse_param_vars
+# -------------------
+# Extra instance variables.
+m4_define([b4_parse_param_vars],
+ [m4_ifset([b4_parse_param],
+ [
+ // User arguments.
+b4_cc_var_decls(b4_parse_param)])])
+m4_define([b4_cc_var_decls],
+ [m4_map_sep([b4_cc_var_decl], [
+], [$@])])
+m4_define([b4_cc_var_decl],
+ [ $1;])
+
+
+## ---------##
+## Values. ##
+## ---------##
+
+# b4_yylloc_default_define
+# ------------------------
+# Define YYLLOC_DEFAULT.
+m4_define([b4_yylloc_default_define],
+[[/* 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).begin = YYRHSLOC (Rhs, 1).begin; \
+ (Current).end = YYRHSLOC (Rhs, N).end; \
+ } \
+ else \
+ { \
+ (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
+ } \
+ while (false)
+# endif
+]])
+
+## -------- ##
+## Checks. ##
+## -------- ##
+
+b4_token_ctor_if([b4_variant_if([],
+ [b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
+ [cannot use '%s' without '%s'],
+ [%define api.token.constructor],
+ [%define api.value.type variant]))])])
diff --git a/contrib/tools/bison/data/skeletons/c-like.m4 b/contrib/tools/bison/data/skeletons/c-like.m4
new file mode 100644
index 0000000000..8d891b67ef
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/c-like.m4
@@ -0,0 +1,66 @@
+ -*- Autoconf -*-
+
+# Common code for C-like languages (C, C++, Java, etc.)
+
+# Copyright (C) 2012-2015, 2018-2019 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/>.
+
+# _b4_comment(TEXT, OPEN, CONTINUE, END)
+# --------------------------------------
+# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
+# Avoid adding indentation to the first line, as the indentation comes
+# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
+#
+# Prefix all the output lines with PREFIX.
+m4_define([_b4_comment],
+[$2[]m4_bpatsubst(m4_expand([[$1]]), [
+\(.\)], [
+$3\1])$4])
+
+
+# b4_comment(TEXT, [PREFIX])
+# --------------------------
+# Put TEXT in comment. Prefix all the output lines with PREFIX.
+m4_define([b4_comment],
+[_b4_comment([$1], [$2/* ], [$2 ], [ */])])
+
+
+
+
+# _b4_dollar_dollar(VALUE, SYMBOL-NUM, FIELD, DEFAULT-FIELD)
+# ----------------------------------------------------------
+# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD",
+# otherwise just VALUE. Be sure to pass "(VALUE)" if VALUE is a
+# pointer.
+m4_define([_b4_dollar_dollar],
+[b4_symbol_value([$1],
+ [$2],
+ m4_if([$3], [[]],
+ [[$4]], [[$3]]))])
+
+# b4_dollar_pushdef(VALUE-POINTER, SYMBOL-NUM, [TYPE_TAG], LOCATION)
+# b4_dollar_popdef
+# ------------------------------------------------------------------
+# Define b4_dollar_dollar for VALUE-POINTER and DEFAULT-FIELD,
+# and b4_at_dollar for LOCATION.
+m4_define([b4_dollar_pushdef],
+[m4_pushdef([b4_dollar_dollar],
+ [_b4_dollar_dollar([$1], [$2], m4_dquote($][1), [$3])])dnl
+m4_pushdef([b4_at_dollar], [$4])dnl
+])
+m4_define([b4_dollar_popdef],
+[m4_popdef([b4_at_dollar])dnl
+m4_popdef([b4_dollar_dollar])dnl
+])
diff --git a/contrib/tools/bison/data/skeletons/c-skel.m4 b/contrib/tools/bison/data/skeletons/c-skel.m4
new file mode 100644
index 0000000000..2a21cfc7d0
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/c-skel.m4
@@ -0,0 +1,27 @@
+ -*- Autoconf -*-
+
+# C skeleton dispatching for Bison.
+
+# Copyright (C) 2006-2007, 2009-2015, 2018-2019 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/>.
+
+b4_glr_if( [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])])
+b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])])
+
+m4_define_default([b4_used_skeleton], [b4_skeletonsdir/[yacc.c]])
+m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
+
+m4_include(b4_used_skeleton)
diff --git a/contrib/tools/bison/data/skeletons/c.m4 b/contrib/tools/bison/data/skeletons/c.m4
new file mode 100644
index 0000000000..3cde04a957
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/c.m4
@@ -0,0 +1,883 @@
+ -*- Autoconf -*-
+
+# C M4 Macros for Bison.
+
+# Copyright (C) 2002, 2004-2015, 2018-2019 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/>.
+
+m4_include(b4_skeletonsdir/[c-like.m4])
+
+# b4_tocpp(STRING)
+# ----------------
+# Convert STRING into a valid C macro name.
+m4_define([b4_tocpp],
+[m4_toupper(m4_bpatsubst(m4_quote($1), [[^a-zA-Z0-9]+], [_]))])
+
+
+# b4_cpp_guard(FILE)
+# ------------------
+# A valid C macro name to use as a CPP header guard for FILE.
+m4_define([b4_cpp_guard],
+[[YY_]b4_tocpp(m4_defn([b4_prefix])/[$1])[_INCLUDED]])
+
+
+# b4_cpp_guard_open(FILE)
+# b4_cpp_guard_close(FILE)
+# ------------------------
+# If FILE does not expand to nothing, open/close CPP inclusion guards for FILE.
+m4_define([b4_cpp_guard_open],
+[m4_ifval(m4_quote($1),
+[#ifndef b4_cpp_guard([$1])
+# define b4_cpp_guard([$1])])])
+
+m4_define([b4_cpp_guard_close],
+[m4_ifval(m4_quote($1),
+[#endif b4_comment([!b4_cpp_guard([$1])])])])
+
+
+## ---------------- ##
+## Identification. ##
+## ---------------- ##
+
+# b4_identification
+# -----------------
+# Depends on individual skeletons to define b4_pure_flag, b4_push_flag, or
+# b4_pull_flag if they use the values of the %define variables api.pure or
+# api.push-pull.
+m4_define([b4_identification],
+[[/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "]b4_version["
+
+/* Skeleton name. */
+#define YYSKELETON_NAME ]b4_skeleton[]m4_ifdef([b4_pure_flag], [[
+
+/* Pure parsers. */
+#define YYPURE ]b4_pure_flag])[]m4_ifdef([b4_push_flag], [[
+
+/* Push parsers. */
+#define YYPUSH ]b4_push_flag])[]m4_ifdef([b4_pull_flag], [[
+
+/* Pull parsers. */
+#define YYPULL ]b4_pull_flag])[
+]])
+
+
+## ---------------- ##
+## Default values. ##
+## ---------------- ##
+
+# b4_api_prefix, b4_api_PREFIX
+# ----------------------------
+# Corresponds to %define api.prefix
+b4_percent_define_default([[api.prefix]], [[yy]])
+m4_define([b4_api_prefix],
+[b4_percent_define_get([[api.prefix]])])
+m4_define([b4_api_PREFIX],
+[m4_toupper(b4_api_prefix)])
+
+
+# b4_prefix
+# ---------
+# If the %name-prefix is not given, it is api.prefix.
+m4_define_default([b4_prefix], [b4_api_prefix])
+
+# If the %union is not named, its name is YYSTYPE.
+b4_percent_define_default([[api.value.union.name]],
+ [b4_api_PREFIX[][STYPE]])
+
+
+## ------------------------ ##
+## Pure/impure interfaces. ##
+## ------------------------ ##
+
+# b4_lex_formals
+# --------------
+# All the yylex formal arguments.
+# b4_lex_param arrives quoted twice, but we want to keep only one level.
+m4_define([b4_lex_formals],
+[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl
+b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl
+m4_ifdef([b4_lex_param], [, ]b4_lex_param)])
+
+
+# b4_lex
+# ------
+# Call yylex.
+m4_define([b4_lex],
+[b4_function_call([yylex], [int], b4_lex_formals)])
+
+
+# b4_user_args
+# ------------
+m4_define([b4_user_args],
+[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])])
+
+
+# b4_parse_param
+# --------------
+# If defined, b4_parse_param arrives double quoted, but below we prefer
+# it to be single quoted.
+m4_define([b4_parse_param],
+b4_parse_param)
+
+
+# b4_parse_param_for(DECL, FORMAL, BODY)
+# ---------------------------------------
+# Iterate over the user parameters, binding the declaration to DECL,
+# the formal name to FORMAL, and evaluating the BODY.
+m4_define([b4_parse_param_for],
+[m4_foreach([$1_$2], m4_defn([b4_parse_param]),
+[m4_pushdef([$1], m4_unquote(m4_car($1_$2)))dnl
+m4_pushdef([$2], m4_shift($1_$2))dnl
+$3[]dnl
+m4_popdef([$2])dnl
+m4_popdef([$1])dnl
+])])
+
+# b4_parse_param_use([VAL], [LOC])
+# --------------------------------
+# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
+m4_define([b4_parse_param_use],
+[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl
+b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl
+b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal);
+])dnl
+])
+
+
+## ------------ ##
+## Data Types. ##
+## ------------ ##
+
+# b4_int_type(MIN, MAX)
+# ---------------------
+# Return the smallest int type able to handle numbers ranging from
+# MIN to MAX (included).
+m4_define([b4_int_type],
+[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char],
+ b4_ints_in($@, [-128], [127]), [1], [signed char],
+
+ b4_ints_in($@, [0], [65535]), [1], [unsigned short],
+ b4_ints_in($@, [-32768], [32767]), [1], [short],
+
+ m4_eval([0 <= $1]), [1], [unsigned],
+
+ [int])])
+
+
+# b4_int_type_for(NAME)
+# ---------------------
+# Return the smallest int type able to handle numbers ranging from
+# 'NAME_min' to 'NAME_max' (included).
+m4_define([b4_int_type_for],
+[b4_int_type($1_min, $1_max)])
+
+
+# b4_table_value_equals(TABLE, VALUE, LITERAL)
+# --------------------------------------------
+# Without inducing a comparison warning from the compiler, check if the
+# literal value LITERAL equals VALUE from table TABLE, which must have
+# TABLE_min and TABLE_max defined.
+m4_define([b4_table_value_equals],
+[m4_if(m4_eval($3 < m4_indir([b4_]$1[_min])
+ || m4_indir([b4_]$1[_max]) < $3), [1],
+ [[0]],
+ [(!!(($2) == ($3)))])])
+
+
+## ----------------- ##
+## Compiler issues. ##
+## ----------------- ##
+
+# b4_attribute_define([noreturn])
+# -------------------------------
+# Provide portable compiler "attributes". If "noreturn" is passed, define
+# _Noreturn.
+m4_define([b4_attribute_define],
+[[#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */
+#if ! defined _Noreturn
+# if defined __cplusplus && 201103L <= __cplusplus
+# define _Noreturn [[noreturn]]
+# elif !(defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)
+# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \
+ || 0x5110 <= __SUNPRO_C)
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+# 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__ && ! defined __ICC && 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
+]])
+
+
+# b4_null_define
+# --------------
+# Portability issues: define a YY_NULLPTR appropriate for the current
+# language (C, C++98, or C++11).
+#
+# In C++ pre C++11 it is standard practice to use 0 (not NULL) for the
+# null pointer. In C, prefer ((void*)0) to avoid having to include stdlib.h.
+m4_define([b4_null_define],
+[# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif[]dnl
+])
+
+
+# b4_null
+# -------
+# Return a null pointer constant.
+m4_define([b4_null], [YY_NULLPTR])
+
+
+
+## ---------##
+## Values. ##
+## ---------##
+
+# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
+# -------------------------------------------------------------
+# Define "yy<TABLE-NAME>" whose contents is CONTENT.
+m4_define([b4_integral_parser_table_define],
+[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl
+static const b4_int_type_for([$2]) yy$1[[]] =
+{
+ $2
+};dnl
+])
+
+
+## ------------------------- ##
+## Assigning token numbers. ##
+## ------------------------- ##
+
+# b4_token_define(TOKEN-NUM)
+# --------------------------
+# Output the definition of this token as #define.
+m4_define([b4_token_define],
+[b4_token_format([#define %s %s], [$1])])
+
+# b4_token_defines
+# ----------------
+# Output the definition of the tokens.
+m4_define([b4_token_defines],
+[b4_any_token_visible_if([/* Tokens. */
+m4_join([
+], b4_symbol_map([b4_token_define]))
+])])
+
+
+# b4_token_enum(TOKEN-NUM)
+# ------------------------
+# Output the definition of this token as an enum.
+m4_define([b4_token_enum],
+[b4_token_format([%s = %s], [$1])])
+
+
+# b4_token_enums
+# --------------
+# Output the definition of the tokens (if there are) as enums.
+m4_define([b4_token_enums],
+[b4_any_token_visible_if([[/* Token type. */
+#ifndef ]b4_api_PREFIX[TOKENTYPE
+# define ]b4_api_PREFIX[TOKENTYPE
+ enum ]b4_api_prefix[tokentype
+ {
+ ]m4_join([,
+ ],
+ b4_symbol_map([b4_token_enum]))[
+ };
+#endif
+]])])
+
+
+# b4_token_enums_defines
+# ----------------------
+# Output the definition of the tokens (if there are any) as enums and,
+# if POSIX Yacc is enabled, as #defines.
+m4_define([b4_token_enums_defines],
+[b4_token_enums[]b4_yacc_if([b4_token_defines])])
+
+
+## ----------------- ##
+## Semantic Values. ##
+## ----------------- ##
+
+
+# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
+# ----------------------------------------------
+# See README.
+m4_define([b4_symbol_value],
+[m4_ifval([$3],
+ [($1.$3)],
+ [m4_ifval([$2],
+ [b4_symbol_if([$2], [has_type],
+ [($1.b4_symbol([$2], [type]))],
+ [$1])],
+ [$1])])])
+
+
+## ---------------------- ##
+## Defining C functions. ##
+## ---------------------- ##
+
+
+# b4_function_define(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
+# -----------------------------------------------------------
+# Declare the function NAME in C.
+m4_define([b4_function_define],
+[$2
+$1 (b4_formals(m4_shift2($@)))[]dnl
+])
+
+
+# b4_formals([DECL1, NAME1], ...)
+# -------------------------------
+# The formal arguments of a C function definition.
+m4_define([b4_formals],
+[m4_if([$#], [0], [void],
+ [$#$1], [1], [void],
+ [m4_map_sep([b4_formal], [, ], [$@])])])
+
+m4_define([b4_formal],
+[$1])
+
+
+
+## ----------------------- ##
+## Declaring C functions. ##
+## ----------------------- ##
+
+
+# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
+# ------------------------------------------------------------
+# Declare the function NAME.
+m4_define([b4_function_declare],
+[$2 $1 (b4_formals(m4_shift2($@)));[]dnl
+])
+
+
+
+
+## --------------------- ##
+## Calling C functions. ##
+## --------------------- ##
+
+
+# b4_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
+# -----------------------------------------------------------
+# Call the function NAME with arguments NAME1, NAME2 etc.
+m4_define([b4_function_call],
+[$1 (b4_args(m4_shift2($@)))[]dnl
+])
+
+
+# b4_args([DECL1, NAME1], ...)
+# ----------------------------
+# Output the arguments NAME1, NAME2...
+m4_define([b4_args],
+[m4_map_sep([b4_arg], [, ], [$@])])
+
+m4_define([b4_arg],
+[$2])
+
+
+## ----------- ##
+## Synclines. ##
+## ----------- ##
+
+# b4_sync_start(LINE, FILE)
+# -------------------------
+m4_define([b4_sync_start], [[#]line $1 $2])
+
+
+## -------------- ##
+## User actions. ##
+## -------------- ##
+
+# b4_case(LABEL, STATEMENTS)
+# --------------------------
+m4_define([b4_case],
+[ case $1:
+$2
+b4_syncline([@oline@], [@ofile@])
+ break;])
+
+
+# b4_predicate_case(LABEL, CONDITIONS)
+# ------------------------------------
+m4_define([b4_predicate_case],
+[ case $1:
+ if (! (
+$2)) YYERROR;
+b4_syncline([@oline@], [@ofile@])
+ break;])
+
+
+# b4_yydestruct_define
+# --------------------
+# Define the "yydestruct" function.
+m4_define_default([b4_yydestruct_define],
+[[/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+]b4_function_define([yydestruct],
+ [static void],
+ [[const char *yymsg], [yymsg]],
+ [[int yytype], [yytype]],
+ [[YYSTYPE *yyvaluep], [yyvaluep]][]dnl
+b4_locations_if( [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
+m4_ifset([b4_parse_param], [, b4_parse_param]))[
+{
+]b4_parse_param_use([yyvaluep], [yylocationp])dnl
+[ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ ]b4_symbol_actions([destructor])[
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}]dnl
+])
+
+
+# b4_yy_symbol_print_define
+# -------------------------
+# Define the "yy_symbol_print" function.
+m4_define_default([b4_yy_symbol_print_define],
+[[
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+]b4_function_define([yy_symbol_value_print],
+ [static void],
+ [[FILE *yyo], [yyo]],
+ [[int yytype], [yytype]],
+ [[YYSTYPE const * const yyvaluep], [yyvaluep]][]dnl
+b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
+m4_ifset([b4_parse_param], [, b4_parse_param]))[
+{
+ FILE *yyoutput = yyo;
+]b4_parse_param_use([yyoutput], [yylocationp])dnl
+[ if (!yyvaluep)
+ return;]
+dnl glr.c does not feature yytoknum.
+m4_if(b4_skeleton, ["yacc.c"],
+[[# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
+# endif
+]])dnl
+ b4_symbol_actions([printer])[
+}
+
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+]b4_function_define([yy_symbol_print],
+ [static void],
+ [[FILE *yyo], [yyo]],
+ [[int yytype], [yytype]],
+ [[YYSTYPE const * const yyvaluep], [yyvaluep]][]dnl
+b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
+m4_ifset([b4_parse_param], [, b4_parse_param]))[
+{
+ YYFPRINTF (yyo, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+]b4_locations_if([ YY_LOCATION_PRINT (yyo, *yylocationp);
+ YYFPRINTF (yyo, ": ");
+])dnl
+[ yy_symbol_value_print (yyo, yytype, yyvaluep]dnl
+b4_locations_if([, yylocationp])[]b4_user_args[);
+ YYFPRINTF (yyo, ")");
+}]dnl
+])
+
+
+## ---------------- ##
+## api.value.type. ##
+## ---------------- ##
+
+
+# ---------------------- #
+# api.value.type=union. #
+# ---------------------- #
+
+# b4_symbol_type_register(SYMBOL-NUM)
+# -----------------------------------
+# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag.
+# Extend the definition of %union's body (b4_union_members) with a
+# field of that type, and extend the symbol's "type" field to point to
+# the field name, instead of the type name.
+m4_define([b4_symbol_type_register],
+[m4_define([b4_symbol($1, type_tag)],
+ [b4_symbol_if([$1], [has_id],
+ [b4_symbol([$1], [id])],
+ [yytype_[]b4_symbol([$1], [number])])])dnl
+m4_append([b4_union_members],
+m4_expand([
+ b4_symbol_tag_comment([$1])dnl
+ b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
+])
+
+
+# b4_type_define_tag(SYMBOL1-NUM, ...)
+# ------------------------------------
+# For the batch of symbols SYMBOL1-NUM... (which all have the same
+# type), enhance the %union definition for each of them, and set
+# there "type" field to the field tag name, instead of the type name.
+m4_define([b4_type_define_tag],
+[b4_symbol_if([$1], [has_type],
+ [m4_map([b4_symbol_type_register], [$@])])
+])
+
+
+# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE])
+# ----------------------------------------------
+# Same of b4_symbol_value, but when api.value.type=union.
+m4_define([b4_symbol_value_union],
+[m4_ifval([$3],
+ [(*($3*)(&$1))],
+ [m4_ifval([$2],
+ [b4_symbol_if([$2], [has_type],
+ [($1.b4_symbol([$2], [type_tag]))],
+ [$1])],
+ [$1])])])
+
+
+# b4_value_type_setup_union
+# -------------------------
+# Setup support for api.value.type=union. Symbols are defined with a
+# type instead of a union member name: build the corresponding union,
+# and give the symbols their tag.
+m4_define([b4_value_type_setup_union],
+[m4_define([b4_union_members])
+b4_type_foreach([b4_type_define_tag])
+m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
+])
+
+
+# -------------------------- #
+# api.value.type = variant. #
+# -------------------------- #
+
+# b4_value_type_setup_variant
+# ---------------------------
+# Setup support for api.value.type=variant. By default, fail, specialized
+# by other skeletons.
+m4_define([b4_value_type_setup_variant],
+[b4_complain_at(b4_percent_define_get_loc([[api.value.type]]),
+ [['%s' does not support '%s']],
+ [b4_skeleton],
+ [%define api.value.type variant])])
+
+
+# _b4_value_type_setup_keyword
+# ----------------------------
+# api.value.type is defined with a keyword/string syntax. Check if
+# that is properly defined, and prepare its use.
+m4_define([_b4_value_type_setup_keyword],
+[b4_percent_define_check_values([[[[api.value.type]],
+ [[none]],
+ [[union]],
+ [[union-directive]],
+ [[variant]],
+ [[yystype]]]])dnl
+m4_case(b4_percent_define_get([[api.value.type]]),
+ [union], [b4_value_type_setup_union],
+ [variant], [b4_value_type_setup_variant])])
+
+
+# b4_value_type_setup
+# -------------------
+# Check if api.value.type is properly defined, and possibly prepare
+# its use.
+b4_define_silent([b4_value_type_setup],
+[# Define default value.
+b4_percent_define_ifdef([[api.value.type]], [],
+[# %union => api.value.type=union-directive
+m4_ifdef([b4_union_members],
+[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
+m4_define([b4_percent_define(api.value.type)], [union-directive])],
+[# no tag seen => api.value.type={int}
+m4_if(b4_tag_seen_flag, 0,
+[m4_define([b4_percent_define_kind(api.value.type)], [code])
+m4_define([b4_percent_define(api.value.type)], [int])],
+[# otherwise api.value.type=yystype
+m4_define([b4_percent_define_kind(api.value.type)], [keyword])
+m4_define([b4_percent_define(api.value.type)], [yystype])])])])
+
+# Set up.
+m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+ [keyword\|string], [_b4_value_type_setup_keyword])
+])
+
+
+## -------------- ##
+## Declarations. ##
+## -------------- ##
+
+
+# b4_value_type_define
+# --------------------
+m4_define([b4_value_type_define],
+[b4_value_type_setup[]dnl
+/* Value type. */
+m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+[code],
+[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
+typedef ]b4_percent_define_get([[api.value.type]])[ ]b4_api_PREFIX[STYPE;
+# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
+# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
+#endif
+]],
+[m4_bmatch(b4_percent_define_get([[api.value.type]]),
+[union\|union-directive],
+[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
+]b4_percent_define_get_syncline([[api.value.union.name]])[
+union ]b4_percent_define_get([[api.value.union.name]])[
+{
+]b4_user_union_members[
+};
+]b4_percent_define_get_syncline([[api.value.union.name]])[
+typedef union ]b4_percent_define_get([[api.value.union.name]])[ ]b4_api_PREFIX[STYPE;
+# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
+# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
+#endif
+]])])])
+
+
+# b4_location_type_define
+# -----------------------
+m4_define([b4_location_type_define],
+[[/* Location type. */
+#if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED
+typedef struct ]b4_api_PREFIX[LTYPE ]b4_api_PREFIX[LTYPE;
+struct ]b4_api_PREFIX[LTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
+# define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
+#endif
+]])
+
+
+# b4_declare_yylstype
+# -------------------
+# Declarations that might either go into the header (if --defines) or
+# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
+m4_define([b4_declare_yylstype],
+[b4_value_type_define[]b4_locations_if([
+b4_location_type_define])
+
+b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
+]b4_locations_if([[extern ]b4_api_PREFIX[LTYPE ]b4_prefix[lloc;]])])[]dnl
+])
+
+
+# b4_YYDEBUG_define
+# -----------------
+m4_define([b4_YYDEBUG_define],
+[[/* Debug traces. */
+]m4_if(b4_api_prefix, [yy],
+[[#ifndef YYDEBUG
+# define YYDEBUG ]b4_parse_trace_if([1], [0])[
+#endif]],
+[[#ifndef ]b4_api_PREFIX[DEBUG
+# if defined YYDEBUG
+#if YYDEBUG
+# define ]b4_api_PREFIX[DEBUG 1
+# else
+# define ]b4_api_PREFIX[DEBUG 0
+# endif
+# else /* ! defined YYDEBUG */
+# define ]b4_api_PREFIX[DEBUG ]b4_parse_trace_if([1], [0])[
+# endif /* ! defined YYDEBUG */
+#endif /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl
+])
+
+# b4_declare_yydebug
+# ------------------
+m4_define([b4_declare_yydebug],
+[b4_YYDEBUG_define[
+#if ]b4_api_PREFIX[DEBUG
+extern int ]b4_prefix[debug;
+#endif][]dnl
+])
+
+# b4_yylloc_default_define
+# ------------------------
+# Define YYLLOC_DEFAULT.
+m4_define([b4_yylloc_default_define],
+[[/* 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
+]])
+
+# b4_yy_location_print_define
+# ---------------------------
+# Define YY_LOCATION_PRINT.
+m4_define([b4_yy_location_print_define],
+[b4_locations_if([[
+/* 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 ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+YY_ATTRIBUTE_UNUSED
+]b4_function_define([yy_location_print_],
+ [static int],
+ [[FILE *yyo], [yyo]],
+ [[YYLTYPE const * const yylocp], [yylocp]])[
+{
+ int 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]],
+[[/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif]])
+])
+
+# b4_yyloc_default
+# ----------------
+# Expand to a possible default value for yylloc.
+m4_define([b4_yyloc_default],
+[[
+# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
+ = { ]m4_join([, ],
+ m4_defn([b4_location_initial_line]),
+ m4_defn([b4_location_initial_column]),
+ m4_defn([b4_location_initial_line]),
+ m4_defn([b4_location_initial_column]))[ }
+# endif
+]])
diff --git a/contrib/tools/bison/data/skeletons/glr.cc b/contrib/tools/bison/data/skeletons/glr.cc
new file mode 100644
index 0000000000..5621734163
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/glr.cc
@@ -0,0 +1,369 @@
+# C++ GLR skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2019 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/>.
+
+
+# This skeleton produces a C++ class that encapsulates a C glr parser.
+# This is in order to reduce the maintenance burden. The glr.c
+# skeleton is clean and pure enough so that there are no real
+# problems. The C++ interface is the same as that of lalr1.cc. In
+# fact, glr.c can replace yacc.c without the user noticing any
+# difference, and similarly for glr.cc replacing lalr1.cc.
+#
+# The passing of parse-params
+#
+# The additional arguments are stored as members of the parser
+# object, yyparser. The C routines need to carry yyparser
+# throughout the C parser; that's easy: make yyparser an
+# additional parse-param. But because the C++ skeleton needs to
+# know the "real" original parse-param, we save them
+# (b4_parse_param_orig). Note that b4_parse_param is overquoted
+# (and c.m4 strips one level of quotes). This is a PITA, and
+# explains why there are so many levels of quotes.
+#
+# The locations
+#
+# We use location.cc just like lalr1.cc, but because glr.c stores
+# the locations in a union, the position and location classes
+# must not have a constructor. Therefore, contrary to lalr1.cc, we
+# must not define "b4_location_constructors". As a consequence the
+# user must initialize the first positions (in particular the
+# filename member).
+
+# We require a pure interface.
+m4_define([b4_pure_flag], [1])
+
+m4_include(b4_skeletonsdir/[c++.m4])
+b4_bison_locations_if([m4_include(b4_skeletonsdir/[location.cc])])
+
+m4_define([b4_parser_class],
+ [b4_percent_define_get([[api.parser.class]])])
+
+# Save the parse parameters.
+m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
+
+# b4_parse_param_wrap
+# -------------------
+# New ones.
+m4_ifset([b4_parse_param],
+[m4_define([b4_parse_param_wrap],
+ [[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]],]
+m4_defn([b4_parse_param]))],
+[m4_define([b4_parse_param_wrap],
+ [[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]])
+])
+
+
+# b4_yy_symbol_print_define
+# -------------------------
+# Bypass the default implementation to generate the "yy_symbol_print"
+# and "yy_symbol_value_print" functions.
+m4_define([b4_yy_symbol_print_define],
+[[
+/*--------------------.
+| Print this symbol. |
+`--------------------*/
+
+]b4_function_define([yy_symbol_print],
+ [static void],
+ [[FILE *], []],
+ [[int yytype], [yytype]],
+ [[const ]b4_namespace_ref::b4_parser_class[::semantic_type *yyvaluep],
+ [yyvaluep]][]dnl
+b4_locations_if([,
+ [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp],
+ [yylocationp]]]),
+ b4_parse_param)[
+{
+]b4_parse_param_use[]dnl
+[ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
+}
+]])[
+
+# Hijack the initial action to initialize the locations.
+]b4_bison_locations_if([m4_define([b4_initial_action],
+[yylloc.initialize ();]m4_ifdef([b4_initial_action], [
+m4_defn([b4_initial_action])]))])[
+
+# Hijack the post prologue to declare yyerror.
+]m4_append([b4_post_prologue],
+[b4_syncline([@oline@], [@ofile@])[
+]b4_function_declare([yyerror],
+ [static void],b4_locations_if([
+ [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp],
+ [yylocationp]],])
+ b4_parse_param,
+ [[const char* msg], [msg]])])[
+
+
+#undef yynerrs
+#undef yychar
+#undef yylval]b4_locations_if([
+#undef yylloc])
+
+m4_if(b4_prefix, [yy], [],
+[[/* Substitute the variable and function names. */
+#define yyparse ]b4_prefix[parse
+#define yylex ]b4_prefix[lex
+#define yyerror ]b4_prefix[error
+#define yydebug ]b4_prefix[debug]]b4_pure_if([], [[
+#define yylval ]b4_prefix[lval
+#define yychar ]b4_prefix[char
+#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
+#define yylloc ]b4_prefix[lloc]])]))
+
+# Hijack the epilogue to define implementations (yyerror, parser member
+# functions etc.).
+m4_append([b4_epilogue],
+[b4_syncline([@oline@], [@ofile@])[
+
+/*------------------.
+| Report an error. |
+`------------------*/
+
+]b4_function_define([yyerror],
+ [static void],b4_locations_if([
+ [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp],
+ [yylocationp]],])
+ b4_parse_param,
+ [[const char* msg], [msg]])[
+{
+]b4_parse_param_use[]dnl
+[ yyparser.error (]b4_locations_if([[*yylocationp, ]])[msg);
+}
+
+
+]b4_namespace_open[
+]dnl In this section, the parse params are the original parse_params.
+m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
+[ /// Build a parser object.
+ ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
+ :])[
+#if ]b4_api_PREFIX[DEBUG
+ ]m4_ifset([b4_parse_param], [ ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
+#endif]b4_parse_param_cons[
+ {}
+
+ ]b4_parser_class::~b4_parser_class[ ()
+ {}
+
+ ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+ {}
+
+ int
+ ]b4_parser_class[::operator() ()
+ {
+ return parse ();
+ }
+
+ int
+ ]b4_parser_class[::parse ()
+ {
+ return ::yyparse (*this]b4_user_args[);
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ /*--------------------.
+ | Print this symbol. |
+ `--------------------*/
+
+ void
+ ]b4_parser_class[::yy_symbol_value_print_ (int yytype,
+ const semantic_type* yyvaluep]b4_locations_if([[,
+ const location_type* yylocationp]])[)
+ {]b4_locations_if([[
+ YYUSE (yylocationp);]])[
+ YYUSE (yyvaluep);
+ std::ostream& yyo = debug_stream ();
+ std::ostream& yyoutput = yyo;
+ YYUSE (yyoutput);
+ ]b4_symbol_actions([printer])[
+ }
+
+
+ void
+ ]b4_parser_class[::yy_symbol_print_ (int yytype,
+ const semantic_type* yyvaluep]b4_locations_if([[,
+ const location_type* yylocationp]])[)
+ {
+ *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
+ << ' ' << yytname[yytype] << " ("]b4_locations_if([[
+ << *yylocationp << ": "]])[;
+ yy_symbol_value_print_ (yytype, yyvaluep]b4_locations_if([[, yylocationp]])[);
+ *yycdebug_ << ')';
+ }
+
+ std::ostream&
+ ]b4_parser_class[::debug_stream () const
+ {
+ return *yycdebug_;
+ }
+
+ void
+ ]b4_parser_class[::set_debug_stream (std::ostream& o)
+ {
+ yycdebug_ = &o;
+ }
+
+
+ ]b4_parser_class[::debug_level_type
+ ]b4_parser_class[::debug_level () const
+ {
+ return yydebug;
+ }
+
+ void
+ ]b4_parser_class[::set_debug_level (debug_level_type l)
+ {
+ // Actually, it is yydebug which is really used.
+ yydebug = l;
+ }
+
+#endif
+]m4_popdef([b4_parse_param])dnl
+b4_namespace_close
+])
+
+
+# b4_shared_declarations(hh|cc)
+# -----------------------------
+# Declaration that might either go into the header (if --defines, $1 = hh)
+# or in the implementation file.
+m4_define([b4_shared_declarations],
+[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
+b4_percent_code_get([[requires]])[
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+]b4_cxx_portability[
+]m4_ifdef([b4_location_include],
+ [[# include ]b4_location_include])[
+]b4_variant_if([b4_variant_includes])[
+
+]b4_attribute_define[
+]b4_null_define[
+
+// Whether we are compiled with exception support.
+#ifndef YY_EXCEPTIONS
+# if defined __GNUC__ && !defined __EXCEPTIONS
+# define YY_EXCEPTIONS 0
+# else
+# define YY_EXCEPTIONS 1
+# endif
+#endif
+
+]b4_YYDEBUG_define[
+
+]b4_namespace_open[
+
+]b4_bison_locations_if([m4_ifndef([b4_location_file],
+ [b4_location_define])])[
+
+ /// A Bison parser.
+ class ]b4_parser_class[
+ {
+ public:
+]b4_public_types_declare[
+
+ /// Build a parser object.
+ ]b4_parser_class[ (]b4_parse_param_decl[);
+ virtual ~]b4_parser_class[ ();
+
+ /// Parse. An alias for parse ().
+ /// \returns 0 iff parsing succeeded.
+ int operator() ();
+
+ /// Parse.
+ /// \returns 0 iff parsing succeeded.
+ virtual int parse ();
+
+#if ]b4_api_PREFIX[DEBUG
+ /// The current debugging stream.
+ std::ostream& debug_stream () const;
+ /// Set the current debugging stream.
+ void set_debug_stream (std::ostream &);
+
+ /// Type for debugging levels.
+ typedef int debug_level_type;
+ /// The current debugging level.
+ debug_level_type debug_level () const;
+ /// Set the current debugging level.
+ void set_debug_level (debug_level_type l);
+#endif
+
+ /// Report a syntax error.]b4_locations_if([[
+ /// \param loc where the syntax error is found.]])[
+ /// \param msg a description of the syntax error.
+ virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
+
+# if ]b4_api_PREFIX[DEBUG
+ public:
+ /// \brief Report a symbol value on the debug stream.
+ /// \param yytype The token type.
+ /// \param yyvaluep Its semantic value.]b4_locations_if([[
+ /// \param yylocationp Its location.]])[
+ virtual void yy_symbol_value_print_ (int yytype,
+ const semantic_type* yyvaluep]b4_locations_if([[,
+ const location_type* yylocationp]])[);
+ /// \brief Report a symbol on the debug stream.
+ /// \param yytype The token type.
+ /// \param yyvaluep Its semantic value.]b4_locations_if([[
+ /// \param yylocationp Its location.]])[
+ virtual void yy_symbol_print_ (int yytype,
+ const semantic_type* yyvaluep]b4_locations_if([[,
+ const location_type* yylocationp]])[);
+ private:
+ // Debugging.
+ std::ostream* yycdebug_;
+#endif
+
+]b4_parse_param_vars[
+ };
+
+]dnl Redirections for glr.c.
+b4_percent_define_flag_if([[global_tokens_and_yystype]],
+[b4_token_defines])
+[
+#ifndef ]b4_api_PREFIX[STYPE
+# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
+#endif
+#ifndef ]b4_api_PREFIX[LTYPE
+# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
+#endif
+
+]b4_namespace_close[
+]b4_percent_code_get([[provides]])[
+]m4_popdef([b4_parse_param])dnl
+])
+
+b4_defines_if(
+[b4_output_begin([b4_spec_defines_file])
+b4_copyright([Skeleton interface for Bison GLR parsers in C++],
+ [2002-2015, 2018-2019])[
+// C++ GLR parser skeleton written by Akim Demaille.
+
+]b4_disclaimer[
+]b4_cpp_guard_open([b4_spec_defines_file])[
+]b4_shared_declarations[
+]b4_cpp_guard_close([b4_spec_defines_file])[
+]b4_output_end])
+
+# Let glr.c (and b4_shared_declarations) believe that the user
+# arguments include the parser itself.
+m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_wrap]))
+m4_include(b4_skeletonsdir/[glr.c])
+m4_popdef([b4_parse_param])
diff --git a/contrib/tools/bison/data/skeletons/lalr1.cc b/contrib/tools/bison/data/skeletons/lalr1.cc
new file mode 100644
index 0000000000..09f4259f28
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/lalr1.cc
@@ -0,0 +1,1247 @@
+# C++ skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2019 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/>.
+
+m4_include(b4_skeletonsdir/[c++.m4])
+
+# api.value.type=variant is valid.
+m4_define([b4_value_type_setup_variant])
+
+
+# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
+# --------------------------------------------------------------
+# Declare "parser::yy<TABLE-NAME>_" whose contents is CONTENT.
+m4_define([b4_integral_parser_table_declare],
+[m4_ifval([$3], [b4_comment([$3], [ ])
+])dnl
+ static const b4_int_type_for([$2]) yy$1_[[]];dnl
+])
+
+# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
+# -------------------------------------------------------------
+# Define "parser::yy<TABLE-NAME>_" whose contents is CONTENT.
+m4_define([b4_integral_parser_table_define],
+[ const b4_int_type_for([$2])
+ b4_parser_class::yy$1_[[]] =
+ {
+ $2
+ };dnl
+])
+
+# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
+# -------------------------------------------------
+# Same as b4_symbol_value, but used in a template method. It makes
+# a difference when using variants. Note that b4_value_type_setup_union
+# overrides b4_symbol_value, so we must override it again.
+m4_copy([b4_symbol_value], [b4_symbol_value_template])
+m4_append([b4_value_type_setup_union],
+[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
+
+# b4_lhs_value(SYMBOL-NUM, [TYPE])
+# --------------------------------
+# See README.
+m4_define([b4_lhs_value],
+[b4_symbol_value([yylhs.value], [$1], [$2])])
+
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[yylhs.location])
+
+
+# b4_rhs_data(RULE-LENGTH, POS)
+# -----------------------------
+# See README.
+m4_define([b4_rhs_data],
+[yystack_@{b4_subtract($@)@}])
+
+
+# b4_rhs_state(RULE-LENGTH, POS)
+# ------------------------------
+# The state corresponding to the symbol #POS, where the current
+# rule has RULE-LENGTH symbols on RHS.
+m4_define([b4_rhs_state],
+[b4_rhs_data([$1], [$2]).state])
+
+
+# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
+# --------------------------------------------------
+# See README.
+m4_define([_b4_rhs_value],
+[b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3], [$4])])
+
+m4_define([b4_rhs_value],
+[b4_percent_define_ifdef([api.value.automove],
+ [YY_MOVE (_b4_rhs_value($@))],
+ [_b4_rhs_value($@)])])
+
+
+# b4_rhs_location(RULE-LENGTH, POS)
+# ---------------------------------
+# Expansion of @POS, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+[b4_rhs_data([$1], [$2]).location])
+
+
+# b4_symbol_action(SYMBOL-NUM, KIND)
+# ----------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# Same as in C, but using references instead of pointers.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
+b4_dollar_pushdef([yysym.value],
+ [$1],
+ [],
+ [yysym.location])dnl
+ _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
+ b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])
+ break;
+
+m4_popdef([b4_symbol_value])[]dnl
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_lex
+# ------
+# Call yylex.
+m4_define([b4_lex],
+[b4_token_ctor_if(
+[b4_function_call([yylex],
+ [symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))],
+[b4_function_call([yylex], [int],
+ [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
+b4_locations_if([, [[location*], [&yyla.location]]])dnl
+m4_ifdef([b4_lex_param], [, ]b4_lex_param))])])
+
+
+m4_pushdef([b4_copyright_years],
+ [2002-2015, 2018-2019])
+
+m4_define([b4_parser_class],
+ [b4_percent_define_get([[api.parser.class]])])
+
+b4_bison_locations_if([# Backward compatibility.
+ m4_define([b4_location_constructors])
+ m4_include(b4_skeletonsdir/[location.cc])])
+m4_include(b4_skeletonsdir/[stack.hh])
+b4_variant_if([m4_include(b4_skeletonsdir/[variant.hh])])
+
+
+# b4_shared_declarations(hh|cc)
+# -----------------------------
+# Declaration that might either go into the header (if --defines, $1 = hh)
+# or in the implementation file.
+m4_define([b4_shared_declarations],
+[b4_percent_code_get([[requires]])[
+]b4_parse_assert_if([# include <cassert>])[
+# include <cstdlib> // std::abort
+# include <iostream>
+# include <stdexcept>
+# include <string>
+# include <vector>
+
+]b4_cxx_portability[
+]m4_ifdef([b4_location_include],
+ [[# include ]b4_location_include])[
+]b4_variant_if([b4_variant_includes])[
+
+]b4_attribute_define[
+]b4_null_define[
+
+]b4_YYDEBUG_define[
+
+]b4_namespace_open[
+
+]b4_bison_locations_if([m4_ifndef([b4_location_file],
+ [b4_location_define])])[
+
+ /// A Bison parser.
+ class ]b4_parser_class[
+ {
+ public:
+]b4_public_types_declare[
+]b4_symbol_type_define[
+ /// Build a parser object.
+ ]b4_parser_class[ (]b4_parse_param_decl[);
+ virtual ~]b4_parser_class[ ();
+
+ /// Parse. An alias for parse ().
+ /// \returns 0 iff parsing succeeded.
+ int operator() ();
+
+ /// Parse.
+ /// \returns 0 iff parsing succeeded.
+ virtual int parse ();
+
+#if ]b4_api_PREFIX[DEBUG
+ /// The current debugging stream.
+ std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
+ /// Set the current debugging stream.
+ void set_debug_stream (std::ostream &);
+
+ /// Type for debugging levels.
+ typedef int debug_level_type;
+ /// The current debugging level.
+ debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
+ /// Set the current debugging level.
+ void set_debug_level (debug_level_type l);
+#endif
+
+ /// Report a syntax error.]b4_locations_if([[
+ /// \param loc where the syntax error is found.]])[
+ /// \param msg a description of the syntax error.
+ virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
+
+ /// Report a syntax error.
+ void error (const syntax_error& err);
+
+]b4_token_constructor_define[
+
+ private:
+ /// This class is not copyable.
+ ]b4_parser_class[ (const ]b4_parser_class[&);
+ ]b4_parser_class[& operator= (const ]b4_parser_class[&);
+
+ /// State numbers.
+ typedef int state_type;
+
+ /// Generate an error message.
+ /// \param yystate the state where the error occurred.
+ /// \param yyla the lookahead token.
+ virtual std::string yysyntax_error_ (state_type yystate,
+ const symbol_type& yyla) const;
+
+ /// Compute post-reduction state.
+ /// \param yystate the current state
+ /// \param yysym the nonterminal to push on the stack
+ state_type yy_lr_goto_state_ (state_type yystate, int yysym);
+
+ /// Whether the given \c yypact_ value indicates a defaulted state.
+ /// \param yyvalue the value to check
+ static bool yy_pact_value_is_default_ (int yyvalue);
+
+ /// Whether the given \c yytable_ value indicates a syntax error.
+ /// \param yyvalue the value to check
+ static bool yy_table_value_is_error_ (int yyvalue);
+
+ static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
+ static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
+
+ /// Convert a scanner token number \a t to a symbol number.
+ static token_number_type yytranslate_ (]b4_token_ctor_if([token_type], [int])[ t);
+
+ // Tables.
+]b4_parser_tables_declare[]b4_error_verbose_if([
+
+ /// Convert the symbol name \a n to a form suitable for a diagnostic.
+ static std::string yytnamerr_ (const char *n);])[
+
+]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
+ /// For a symbol, its name in clear.
+ static const char* const yytname_[];
+]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
+]b4_integral_parser_table_declare([rline], [b4_rline],
+ [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
+ /// Report on the debug stream that the rule \a r is going to be reduced.
+ virtual void yy_reduce_print_ (int r);
+ /// Print the state stack on the debug stream.
+ virtual void yystack_print_ ();
+
+ /// Debugging level.
+ int yydebug_;
+ /// Debug stream.
+ std::ostream* yycdebug_;
+
+ /// \brief Display a symbol type, value and location.
+ /// \param yyo The output stream.
+ /// \param yysym The symbol.
+ template <typename Base>
+ void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;
+#endif
+
+ /// \brief Reclaim the memory associated to a symbol.
+ /// \param yymsg Why this token is reclaimed.
+ /// If null, print nothing.
+ /// \param yysym The symbol.
+ template <typename Base>
+ void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
+
+ private:
+ /// Type access provider for state based symbols.
+ struct by_state
+ {
+ /// Default constructor.
+ by_state () YY_NOEXCEPT;
+
+ /// The symbol type as needed by the constructor.
+ typedef state_type kind_type;
+
+ /// Constructor.
+ by_state (kind_type s) YY_NOEXCEPT;
+
+ /// Copy constructor.
+ by_state (const by_state& that) YY_NOEXCEPT;
+
+ /// Record that this symbol is empty.
+ void clear () YY_NOEXCEPT;
+
+ /// Steal the symbol type from \a that.
+ void move (by_state& that);
+
+ /// The (internal) type number (corresponding to \a state).
+ /// \a empty_symbol when empty.
+ symbol_number_type type_get () const YY_NOEXCEPT;
+
+ /// The state number used to denote an empty symbol.
+ enum { empty_state = -1 };
+
+ /// The state.
+ /// \a empty when empty.
+ state_type state;
+ };
+
+ /// "Internal" symbol: element of the stack.
+ struct stack_symbol_type : basic_symbol<by_state>
+ {
+ /// Superclass.
+ typedef basic_symbol<by_state> super_type;
+ /// Construct an empty symbol.
+ stack_symbol_type ();
+ /// Move or copy construction.
+ stack_symbol_type (YY_RVREF (stack_symbol_type) that);
+ /// Steal the contents from \a sym to build this.
+ stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) sym);
+#if YY_CPLUSPLUS < 201103L
+ /// Assignment, needed by push_back by some old implementations.
+ /// Moves the contents of that.
+ stack_symbol_type& operator= (stack_symbol_type& that);
+#endif
+ };
+
+]b4_stack_define[
+
+ /// Stack type.
+ typedef stack<stack_symbol_type> stack_type;
+
+ /// The stack.
+ stack_type yystack_;
+
+ /// Push a new state on the stack.
+ /// \param m a debug message to display
+ /// if null, no trace is output.
+ /// \param sym the symbol
+ /// \warning the contents of \a s.value is stolen.
+ void yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym);
+
+ /// Push a new look ahead token on the state on the stack.
+ /// \param m a debug message to display
+ /// if null, no trace is output.
+ /// \param s the state
+ /// \param sym the symbol (for its value and location).
+ /// \warning the contents of \a sym.value is stolen.
+ void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym);
+
+ /// Pop \a n symbols from the stack.
+ void yypop_ (int n = 1);
+
+ /// Constants.
+ enum
+ {
+ yyeof_ = 0,
+ yylast_ = ]b4_last[, ///< Last index in yytable_.
+ yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols.
+ yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
+ yyterror_ = 1,
+ yyerrcode_ = 256,
+ yyntokens_ = ]b4_tokens_number[ ///< Number of tokens.
+ };
+
+]b4_parse_param_vars[
+ };
+
+]b4_token_ctor_if([b4_yytranslate_define([$1])[
+]b4_public_types_define([$1])])[
+]b4_namespace_close[
+
+]b4_percent_define_flag_if([[global_tokens_and_yystype]],
+[b4_token_defines
+
+#ifndef ]b4_api_PREFIX[STYPE
+ // Redirection for backward compatibility.
+# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class::semantic_type
+#endif
+])[
+]b4_percent_code_get([[provides]])[
+]])
+
+## -------------- ##
+## Output files. ##
+## -------------- ##
+
+b4_defines_if(
+[b4_output_begin([b4_spec_defines_file])
+b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
+[
+/**
+ ** \file ]b4_spec_defines_file[
+ ** Define the ]b4_namespace_ref[::parser class.
+ */
+
+// C++ LALR(1) parser skeleton written by Akim Demaille.
+
+]b4_disclaimer[
+]b4_cpp_guard_open([b4_spec_defines_file])[
+]b4_shared_declarations(hh)[
+]b4_cpp_guard_close([b4_spec_defines_file])
+b4_output_end
+])
+
+
+b4_output_begin([b4_parser_file_name])[
+]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])[
+]b4_disclaimer[
+]b4_percent_code_get([[top]])[]dnl
+m4_if(b4_prefix, [yy], [],
+[
+// Take the name prefix into account.
+[#]define yylex b4_prefix[]lex])[
+
+]b4_user_pre_prologue[
+
+]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]],
+ [b4_shared_declarations([cc])])[
+
+]b4_user_post_prologue[
+]b4_percent_code_get[
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+// Whether we are compiled with exception support.
+#ifndef YY_EXCEPTIONS
+# if defined __GNUC__ && !defined __EXCEPTIONS
+# define YY_EXCEPTIONS 0
+# else
+# define YY_EXCEPTIONS 1
+# endif
+#endif
+
+]b4_locations_if([dnl
+[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
+]b4_yylloc_default_define])[
+
+// Suppress unused-variable warnings by "using" E.
+#define YYUSE(E) ((void) (E))
+
+// Enable debugging if requested.
+#if ]b4_api_PREFIX[DEBUG
+
+// A pseudo ostream that takes yydebug_ into account.
+# define YYCDEBUG if (yydebug_) (*yycdebug_)
+
+# define YY_SYMBOL_PRINT(Title, Symbol) \
+ do { \
+ if (yydebug_) \
+ { \
+ *yycdebug_ << Title << ' '; \
+ yy_print_ (*yycdebug_, Symbol); \
+ *yycdebug_ << '\n'; \
+ } \
+ } while (false)
+
+# define YY_REDUCE_PRINT(Rule) \
+ do { \
+ if (yydebug_) \
+ yy_reduce_print_ (Rule); \
+ } while (false)
+
+# define YY_STACK_PRINT() \
+ do { \
+ if (yydebug_) \
+ yystack_print_ (); \
+ } while (false)
+
+#else // !]b4_api_PREFIX[DEBUG
+
+# define YYCDEBUG if (false) std::cerr
+# define YY_SYMBOL_PRINT(Title, Symbol) YYUSE (Symbol)
+# define YY_REDUCE_PRINT(Rule) static_cast<void> (0)
+# define YY_STACK_PRINT() static_cast<void> (0)
+
+#endif // !]b4_api_PREFIX[DEBUG
+
+#define yyerrok (yyerrstatus_ = 0)
+#define yyclearin (yyla.clear ())
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYRECOVERING() (!!yyerrstatus_)
+
+]b4_namespace_open[]b4_error_verbose_if([[
+
+ /* Return YYSTR after stripping away unnecessary quotes and
+ backslashes, so that it's suitable for yyerror. The heuristic is
+ that double-quoting is unnecessary unless the string contains an
+ apostrophe, a comma, or backslash (other than backslash-backslash).
+ YYSTR is taken from yytname. */
+ std::string
+ ]b4_parser_class[::yytnamerr_ (const char *yystr)
+ {
+ if (*yystr == '"')
+ {
+ std::string yyr;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ else
+ goto append;
+
+ append:
+ default:
+ yyr += *yyp;
+ break;
+
+ case '"':
+ return yyr;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ return yystr;
+ }
+]])[
+
+ /// Build a parser object.
+ ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
+ :])[
+#if ]b4_api_PREFIX[DEBUG
+ ]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false),
+ yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
+#endif]b4_parse_param_cons[
+ {}
+
+ ]b4_parser_class::~b4_parser_class[ ()
+ {}
+
+ ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+ {}
+
+ /*---------------.
+ | Symbol types. |
+ `---------------*/
+
+]b4_token_ctor_if([], [b4_public_types_define([cc])])[
+
+ // by_state.
+ ]b4_parser_class[::by_state::by_state () YY_NOEXCEPT
+ : state (empty_state)
+ {}
+
+ ]b4_parser_class[::by_state::by_state (const by_state& that) YY_NOEXCEPT
+ : state (that.state)
+ {}
+
+ void
+ ]b4_parser_class[::by_state::clear () YY_NOEXCEPT
+ {
+ state = empty_state;
+ }
+
+ void
+ ]b4_parser_class[::by_state::move (by_state& that)
+ {
+ state = that.state;
+ that.clear ();
+ }
+
+ ]b4_parser_class[::by_state::by_state (state_type s) YY_NOEXCEPT
+ : state (s)
+ {}
+
+ ]b4_parser_class[::symbol_number_type
+ ]b4_parser_class[::by_state::type_get () const YY_NOEXCEPT
+ {
+ if (state == empty_state)
+ return empty_symbol;
+ else
+ return yystos_[state];
+ }
+
+ ]b4_parser_class[::stack_symbol_type::stack_symbol_type ()
+ {}
+
+ ]b4_parser_class[::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
+ : super_type (YY_MOVE (that.state)]b4_variant_if([], [, YY_MOVE (that.value)])b4_locations_if([, YY_MOVE (that.location)])[)
+ {]b4_variant_if([
+ b4_symbol_variant([that.type_get ()],
+ [value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[
+#if 201103L <= YY_CPLUSPLUS
+ // that is emptied.
+ that.state = empty_state;
+#endif
+ }
+
+ ]b4_parser_class[::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
+ : super_type (s]b4_variant_if([], [, YY_MOVE (that.value)])[]b4_locations_if([, YY_MOVE (that.location)])[)
+ {]b4_variant_if([
+ b4_symbol_variant([that.type_get ()],
+ [value], [move], [YY_MOVE (that.value)])])[
+ // that is emptied.
+ that.type = empty_symbol;
+ }
+
+#if YY_CPLUSPLUS < 201103L
+ ]b4_parser_class[::stack_symbol_type&
+ ]b4_parser_class[::stack_symbol_type::operator= (stack_symbol_type& that)
+ {
+ state = that.state;
+ ]b4_variant_if([b4_symbol_variant([that.type_get ()],
+ [value], [move], [that.value])],
+ [[value = that.value;]])[]b4_locations_if([
+ location = that.location;])[
+ // that is emptied.
+ that.state = empty_state;
+ return *this;
+ }
+#endif
+
+ template <typename Base>
+ void
+ ]b4_parser_class[::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+ {
+ if (yymsg)
+ YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
+
+ // User destructor.
+ b4_symbol_actions([destructor], [yysym.type_get ()])])[
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ template <typename Base>
+ void
+ ]b4_parser_class[::yy_print_ (std::ostream& yyo,
+ const basic_symbol<Base>& yysym) const
+ {
+ std::ostream& yyoutput = yyo;
+ YYUSE (yyoutput);
+ symbol_number_type yytype = yysym.type_get ();
+#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408
+ // Avoid a (spurious) G++ 4.8 warning about "array subscript is
+ // below array bounds".
+ if (yysym.empty ())
+ std::abort ();
+#endif
+ yyo << (yytype < yyntokens_ ? "token" : "nterm")
+ << ' ' << yytname_[yytype] << " ("]b4_locations_if([
+ << yysym.location << ": "])[;
+ ]b4_symbol_actions([printer])[
+ yyo << ')';
+ }
+#endif
+
+ void
+ ]b4_parser_class[::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)
+ {
+ if (m)
+ YY_SYMBOL_PRINT (m, sym);
+ yystack_.push (YY_MOVE (sym));
+ }
+
+ void
+ ]b4_parser_class[::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
+ {
+#if 201103L <= YY_CPLUSPLUS
+ yypush_ (m, stack_symbol_type (s, std::move (sym)));
+#else
+ stack_symbol_type ss (s, sym);
+ yypush_ (m, ss);
+#endif
+ }
+
+ void
+ ]b4_parser_class[::yypop_ (int n)
+ {
+ yystack_.pop (n);
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ std::ostream&
+ ]b4_parser_class[::debug_stream () const
+ {
+ return *yycdebug_;
+ }
+
+ void
+ ]b4_parser_class[::set_debug_stream (std::ostream& o)
+ {
+ yycdebug_ = &o;
+ }
+
+
+ ]b4_parser_class[::debug_level_type
+ ]b4_parser_class[::debug_level () const
+ {
+ return yydebug_;
+ }
+
+ void
+ ]b4_parser_class[::set_debug_level (debug_level_type l)
+ {
+ yydebug_ = l;
+ }
+#endif // ]b4_api_PREFIX[DEBUG
+
+ ]b4_parser_class[::state_type
+ ]b4_parser_class[::yy_lr_goto_state_ (state_type yystate, int yysym)
+ {
+ int yyr = yypgoto_[yysym - yyntokens_] + yystate;
+ if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+ return yytable_[yyr];
+ else
+ return yydefgoto_[yysym - yyntokens_];
+ }
+
+ bool
+ ]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue)
+ {
+ return yyvalue == yypact_ninf_;
+ }
+
+ bool
+ ]b4_parser_class[::yy_table_value_is_error_ (int yyvalue)
+ {
+ return yyvalue == yytable_ninf_;
+ }
+
+ int
+ ]b4_parser_class[::operator() ()
+ {
+ return parse ();
+ }
+
+ int
+ ]b4_parser_class[::parse ()
+ {
+ // State.
+ int yyn;
+ /// Length of the RHS of the rule being reduced.
+ int yylen = 0;
+
+ // Error handling.
+ int yynerrs_ = 0;
+ int yyerrstatus_ = 0;
+
+ /// The lookahead symbol.
+ symbol_type yyla;]b4_locations_if([[
+
+ /// The locations where the error started and ended.
+ stack_symbol_type yyerror_range[3];]])[
+
+ /// The return value of parse ().
+ int yyresult;
+
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {
+ YYCDEBUG << "Starting parse\n";
+
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
+ b4_user_initial_action
+b4_dollar_popdef])[]dnl
+
+ [ /* Initialize the stack. The initial state will be set in
+ yynewstate, since the latter expects the semantical and the
+ location values to have been already stored, initialize these
+ stacks with a primary value. */
+ yystack_.clear ();
+ yypush_ (YY_NULLPTR, 0, YY_MOVE (yyla));
+
+ /*-----------------------------------------------.
+ | yynewstate -- push a new symbol on the stack. |
+ `-----------------------------------------------*/
+ yynewstate:
+ YYCDEBUG << "Entering state " << yystack_[0].state << '\n';
+
+ // Accept?
+ if (yystack_[0].state == yyfinal_)
+ YYACCEPT;
+
+ goto yybackup;
+
+
+ /*-----------.
+ | yybackup. |
+ `-----------*/
+ yybackup:
+ // Try to take a decision without lookahead.
+ yyn = yypact_[yystack_[0].state];
+ if (yy_pact_value_is_default_ (yyn))
+ goto yydefault;
+
+ // Read a lookahead token.
+ if (yyla.empty ())
+ {
+ YYCDEBUG << "Reading a token: ";
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {]b4_token_ctor_if([[
+ symbol_type yylookahead (]b4_lex[);
+ yyla.move (yylookahead);]], [[
+ yyla.type = yytranslate_ (]b4_lex[);]])[
+ }
+#if YY_EXCEPTIONS
+ catch (const syntax_error& yyexc)
+ {
+ YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
+ error (yyexc);
+ goto yyerrlab1;
+ }
+#endif // YY_EXCEPTIONS
+ }
+ YY_SYMBOL_PRINT ("Next token is", yyla);
+
+ /* If the proper action on seeing token YYLA.TYPE is to reduce or
+ to detect an error, take that action. */
+ yyn += yyla.type_get ();
+ if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
+ goto yydefault;
+
+ // Reduce or error.
+ yyn = yytable_[yyn];
+ if (yyn <= 0)
+ {
+ if (yy_table_value_is_error_ (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ // Count tokens shifted since error; after three, turn off error status.
+ if (yyerrstatus_)
+ --yyerrstatus_;
+
+ // Shift the lookahead token.
+ yypush_ ("Shifting", yyn, YY_MOVE (yyla));
+ goto yynewstate;
+
+
+ /*-----------------------------------------------------------.
+ | yydefault -- do the default action for the current state. |
+ `-----------------------------------------------------------*/
+ yydefault:
+ yyn = yydefact_[yystack_[0].state];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+ /*-----------------------------.
+ | yyreduce -- do a reduction. |
+ `-----------------------------*/
+ yyreduce:
+ yylen = yyr2_[yyn];
+ {
+ stack_symbol_type yylhs;
+ yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
+ /* Variants are always initialized to an empty instance of the
+ correct type. The default '$$ = $1' action is NOT applied
+ when using variants. */
+ b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [
+ /* If YYLEN is nonzero, implement the default value of the
+ action: '$$ = $1'. Otherwise, use the top of the stack.
+
+ Otherwise, the following line sets YYLHS.VALUE to garbage.
+ This behavior is undocumented and Bison users should not rely
+ upon it. */
+ if (yylen)
+ yylhs.value = yystack_@{yylen - 1@}.value;
+ else
+ yylhs.value = yystack_@{0@}.value;])[
+]b4_locations_if([dnl
+[
+ // Default location.
+ {
+ stack_type::slice range (yystack_, yylen);
+ YYLLOC_DEFAULT (yylhs.location, range, yylen);
+ yyerror_range[1].location = yylhs.location;
+ }]])[
+
+ // Perform the reduction.
+ YY_REDUCE_PRINT (yyn);
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {
+ switch (yyn)
+ {
+]b4_user_actions[
+ default:
+ break;
+ }
+ }
+#if YY_EXCEPTIONS
+ catch (const syntax_error& yyexc)
+ {
+ YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
+ error (yyexc);
+ YYERROR;
+ }
+#endif // YY_EXCEPTIONS
+ YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+ yypop_ (yylen);
+ yylen = 0;
+ YY_STACK_PRINT ();
+
+ // Shift the result of the reduction.
+ yypush_ (YY_NULLPTR, YY_MOVE (yylhs));
+ }
+ goto yynewstate;
+
+
+ /*--------------------------------------.
+ | yyerrlab -- here on detecting error. |
+ `--------------------------------------*/
+ yyerrlab:
+ // If not already recovering from an error, report this error.
+ if (!yyerrstatus_)
+ {
+ ++yynerrs_;
+ error (]b4_join(b4_locations_if([yyla.location]),
+ [[yysyntax_error_ (yystack_[0].state, yyla)]])[);
+ }
+
+]b4_locations_if([[
+ yyerror_range[1].location = yyla.location;]])[
+ if (yyerrstatus_ == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ // Return failure if at end of input.
+ if (yyla.type_get () == yyeof_)
+ YYABORT;
+ else if (!yyla.empty ())
+ {
+ yy_destroy_ ("Error: discarding", yyla);
+ yyla.clear ();
+ }
+ }
+
+ // Else will try to reuse lookahead token after shifting the error token.
+ goto yyerrlab1;
+
+
+ /*---------------------------------------------------.
+ | yyerrorlab -- error raised explicitly by YYERROR. |
+ `---------------------------------------------------*/
+ yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and
+ the label yyerrorlab therefore never appears in user code. */
+ if (false)
+ YYERROR;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ yypop_ (yylen);
+ yylen = 0;
+ goto yyerrlab1;
+
+
+ /*-------------------------------------------------------------.
+ | yyerrlab1 -- common code for both syntax error and YYERROR. |
+ `-------------------------------------------------------------*/
+ yyerrlab1:
+ yyerrstatus_ = 3; // Each real token shifted decrements this.
+ {
+ stack_symbol_type error_token;
+ for (;;)
+ {
+ yyn = yypact_[yystack_[0].state];
+ if (!yy_pact_value_is_default_ (yyn))
+ {
+ yyn += 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 (yystack_.size () == 1)
+ YYABORT;
+]b4_locations_if([[
+ yyerror_range[1].location = yystack_[0].location;]])[
+ yy_destroy_ ("Error: popping", yystack_[0]);
+ yypop_ ();
+ YY_STACK_PRINT ();
+ }
+]b4_locations_if([[
+ yyerror_range[2].location = yyla.location;
+ YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);]])[
+
+ // Shift the error token.
+ error_token.state = yyn;
+ yypush_ ("Shifting", YY_MOVE (error_token));
+ }
+ goto yynewstate;
+
+
+ /*-------------------------------------.
+ | yyacceptlab -- YYACCEPT comes here. |
+ `-------------------------------------*/
+ yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+
+ /*-----------------------------------.
+ | yyabortlab -- YYABORT comes here. |
+ `-----------------------------------*/
+ yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+
+ /*-----------------------------------------------------.
+ | yyreturn -- parsing is finished, return the result. |
+ `-----------------------------------------------------*/
+ yyreturn:
+ if (!yyla.empty ())
+ yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ yypop_ (yylen);
+ while (1 < yystack_.size ())
+ {
+ yy_destroy_ ("Cleanup: popping", yystack_[0]);
+ yypop_ ();
+ }
+
+ return yyresult;
+ }
+#if YY_EXCEPTIONS
+ catch (...)
+ {
+ YYCDEBUG << "Exception caught: cleaning lookahead and stack\n";
+ // Do not try to display the values of the reclaimed symbols,
+ // as their printers might throw an exception.
+ if (!yyla.empty ())
+ yy_destroy_ (YY_NULLPTR, yyla);
+
+ while (1 < yystack_.size ())
+ {
+ yy_destroy_ (YY_NULLPTR, yystack_[0]);
+ yypop_ ();
+ }
+ throw;
+ }
+#endif // YY_EXCEPTIONS
+ }
+
+ void
+ ]b4_parser_class[::error (const syntax_error& yyexc)
+ {
+ error (]b4_join(b4_locations_if([yyexc.location]),
+ [[yyexc.what ()]])[);
+ }
+
+ // Generate an error message.
+ std::string
+ ]b4_parser_class[::yysyntax_error_ (]dnl
+b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
+ [state_type, const symbol_type&])[) const
+ {]b4_error_verbose_if([[
+ // Number of reported tokens (one for the "unexpected", one per
+ // "expected").
+ size_t yycount = 0;
+ // Its maximum.
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ // Arguments of yyformat.
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yyla) is
+ if this state is a consistent state with a default action.
+ Thus, detecting the absence of a lookahead is sufficient to
+ determine that there is no unexpected or expected token to
+ report. In that case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is
+ a consistent state with a default action. There might have
+ been a previous inconsistent state, consistent state with a
+ non-default action, or user semantic action that manipulated
+ yyla. (However, yyla is currently not documented for users.)
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state
+ merging (from LALR or IELR) and default reductions corrupt the
+ expected token list. However, the list is correct for
+ canonical LR with one exception: it will still contain any
+ token that will not be accepted due to an error action in a
+ later state.
+ */
+ if (!yyla.empty ())
+ {
+ int yytoken = yyla.type_get ();
+ yyarg[yycount++] = yytname_[yytoken];
+ int yyn = yypact_[yystate];
+ if (!yy_pact_value_is_default_ (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ // Stay within bounds of both yycheck and yytname.
+ int yychecklim = yylast_ - yyn + 1;
+ int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
+ for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+ && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ break;
+ }
+ else
+ yyarg[yycount++] = yytname_[yyx];
+ }
+ }
+ }
+
+ char const* yyformat = YY_NULLPTR;
+ switch (yycount)
+ {
+#define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ default: // Avoid compiler warnings.
+ YYCASE_ (0, YY_("syntax error"));
+ YYCASE_ (1, YY_("syntax error, unexpected %s"));
+ YYCASE_ (2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_ (3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_ (4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_ (5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+ }
+
+ std::string yyres;
+ // Argument number.
+ size_t yyi = 0;
+ for (char const* yyp = yyformat; *yyp; ++yyp)
+ if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+ {
+ yyres += yytnamerr_ (yyarg[yyi++]);
+ ++yyp;
+ }
+ else
+ yyres += *yyp;
+ return yyres;]], [[
+ return YY_("syntax error");]])[
+ }
+
+
+ const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class::yypact_ninf_ = b4_pact_ninf[;
+
+ const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class::yytable_ninf_ = b4_table_ninf[;
+
+]b4_parser_tables_define[
+
+]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
+ // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+ const char*
+ const ]b4_parser_class[::yytname_[] =
+ {
+ ]b4_tname[
+ };
+
+]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
+]b4_integral_parser_table_define([rline], [b4_rline])[
+
+ // Print the state stack on the debug stream.
+ void
+ ]b4_parser_class[::yystack_print_ ()
+ {
+ *yycdebug_ << "Stack now";
+ for (stack_type::const_iterator
+ i = yystack_.begin (),
+ i_end = yystack_.end ();
+ i != i_end; ++i)
+ *yycdebug_ << ' ' << i->state;
+ *yycdebug_ << '\n';
+ }
+
+ // Report on the debug stream that the rule \a yyrule is going to be reduced.
+ void
+ ]b4_parser_class[::yy_reduce_print_ (int yyrule)
+ {
+ unsigned yylno = yyrline_[yyrule];
+ int yynrhs = yyr2_[yyrule];
+ // Print the symbols being reduced, and their result.
+ *yycdebug_ << "Reducing stack by rule " << yyrule - 1
+ << " (line " << yylno << "):\n";
+ // The symbols being reduced.
+ for (int yyi = 0; yyi < yynrhs; yyi++)
+ YY_SYMBOL_PRINT (" $" << yyi + 1 << " =",
+ ]b4_rhs_data(yynrhs, yyi + 1)[);
+ }
+#endif // ]b4_api_PREFIX[DEBUG
+
+]b4_token_ctor_if([], [b4_yytranslate_define([cc])])[
+]b4_namespace_close[
+]b4_epilogue[]dnl
+b4_output_end
+
+
+m4_popdef([b4_copyright_years])dnl
diff --git a/contrib/tools/bison/data/skeletons/location.cc b/contrib/tools/bison/data/skeletons/location.cc
new file mode 100644
index 0000000000..a57c0fb67a
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/location.cc
@@ -0,0 +1,363 @@
+# C++ skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2019 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/>.
+
+m4_pushdef([b4_copyright_years],
+ [2002-2015, 2018-2019])
+
+
+# b4_position_file
+# ----------------
+# Name of the file containing the position class, if we want this file.
+b4_defines_if([b4_required_version_if([302], [],
+ [m4_define([b4_position_file], [position.hh])])])])
+
+
+# b4_location_file
+# ----------------
+# Name of the file containing the position/location class,
+# if we want this file.
+b4_percent_define_check_file([b4_location_file],
+ [[api.location.file]],
+ b4_defines_if([[location.hh]]))
+
+# b4_location_include
+# -------------------
+# If location.hh is to be generated, the name under which should it be
+# included.
+#
+# b4_location_path
+# ----------------
+# The path to use for the CPP guard.
+m4_ifdef([b4_location_file],
+[m4_define([b4_location_include],
+ [b4_percent_define_get([[api.location.include]],
+ ["b4_location_file"])])
+ m4_define([b4_location_path],
+ b4_percent_define_get([[api.location.include]],
+ ["b4_dir_prefix[]b4_location_file"]))
+ m4_define([b4_location_path],
+ m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
+ ])
+
+
+
+# b4_location_define
+# ------------------
+# Define the position and location classes.
+m4_define([b4_location_define],
+[[ /// A point in a source file.
+ class position
+ {
+ public:]m4_ifdef([b4_location_constructors], [[
+ /// Construct a position.
+ explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
+ unsigned l = ]b4_location_initial_line[u,
+ unsigned c = ]b4_location_initial_column[u)
+ : filename (f)
+ , line (l)
+ , column (c)
+ {}
+
+]])[
+ /// Initialization.
+ void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
+ unsigned l = ]b4_location_initial_line[u,
+ unsigned c = ]b4_location_initial_column[u)
+ {
+ filename = fn;
+ line = l;
+ column = c;
+ }
+
+ /** \name Line and Column related manipulators
+ ** \{ */
+ /// (line related) Advance to the COUNT next lines.
+ void lines (int count = 1)
+ {
+ if (count)
+ {
+ column = ]b4_location_initial_column[u;
+ line = add_ (line, count, ]b4_location_initial_line[);
+ }
+ }
+
+ /// (column related) Advance to the COUNT next columns.
+ void columns (int count = 1)
+ {
+ column = add_ (column, count, ]b4_location_initial_column[);
+ }
+ /** \} */
+
+ /// File name to which this position refers.
+ ]b4_percent_define_get([[filename_type]])[* filename;
+ /// Current line number.
+ unsigned line;
+ /// Current column number.
+ unsigned column;
+
+ private:
+ /// Compute max (min, lhs+rhs).
+ static unsigned add_ (unsigned lhs, int rhs, int min)
+ {
+ return static_cast<unsigned> (std::max (min,
+ static_cast<int> (lhs) + rhs));
+ }
+ };
+
+ /// Add \a width columns, in place.
+ inline position&
+ operator+= (position& res, int width)
+ {
+ res.columns (width);
+ return res;
+ }
+
+ /// Add \a width columns.
+ inline position
+ operator+ (position res, int width)
+ {
+ return res += width;
+ }
+
+ /// Subtract \a width columns, in place.
+ inline position&
+ operator-= (position& res, int width)
+ {
+ return res += -width;
+ }
+
+ /// Subtract \a width columns.
+ inline position
+ operator- (position res, int width)
+ {
+ return res -= width;
+ }
+]b4_percent_define_flag_if([[define_location_comparison]], [[
+ /// Compare two position objects.
+ inline bool
+ operator== (const position& pos1, const position& pos2)
+ {
+ return (pos1.line == pos2.line
+ && pos1.column == pos2.column
+ && (pos1.filename == pos2.filename
+ || (pos1.filename && pos2.filename
+ && *pos1.filename == *pos2.filename)));
+ }
+
+ /// Compare two position objects.
+ inline bool
+ operator!= (const position& pos1, const position& pos2)
+ {
+ return !(pos1 == pos2);
+ }
+]])[
+ /** \brief Intercept output stream redirection.
+ ** \param ostr the destination output stream
+ ** \param pos a reference to the position to redirect
+ */
+ template <typename YYChar>
+ std::basic_ostream<YYChar>&
+ operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
+ {
+ if (pos.filename)
+ ostr << *pos.filename << ':';
+ return ostr << pos.line << '.' << pos.column;
+ }
+
+ /// Two points in a source file.
+ class location
+ {
+ public:
+]m4_ifdef([b4_location_constructors], [
+ /// Construct a location from \a b to \a e.
+ location (const position& b, const position& e)
+ : begin (b)
+ , end (e)
+ {}
+
+ /// Construct a 0-width location in \a p.
+ explicit location (const position& p = position ())
+ : begin (p)
+ , end (p)
+ {}
+
+ /// Construct a 0-width location in \a f, \a l, \a c.
+ explicit location (]b4_percent_define_get([[filename_type]])[* f,
+ unsigned l = ]b4_location_initial_line[u,
+ unsigned c = ]b4_location_initial_column[u)
+ : begin (f, l, c)
+ , end (f, l, c)
+ {}
+
+])[
+ /// Initialization.
+ void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
+ unsigned l = ]b4_location_initial_line[u,
+ unsigned c = ]b4_location_initial_column[u)
+ {
+ begin.initialize (f, l, c);
+ end = begin;
+ }
+
+ /** \name Line and Column related manipulators
+ ** \{ */
+ public:
+ /// Reset initial location to final location.
+ void step ()
+ {
+ begin = end;
+ }
+
+ /// Extend the current location to the COUNT next columns.
+ void columns (int count = 1)
+ {
+ end += count;
+ }
+
+ /// Extend the current location to the COUNT next lines.
+ void lines (int count = 1)
+ {
+ end.lines (count);
+ }
+ /** \} */
+
+
+ public:
+ /// Beginning of the located region.
+ position begin;
+ /// End of the located region.
+ position end;
+ };
+
+ /// Join two locations, in place.
+ inline location& operator+= (location& res, const location& end)
+ {
+ res.end = end.end;
+ return res;
+ }
+
+ /// Join two locations.
+ inline location operator+ (location res, const location& end)
+ {
+ return res += end;
+ }
+
+ /// Add \a width columns to the end position, in place.
+ inline location& operator+= (location& res, int width)
+ {
+ res.columns (width);
+ return res;
+ }
+
+ /// Add \a width columns to the end position.
+ inline location operator+ (location res, int width)
+ {
+ return res += width;
+ }
+
+ /// Subtract \a width columns to the end position, in place.
+ inline location& operator-= (location& res, int width)
+ {
+ return res += -width;
+ }
+
+ /// Subtract \a width columns to the end position.
+ inline location operator- (location res, int width)
+ {
+ return res -= width;
+ }
+]b4_percent_define_flag_if([[define_location_comparison]], [[
+ /// Compare two location objects.
+ inline bool
+ operator== (const location& loc1, const location& loc2)
+ {
+ return loc1.begin == loc2.begin && loc1.end == loc2.end;
+ }
+
+ /// Compare two location objects.
+ inline bool
+ operator!= (const location& loc1, const location& loc2)
+ {
+ return !(loc1 == loc2);
+ }
+]])[
+ /** \brief Intercept output stream redirection.
+ ** \param ostr the destination output stream
+ ** \param loc a reference to the location to redirect
+ **
+ ** Avoid duplicate information.
+ */
+ template <typename YYChar>
+ std::basic_ostream<YYChar>&
+ operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
+ {
+ unsigned end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
+ ostr << loc.begin;
+ if (loc.end.filename
+ && (!loc.begin.filename
+ || *loc.begin.filename != *loc.end.filename))
+ ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
+ else if (loc.begin.line < loc.end.line)
+ ostr << '-' << loc.end.line << '.' << end_col;
+ else if (loc.begin.column < end_col)
+ ostr << '-' << end_col;
+ return ostr;
+ }
+]])
+
+
+m4_ifdef([b4_position_file], [[
+]b4_output_begin([b4_dir_prefix], [b4_position_file])[
+]b4_generated_by[
+// Starting with Bison 3.2, this file is useless: the structure it
+// used to define is now defined in "]b4_location_file[".
+//
+// To get rid of this file:
+// 1. add 'require "3.2"' (or newer) to your grammar file
+// 2. remove references to this file from your build system
+// 3. if you used to include it, include "]b4_location_file[" instead.
+
+#include ]b4_location_include[
+]b4_output_end[
+]])
+
+
+m4_ifdef([b4_location_file], [[
+]b4_output_begin([b4_dir_prefix], [b4_location_file])[
+]b4_copyright([Locations for Bison parsers in C++])[
+/**
+ ** \file ]b4_location_path[
+ ** Define the ]b4_namespace_ref[::location class.
+ */
+
+]b4_cpp_guard_open([b4_location_path])[
+
+# include <algorithm> // std::max
+# include <iostream>
+# include <string>
+
+]b4_null_define[
+
+]b4_namespace_open[
+]b4_location_define[
+]b4_namespace_close[
+]b4_cpp_guard_close([b4_location_path])[
+]b4_output_end[
+]])
+
+
+m4_popdef([b4_copyright_years])
diff --git a/contrib/tools/bison/data/skeletons/stack.hh b/contrib/tools/bison/data/skeletons/stack.hh
new file mode 100644
index 0000000000..926a6f8cac
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/stack.hh
@@ -0,0 +1,163 @@
+# C++ skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2019 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/>.
+
+
+# b4_stack_file
+# -------------
+# Name of the file containing the stack class, if we want this file.
+b4_defines_if([b4_required_version_if([302], [],
+ [m4_define([b4_stack_file], [stack.hh])])])
+
+
+# b4_stack_define
+# ---------------
+m4_define([b4_stack_define],
+[[ /// A stack with random access from its top.
+ template <typename T, typename S = std::vector<T> >
+ class stack
+ {
+ public:
+ // Hide our reversed order.
+ typedef typename S::reverse_iterator iterator;
+ typedef typename S::const_reverse_iterator const_iterator;
+ typedef typename S::size_type size_type;
+
+ stack (size_type n = 200)
+ : seq_ (n)
+ {}
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ T&
+ operator[] (size_type i)
+ {
+ return seq_[size () - 1 - i];
+ }
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ T&
+ operator[] (int i)
+ {
+ return operator[] (size_type (i));
+ }
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ const T&
+ operator[] (size_type i) const
+ {
+ return seq_[size () - 1 - i];
+ }
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ const T&
+ operator[] (int i) const
+ {
+ return operator[] (size_type (i));
+ }
+
+ /// Steal the contents of \a t.
+ ///
+ /// Close to move-semantics.
+ void
+ push (YY_MOVE_REF (T) t)
+ {
+ seq_.push_back (T ());
+ operator[] (0).move (t);
+ }
+
+ /// Pop elements from the stack.
+ void
+ pop (int n = 1) YY_NOEXCEPT
+ {
+ for (; 0 < n; --n)
+ seq_.pop_back ();
+ }
+
+ /// Pop all elements from the stack.
+ void
+ clear () YY_NOEXCEPT
+ {
+ seq_.clear ();
+ }
+
+ /// Number of elements on the stack.
+ size_type
+ size () const YY_NOEXCEPT
+ {
+ return seq_.size ();
+ }
+
+ /// Iterator on top of the stack (going downwards).
+ const_iterator
+ begin () const YY_NOEXCEPT
+ {
+ return seq_.rbegin ();
+ }
+
+ /// Bottom of the stack.
+ const_iterator
+ end () const YY_NOEXCEPT
+ {
+ return seq_.rend ();
+ }
+
+ /// Present a slice of the top of a stack.
+ class slice
+ {
+ public:
+ slice (const stack& stack, int range)
+ : stack_ (stack)
+ , range_ (range)
+ {}
+
+ const T&
+ operator[] (int i) const
+ {
+ return stack_[range_ - i];
+ }
+
+ private:
+ const stack& stack_;
+ int range_;
+ };
+
+ private:
+ stack (const stack&);
+ stack& operator= (const stack&);
+ /// The wrapped container.
+ S seq_;
+ };
+]])
+
+m4_ifdef([b4_stack_file],
+[b4_output_begin([b4_dir_prefix], [b4_stack_file])[
+]b4_generated_by[
+// Starting with Bison 3.2, this file is useless: the structure it
+// used to define is now defined with the parser itself.
+//
+// To get rid of this file:
+// 1. add 'require "3.2"' (or newer) to your grammar file
+// 2. remove references to this file from your build system.
+]b4_output_end[
+]])
diff --git a/contrib/tools/bison/data/skeletons/variant.hh b/contrib/tools/bison/data/skeletons/variant.hh
new file mode 100644
index 0000000000..8b9d4802df
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/variant.hh
@@ -0,0 +1,453 @@
+# C++ skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2019 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/>.
+
+
+## --------- ##
+## variant. ##
+## --------- ##
+
+# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
+# ------------------------------------------------
+# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
+# YYTYPE.
+m4_define([b4_symbol_variant],
+[m4_pushdef([b4_dollar_dollar],
+ [$2.$3< $][3 > (m4_shift3($@))])dnl
+switch ($1)
+ {
+b4_type_foreach([_b4_type_action])[]dnl
+ default:
+ break;
+ }
+m4_popdef([b4_dollar_dollar])dnl
+])
+
+
+# _b4_char_sizeof_counter
+# -----------------------
+# A counter used by _b4_char_sizeof_dummy to create fresh symbols.
+m4_define([_b4_char_sizeof_counter],
+[0])
+
+# _b4_char_sizeof_dummy
+# ---------------------
+# At each call return a new C++ identifier.
+m4_define([_b4_char_sizeof_dummy],
+[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl
+dummy[]_b4_char_sizeof_counter])
+
+
+# b4_char_sizeof(SYMBOL-NUMS)
+# ---------------------------
+# To be mapped on the list of type names to produce:
+#
+# char dummy1[sizeof (type_name_1)];
+# char dummy2[sizeof (type_name_2)];
+#
+# for defined type names.
+m4_define([b4_char_sizeof],
+[b4_symbol_if([$1], [has_type],
+[
+m4_map([ b4_symbol_tag_comment], [$@])dnl
+ char _b4_char_sizeof_dummy@{sizeof (b4_symbol([$1], [type]))@};
+])])
+
+
+# b4_variant_includes
+# -------------------
+# The needed includes for variants support.
+m4_define([b4_variant_includes],
+[b4_parse_assert_if([[#include <typeinfo>]])[
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+]])
+
+
+
+## -------------------------- ##
+## Adjustments for variants. ##
+## -------------------------- ##
+
+
+# b4_value_type_declare
+# ---------------------
+# Define semantic_type.
+m4_define([b4_value_type_declare],
+[[ /// A buffer to store and retrieve objects.
+ ///
+ /// Sort of a variant, but does not keep track of the nature
+ /// of the stored data, since that knowledge is available
+ /// via the current parser state.
+ class semantic_type
+ {
+ public:
+ /// Type of *this.
+ typedef semantic_type self_type;
+
+ /// Empty construction.
+ semantic_type () YY_NOEXCEPT
+ : yybuffer_ ()]b4_parse_assert_if([
+ , yytypeid_ (YY_NULLPTR)])[
+ {}
+
+ /// Construct and fill.
+ template <typename T>
+ semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
+ : yytypeid_ (&typeid (T))])[
+ {
+ YYASSERT (sizeof (T) <= size);
+ new (yyas_<T> ()) T (YY_MOVE (t));
+ }
+
+ /// Destruction, allowed only if empty.
+ ~semantic_type () YY_NOEXCEPT
+ {]b4_parse_assert_if([
+ YYASSERT (!yytypeid_);
+ ])[}
+
+# if 201103L <= YY_CPLUSPLUS
+ /// Instantiate a \a T in here from \a t.
+ template <typename T, typename... U>
+ T&
+ emplace (U&&... u)
+ {]b4_parse_assert_if([
+ YYASSERT (!yytypeid_);
+ YYASSERT (sizeof (T) <= size);
+ yytypeid_ = & typeid (T);])[
+ return *new (yyas_<T> ()) T (std::forward <U>(u)...);
+ }
+# else
+ /// Instantiate an empty \a T in here.
+ template <typename T>
+ T&
+ emplace ()
+ {]b4_parse_assert_if([
+ YYASSERT (!yytypeid_);
+ YYASSERT (sizeof (T) <= size);
+ yytypeid_ = & typeid (T);])[
+ return *new (yyas_<T> ()) T ();
+ }
+
+ /// Instantiate a \a T in here from \a t.
+ template <typename T>
+ T&
+ emplace (const T& t)
+ {]b4_parse_assert_if([
+ YYASSERT (!yytypeid_);
+ YYASSERT (sizeof (T) <= size);
+ yytypeid_ = & typeid (T);])[
+ return *new (yyas_<T> ()) T (t);
+ }
+# endif
+
+ /// Instantiate an empty \a T in here.
+ /// Obsolete, use emplace.
+ template <typename T>
+ T&
+ build ()
+ {
+ return emplace<T> ();
+ }
+
+ /// Instantiate a \a T in here from \a t.
+ /// Obsolete, use emplace.
+ template <typename T>
+ T&
+ build (const T& t)
+ {
+ return emplace<T> (t);
+ }
+
+ /// Accessor to a built \a T.
+ template <typename T>
+ T&
+ as () YY_NOEXCEPT
+ {]b4_parse_assert_if([
+ YYASSERT (yytypeid_);
+ YYASSERT (*yytypeid_ == typeid (T));
+ YYASSERT (sizeof (T) <= size);])[
+ return *yyas_<T> ();
+ }
+
+ /// Const accessor to a built \a T (for %printer).
+ template <typename T>
+ const T&
+ as () const YY_NOEXCEPT
+ {]b4_parse_assert_if([
+ YYASSERT (yytypeid_);
+ YYASSERT (*yytypeid_ == typeid (T));
+ YYASSERT (sizeof (T) <= size);])[
+ return *yyas_<T> ();
+ }
+
+ /// Swap the content with \a that, of same type.
+ ///
+ /// Both variants must be built beforehand, because swapping the actual
+ /// data requires reading it (with as()), and this is not possible on
+ /// unconstructed variants: it would require some dynamic testing, which
+ /// should not be the variant's responsibility.
+ /// Swapping between built and (possibly) non-built is done with
+ /// self_type::move ().
+ template <typename T>
+ void
+ swap (self_type& that) YY_NOEXCEPT
+ {]b4_parse_assert_if([
+ YYASSERT (yytypeid_);
+ YYASSERT (*yytypeid_ == *that.yytypeid_);])[
+ std::swap (as<T> (), that.as<T> ());
+ }
+
+ /// Move the content of \a that to this.
+ ///
+ /// Destroys \a that.
+ template <typename T>
+ void
+ move (self_type& that)
+ {
+# if 201103L <= YY_CPLUSPLUS
+ emplace<T> (std::move (that.as<T> ()));
+# else
+ emplace<T> ();
+ swap<T> (that);
+# endif
+ that.destroy<T> ();
+ }
+
+# if 201103L <= YY_CPLUSPLUS
+ /// Move the content of \a that to this.
+ template <typename T>
+ void
+ move (self_type&& that)
+ {
+ emplace<T> (std::move (that.as<T> ()));
+ that.destroy<T> ();
+ }
+#endif
+
+ /// Copy the content of \a that to this.
+ template <typename T>
+ void
+ copy (const self_type& that)
+ {
+ emplace<T> (that.as<T> ());
+ }
+
+ /// Destroy the stored \a T.
+ template <typename T>
+ void
+ destroy ()
+ {
+ as<T> ().~T ();]b4_parse_assert_if([
+ yytypeid_ = YY_NULLPTR;])[
+ }
+
+ private:
+ /// Prohibit blind copies.
+ self_type& operator= (const self_type&);
+ semantic_type (const self_type&);
+
+ /// Accessor to raw memory as \a T.
+ template <typename T>
+ T*
+ yyas_ () YY_NOEXCEPT
+ {
+ void *yyp = yybuffer_.yyraw;
+ return static_cast<T*> (yyp);
+ }
+
+ /// Const accessor to raw memory as \a T.
+ template <typename T>
+ const T*
+ yyas_ () const YY_NOEXCEPT
+ {
+ const void *yyp = yybuffer_.yyraw;
+ return static_cast<const T*> (yyp);
+ }
+
+ /// An auxiliary type to compute the largest semantic type.
+ union union_type
+ {]b4_type_foreach([b4_char_sizeof])[ };
+
+ /// The size of the largest semantic type.
+ enum { size = sizeof (union_type) };
+
+ /// A buffer to store semantic values.
+ union
+ {
+ /// Strongest alignment constraints.
+ long double yyalign_me;
+ /// A buffer large enough to store any of the semantic values.
+ char yyraw[size];
+ } yybuffer_;]b4_parse_assert_if([
+
+ /// Whether the content is built: if defined, the name of the stored type.
+ const std::type_info *yytypeid_;])[
+ };
+]])
+
+
+# How the semantic value is extracted when using variants.
+
+# b4_symbol_value(VAL, SYMBOL-NUM, [TYPE])
+# ----------------------------------------
+# See README.
+m4_define([b4_symbol_value],
+[m4_ifval([$3],
+ [$1.as< $3 > ()],
+ [m4_ifval([$2],
+ [b4_symbol_if([$2], [has_type],
+ [$1.as < b4_symbol([$2], [type]) > ()],
+ [$1])],
+ [$1])])])
+
+# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
+# -------------------------------------------------
+# Same as b4_symbol_value, but used in a template method.
+m4_define([b4_symbol_value_template],
+[m4_ifval([$3],
+ [$1.template as< $3 > ()],
+ [m4_ifval([$2],
+ [b4_symbol_if([$2], [has_type],
+ [$1.template as < b4_symbol([$2], [type]) > ()],
+ [$1])],
+ [$1])])])
+
+
+
+## ------------- ##
+## make_SYMBOL. ##
+## ------------- ##
+
+
+# _b4_includes_tokens(SYMBOL-NUM...)
+# ----------------------------------
+# Expands to non-empty iff one of the SYMBOL-NUM denotes
+# a token.
+m4_define([_b4_is_token],
+ [b4_symbol_if([$1], [is_token], [1])])
+m4_define([_b4_includes_tokens],
+ [m4_map([_b4_is_token], [$@])])
+
+
+# _b4_token_maker_define(SYMBOL-NUM)
+# ----------------------------------
+# Declare make_SYMBOL for SYMBOL-NUM. Use at class-level.
+m4_define([_b4_token_maker_define],
+[b4_token_visible_if([$1],
+[#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_[]_b4_symbol([$1], [id]) (b4_join(
+ b4_symbol_if([$1], [has_type],
+ [b4_symbol([$1], [type]) v]),
+ b4_locations_if([location_type l])))
+ {
+ return symbol_type (b4_join([token::b4_symbol([$1], [id])],
+ b4_symbol_if([$1], [has_type], [std::move (v)]),
+ b4_locations_if([std::move (l)])));
+ }
+#else
+ static
+ symbol_type
+ make_[]_b4_symbol([$1], [id]) (b4_join(
+ b4_symbol_if([$1], [has_type],
+ [const b4_symbol([$1], [type])& v]),
+ b4_locations_if([const location_type& l])))
+ {
+ return symbol_type (b4_join([token::b4_symbol([$1], [id])],
+ b4_symbol_if([$1], [has_type], [v]),
+ b4_locations_if([l])));
+ }
+#endif
+])])
+
+
+m4_define([_b4_type_clause],
+[b4_symbol_if([$1], [is_token],
+ [b4_symbol_if([$1], [has_id],
+ [tok == token::b4_symbol([$1], [id])],
+ [tok == b4_symbol([$1], [user_number])])])])
+
+
+# _b4_token_constructor_define(SYMBOL-NUM...)
+# -------------------------------------------
+# Define a unique make_symbol for all the SYMBOL-NUM (they
+# have the same type). Use at class-level.
+m4_define([_b4_token_constructor_define],
+[m4_ifval(_b4_includes_tokens($@),
+[[#if 201103L <= YY_CPLUSPLUS
+ symbol_type (]b4_join(
+ [int tok],
+ b4_symbol_if([$1], [has_type],
+ [b4_symbol([$1], [type]) v]),
+ b4_locations_if([location_type l]))[)
+ : super_type(]b4_join([token_type (tok)],
+ b4_symbol_if([$1], [has_type], [std::move (v)]),
+ b4_locations_if([std::move (l)]))[)
+ {
+ YYASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
+ }
+#else
+ symbol_type (]b4_join(
+ [int tok],
+ b4_symbol_if([$1], [has_type],
+ [const b4_symbol([$1], [type])& v]),
+ b4_locations_if([const location_type& l]))[)
+ : super_type(]b4_join([token_type (tok)],
+ b4_symbol_if([$1], [has_type], [v]),
+ b4_locations_if([l]))[)
+ {
+ YYASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
+ }
+#endif
+]])])
+
+
+# b4_basic_symbol_constructor_define(SYMBOL-NUM)
+# ----------------------------------------------
+# Generate a constructor for basic_symbol from given type.
+m4_define([b4_basic_symbol_constructor_define],
+[[#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (]b4_join(
+ [typename Base::kind_type t],
+ b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
+ b4_locations_if([location_type&& l]))[)
+ : Base (t)]b4_symbol_if([$1], [has_type], [
+ , value (std::move (v))])[]b4_locations_if([
+ , location (std::move (l))])[
+ {}
+#else
+ basic_symbol (]b4_join(
+ [typename Base::kind_type t],
+ b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]),
+ b4_locations_if([const location_type& l]))[)
+ : Base (t)]b4_symbol_if([$1], [has_type], [
+ , value (v)])[]b4_locations_if([
+ , location (l)])[
+ {}
+#endif
+]])
+
+
+# b4_token_constructor_define
+# ---------------------------
+# Define the overloaded versions of make_symbol for all the value types.
+m4_define([b4_token_constructor_define],
+[ // Implementation of make_symbol for each symbol type.
+b4_symbol_foreach([_b4_token_maker_define])])
diff --git a/contrib/tools/bison/data/skeletons/yacc.c b/contrib/tools/bison/data/skeletons/yacc.c
new file mode 100644
index 0000000000..54e40e6741
--- /dev/null
+++ b/contrib/tools/bison/data/skeletons/yacc.c
@@ -0,0 +1,1927 @@
+ -*- C -*-
+# Yacc compatible skeleton for Bison
+
+# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software
+# Foundation, Inc.
+
+m4_pushdef([b4_copyright_years],
+ [1984, 1989-1990, 2000-2015, 2018-2019])
+
+# 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/>.
+
+# Check the value of %define api.push-pull.
+b4_percent_define_default([[api.push-pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push-pull]],
+ [[pull]], [[push]], [[both]]]])
+b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
+b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
+m4_case(b4_percent_define_get([[api.push-pull]]),
+ [pull], [m4_define([b4_push_flag], [[0]])],
+ [push], [m4_define([b4_pull_flag], [[0]])])
+
+# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
+# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
+# behavior of Bison at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
+b4_use_push_for_pull_if([
+ b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+ [m4_define([b4_push_flag], [[1]])])])
+
+# Check the value of %define parse.lac and friends, where LAC stands for
+# lookahead correction.
+b4_percent_define_default([[parse.lac]], [[none]])
+b4_percent_define_default([[parse.lac.es-capacity-initial]], [[20]])
+b4_percent_define_default([[parse.lac.memory-trace]], [[failures]])
+b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]],
+ [[[[parse.lac.memory-trace]],
+ [[failures]], [[full]]]])
+b4_define_flag_if([lac])
+m4_define([b4_lac_flag],
+ [m4_if(b4_percent_define_get([[parse.lac]]),
+ [none], [[0]], [[1]])])
+
+m4_include(b4_skeletonsdir/[c.m4])
+
+## ---------------- ##
+## Default values. ##
+## ---------------- ##
+
+# Stack parameters.
+m4_define_default([b4_stack_depth_max], [10000])
+m4_define_default([b4_stack_depth_init], [200])
+
+
+## ------------------------ ##
+## Pure/impure interfaces. ##
+## ------------------------ ##
+
+b4_percent_define_default([[api.pure]], [[false]])
+b4_percent_define_check_values([[[[api.pure]],
+ [[false]], [[true]], [[]], [[full]]]])
+
+m4_define([b4_pure_flag], [[0]])
+m4_case(b4_percent_define_get([[api.pure]]),
+ [false], [m4_define([b4_pure_flag], [[0]])],
+ [true], [m4_define([b4_pure_flag], [[1]])],
+ [], [m4_define([b4_pure_flag], [[1]])],
+ [full], [m4_define([b4_pure_flag], [[2]])])
+
+m4_define([b4_pure_if],
+[m4_case(b4_pure_flag,
+ [0], [$2],
+ [1], [$1],
+ [2], [$1])])
+ [m4_fatal([invalid api.pure value: ]$1)])])
+
+# b4_yyerror_arg_loc_if(ARG)
+# --------------------------
+# Expand ARG iff yyerror is to be given a location as argument.
+m4_define([b4_yyerror_arg_loc_if],
+[b4_locations_if([m4_case(b4_pure_flag,
+ [1], [m4_ifset([b4_parse_param], [$1])],
+ [2], [$1])])])
+
+# b4_yyerror_args
+# ---------------
+# Arguments passed to yyerror: user args plus yylloc.
+m4_define([b4_yyerror_args],
+[b4_yyerror_arg_loc_if([&yylloc, ])dnl
+m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
+
+
+
+## ------------ ##
+## Data Types. ##
+## ------------ ##
+
+# b4_int_type(MIN, MAX)
+# ---------------------
+# Return the smallest int type able to handle numbers ranging from
+# MIN to MAX (included). Overwrite the version from c.m4, which
+# uses only C89 types, so that the user can override the shorter
+# types, and so that pre-C89 compilers are handled correctly.
+m4_define([b4_int_type],
+[m4_if(b4_ints_in($@, [0], [255]), [1], [yytype_uint8],
+ b4_ints_in($@, [-128], [127]), [1], [yytype_int8],
+
+ b4_ints_in($@, [0], [65535]), [1], [yytype_uint16],
+ b4_ints_in($@, [-32768], [32767]), [1], [yytype_int16],
+
+ m4_eval([0 <= $1]), [1], [unsigned],
+
+ [int])])
+
+
+## ----------------- ##
+## Semantic Values. ##
+## ----------------- ##
+
+
+# b4_lhs_value(SYMBOL-NUM, [TYPE])
+# --------------------------------
+# See README.
+m4_define([b4_lhs_value],
+[b4_symbol_value(yyval, [$1], [$2])])
+
+
+# b4_rhs_value(RULE-LENGTH, POS, [SYMBOL-NUM], [TYPE])
+# ----------------------------------------------------
+# See README.
+m4_define([b4_rhs_value],
+[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3], [$4])])
+
+
+## ----------- ##
+## Locations. ##
+## ----------- ##
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[(yyloc)])
+
+
+# b4_rhs_location(RULE-LENGTH, POS)
+# ---------------------------------
+# Expansion of @POS, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+[(yylsp@{b4_subtract([$2], [$1])@})])
+
+
+## -------------- ##
+## Declarations. ##
+## -------------- ##
+
+# b4_declare_scanner_communication_variables
+# ------------------------------------------
+# Declare the variables that are global, or local to YYPARSE if
+# pure-parser.
+m4_define([b4_declare_scanner_communication_variables], [[
+/* The lookahead symbol. */
+int yychar;
+
+]b4_pure_if([[
+/* 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);]b4_locations_if([[
+
+/* Location data for the lookahead symbol. */
+static YYLTYPE yyloc_default]b4_yyloc_default[;
+YYLTYPE yylloc = yyloc_default;]])],
+[[/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;]b4_locations_if([[
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc]b4_yyloc_default[;]])[
+/* Number of syntax errors so far. */
+int yynerrs;]])])
+
+
+# b4_declare_parser_state_variables
+# ---------------------------------
+# Declare all the variables that are needed to maintain the parser state
+# between calls to yypush_parse.
+m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
+ /* 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.]b4_locations_if([[
+ '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;]b4_locations_if([[
+
+ /* 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;]b4_lac_if([[
+
+ yytype_int16 yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
+ yytype_int16 *yyes;
+ YYSIZE_T yyes_capacity;]])])
+
+
+# _b4_declare_yyparse_push
+# ------------------------
+# Declaration of yyparse (and dependencies) when using the push parser
+# (including in pull mode).
+m4_define([_b4_declare_yyparse_push],
+[[#ifndef YYPUSH_MORE_DEFINED
+# define YYPUSH_MORE_DEFINED
+enum { YYPUSH_MORE = 4 };
+#endif
+
+typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
+
+]b4_pull_if([b4_function_declare([b4_prefix[parse]], [[int]], b4_parse_param)
+])b4_function_declare([b4_prefix[push_parse]], [[int]],
+ [[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([,
+ [[[int pushed_char]], [[pushed_char]]],
+ [[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([,
+ [[b4_api_PREFIX[LTYPE *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [,
+ b4_parse_param]))
+b4_pull_if([b4_function_declare([b4_prefix[pull_parse]], [[int]],
+ [[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
+ b4_parse_param]))])
+b4_function_declare([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
+ [[[void]], []])
+b4_function_declare([b4_prefix[pstate_delete]], [[void]],
+ [[b4_prefix[pstate *ps]], [[ps]]])dnl
+])
+
+# _b4_declare_yyparse
+# -------------------
+# When not the push parser.
+m4_define([_b4_declare_yyparse],
+[b4_function_declare(b4_prefix[parse], [int], b4_parse_param)])
+
+
+# b4_declare_yyparse
+# ------------------
+m4_define([b4_declare_yyparse],
+[b4_push_if([_b4_declare_yyparse_push],
+ [_b4_declare_yyparse])[]dnl
+])
+
+
+# b4_shared_declarations
+# ----------------------
+# Declaration that might either go into the header (if --defines)
+# or open coded in the parser body.
+m4_define([b4_shared_declarations],
+[b4_cpp_guard_open([b4_spec_defines_file])[
+]b4_declare_yydebug[
+]b4_percent_code_get([[requires]])[
+]b4_token_enums_defines[
+]b4_declare_yylstype[
+]b4_declare_yyparse[
+]b4_percent_code_get([[provides]])[
+]b4_cpp_guard_close([b4_spec_defines_file])[]dnl
+])
+
+## -------------- ##
+## Output files. ##
+## -------------- ##
+
+b4_output_begin([b4_parser_file_name])[
+]b4_copyright([Bison implementation for Yacc-like parsers in C])[
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* 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. */
+
+]b4_disclaimer[
+]b4_identification[
+]b4_percent_code_get([[top]])[]dnl
+m4_if(b4_api_prefix, [yy], [],
+[[/* Substitute the type names. */
+#define YYSTYPE ]b4_api_PREFIX[STYPE]b4_locations_if([[
+#define YYLTYPE ]b4_api_PREFIX[LTYPE]])])[
+]m4_if(b4_prefix, [yy], [],
+[[/* Substitute the variable and function names. */]b4_pull_if([[
+#define yyparse ]b4_prefix[parse]])b4_push_if([[
+#define yypush_parse ]b4_prefix[push_parse]b4_pull_if([[
+#define yypull_parse ]b4_prefix[pull_parse]])[
+#define yypstate_new ]b4_prefix[pstate_new
+#define yypstate_delete ]b4_prefix[pstate_delete
+#define yypstate ]b4_prefix[pstate]])[
+#define yylex ]b4_prefix[lex
+#define yyerror ]b4_prefix[error
+#define yydebug ]b4_prefix[debug
+#define yynerrs ]b4_prefix[nerrs
+]]b4_pure_if([], [[
+#define yylval ]b4_prefix[lval
+#define yychar ]b4_prefix[char]b4_locations_if([[
+#define yylloc ]b4_prefix[lloc]])]))[
+
+]b4_user_pre_prologue[
+]b4_null_define[
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
+#endif
+
+]m4_ifval(m4_quote(b4_spec_defines_file),
+[[/* In a future release of Bison, this section will be replaced
+ by #include "@basename(]b4_spec_defines_file[@)". */
+]])dnl
+b4_shared_declarations[
+
+]b4_user_post_prologue[
+]b4_percent_code_get[]dnl
+
+[#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 yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short 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
+# 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
+
+]b4_attribute_define[
+
+#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */]dnl
+b4_push_if([], [b4_lac_if([], [[
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif]])])[
+
+# 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]b4_lac_if([[
+# define YYCOPY_NEEDED 1]])[
+#endif]b4_lac_if([], [[ /* ! defined yyoverflow || YYERROR_VERBOSE */]])[
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \
+ && ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;]b4_locations_if([
+ 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. */
+]b4_locations_if(
+[# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)],
+[# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + 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 ]b4_final_state_number[
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST ]b4_last[
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS ]b4_tokens_number[
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS ]b4_nterms_number[
+/* YYNRULES -- Number of rules. */
+#define YYNRULES ]b4_rules_number[
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES ]b4_states_number[
+
+#define YYUNDEFTOK ]b4_undef_token_number[
+#define YYMAXUTOK ]b4_user_token_number_max[
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
+{
+ ]b4_translate[
+};
+
+#if ]b4_api_PREFIX[DEBUG
+]b4_integral_parser_table_define([rline], [b4_rline],
+ [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
+#endif
+
+#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ ]b4_tname[
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
+{
+ ]b4_toknum[
+};
+# endif
+
+#define YYPACT_NINF ]b4_pact_ninf[
+
+#define yypact_value_is_default(Yystate) \
+ ]b4_table_value_equals([[pact]], [[Yystate]], [b4_pact_ninf])[
+
+#define YYTABLE_NINF ]b4_table_ninf[
+
+#define yytable_value_is_error(Yytable_value) \
+ ]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf])[
+
+]b4_parser_tables_define[
+
+#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; \]b4_lac_if([[
+ YY_LAC_DISCARD ("YYBACKUP"); \]])[
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+]b4_locations_if([[
+]b4_yylloc_default_define[
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+]])[
+
+/* Enable debugging if requested. */
+#if ]b4_api_PREFIX[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)
+
+]b4_yy_location_print_define[
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+]b4_yy_symbol_print_define[
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+]b4_function_define([yy_stack_print], [static void],
+ [[yytype_int16 *yybottom], [yybottom]],
+ [[yytype_int16 *yytop], [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. |
+`------------------------------------------------*/
+
+]b4_function_define([yy_reduce_print], [static void],
+ [[yytype_int16 *yyssp], [yyssp]],
+ [[YYSTYPE *yyvsp], [yyvsp]],
+ b4_locations_if([[[YYLTYPE *yylsp], [yylsp]],
+ ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
+ b4_parse_param]))[
+{
+ unsigned long 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]],
+ &]b4_rhs_value(yynrhs, yyi + 1)[
+ ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
+ b4_user_args[);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !]b4_api_PREFIX[DEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !]b4_api_PREFIX[DEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH ]b4_stack_depth_init[
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH ]b4_stack_depth_max[
+#endif]b4_lac_if([[
+
+/* Given a state stack such that *YYBOTTOM is its bottom, such that
+ *YYTOP is either its top or is YYTOP_EMPTY to indicate an empty
+ 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 ]b4_api_PREFIX[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 =
+ (YYSIZE_T) (*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;]m4_if(b4_percent_define_get([[parse.lac.memory-trace]]),
+ [full], [[
+ YYDPRINTF ((stderr, "%srealloc to %lu%s", yydebug_prefix,
+ (unsigned long) yyalloc, yydebug_suffix));]])[
+ }
+ 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 ]b4_api_PREFIX[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 = (YYSIZE_T) (yyesp - *yyes + 1);
+ if (yylen < yysize)
+ {
+ yyesp -= yylen;
+ yylen = 0;
+ }
+ else
+ {
+ yylen -= yysize;
+ yyesp = yyes_prev;
+ }
+ }
+ if (yylen)
+ yyesp = yyes_prev -= yylen;
+ }
+ {
+ yytype_int16 yystate;
+ {
+ const int yylhs = yyr1[yyrule] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyesp;
+ yystate = ((yytype_int16)
+ (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]));
+ }
+ if (yyesp == yyes_prev)
+ {
+ yyesp = *yyes;
+ *yyesp = yystate;
+ }
+ else
+ {
+ if (yy_lac_stack_realloc (yyes_capacity, 1,
+#if ]b4_api_PREFIX[DEBUG
+ " (", ")",
+#endif
+ yyes, yyesa, &yyesp, yyes_prev))
+ {
+ YYDPRINTF ((stderr, "\n"));
+ return 2;
+ }
+ *++yyesp = yystate;
+ }
+ YYDPRINTF ((stderr, " G%d", (int) yystate));
+ }
+ }
+}]])[
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+]b4_function_define([yystrlen], [static YYSIZE_T],
+ [[const char *yystr], [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. */
+]b4_function_define([yystpcpy], [static char *],
+ [[char *yydest], [yydest]], [[const char *yysrc], [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;
+ else
+ goto append;
+
+ append:
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return (YYSIZE_T) (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.]b4_lac_if([[ In order to see if a particular token T is a
+ valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T).]])[
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store]b4_lac_if([[ or if
+ yy_lac returned 2]])[. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ ]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes,
+ YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "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.]b4_lac_if([[
+ 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.]], [[
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.]])[
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];]b4_lac_if([[
+ YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {]b4_lac_if([], [[
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;]])[
+ int yyx;]b4_lac_if([[
+
+ 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;
+ }]], [[
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {]])[
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
+ return 2;
+ }
+ }
+ }]b4_lac_if([[
+# if ]b4_api_PREFIX[DEBUG
+ else if (yydebug)
+ YYFPRINTF (stderr, "No expected tokens.\n");
+# endif]])[
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ default: /* Avoid compiler warnings. */
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
+ return 2;
+ }
+
+ 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 */
+
+]b4_yydestruct_define[
+
+]b4_pure_if([], [
+
+b4_declare_scanner_communication_variables])[]b4_push_if([[
+
+struct yypstate
+ {]b4_declare_parser_state_variables[
+ /* Used to determine if this is the first time this instance has
+ been used. */
+ int yynew;
+ };]b4_pure_if([], [[
+
+static char yypstate_allocated = 0;]])b4_pull_if([
+
+b4_function_define([[yyparse]], [[int]], b4_parse_param)[
+{
+ return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param],
+ [[, ]b4_args(b4_parse_param)])[);
+}
+
+]b4_function_define([[yypull_parse]], [[int]],
+ [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
+ b4_parse_param]))[
+{]b4_pure_if([b4_locations_if([[
+ static YYLTYPE yyloc_default][]b4_yyloc_default[;
+ YYLTYPE yylloc = yyloc_default;]])])[
+ yypstate *yyps_local;
+ if (yyps)
+ yyps_local = yyps;
+ else
+ {
+ yyps_local = yypstate_new ();
+ if (!yyps_local)
+ {]b4_pure_if([[
+ yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
+ if (!yypstate_allocated)
+ yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
+ return 2;
+ }
+ }
+ int yystatus;
+ do {]b4_pure_if([[
+ YYSTYPE yylval;
+ int ]])[yychar = ]b4_lex[;
+ yystatus =
+ yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
+ } while (yystatus == YYPUSH_MORE);
+ if (!yyps)
+ yypstate_delete (yyps_local);
+ return yystatus;
+}]])[
+
+/* Initialize the parser data structure. */
+]b4_function_define([[yypstate_new]], [[yypstate *]])[
+{
+ yypstate *yyps;]b4_pure_if([], [[
+ if (yypstate_allocated)
+ return YY_NULLPTR;]])[
+ yyps = (yypstate *) malloc (sizeof *yyps);
+ if (!yyps)
+ return YY_NULLPTR;
+ yyps->yynew = 1;]b4_pure_if([], [[
+ yypstate_allocated = 1;]])[
+ return yyps;
+}
+
+]b4_function_define([[yypstate_delete]], [[void]],
+ [[[yypstate *yyps]], [[yyps]]])[
+{
+ if (yyps)
+ {
+#ifndef yyoverflow
+ /* If the stack was reallocated but the parse did not complete, then the
+ stack still needs to be freed. */
+ if (!yyps->yynew && yyps->yyss != yyps->yyssa)
+ YYSTACK_FREE (yyps->yyss);
+#endif]b4_lac_if([[
+ if (!yyps->yynew && yyps->yyes != yyps->yyesa)
+ YYSTACK_FREE (yyps->yyes);]])[
+ free (yyps);]b4_pure_if([], [[
+ yypstate_allocated = 0;]])[
+ }
+}
+]b4_pure_if([[
+#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs]])[
+#define yystate yyps->yystate
+#define yyerrstatus yyps->yyerrstatus
+#define yyssa yyps->yyssa
+#define yyss yyps->yyss
+#define yyssp yyps->yyssp
+#define yyvsa yyps->yyvsa
+#define yyvs yyps->yyvs
+#define yyvsp yyps->yyvsp]b4_locations_if([[
+#define yylsa yyps->yylsa
+#define yyls yyps->yyls
+#define yylsp yyps->yylsp
+#define yyerror_range yyps->yyerror_range]])[
+#define yystacksize yyps->yystacksize]b4_lac_if([[
+#define yyesa yyps->yyesa
+#define yyes yyps->yyes
+#define yyes_capacity yyps->yyes_capacity]])[
+
+
+/*---------------.
+| yypush_parse. |
+`---------------*/
+
+]b4_function_define([[yypush_parse]], [[int]],
+ [[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
+ [[[int yypushed_char]], [[yypushed_char]]],
+ [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
+ [[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
+ b4_parse_param]))], [[
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+]b4_function_define([yyparse], [int], b4_parse_param)])[
+{]b4_pure_if([b4_declare_scanner_communication_variables
+])b4_push_if([b4_pure_if([], [[
+ int yypushed_char = yychar;
+ YYSTYPE yypushed_val = yylval;]b4_locations_if([[
+ YYLTYPE yypushed_loc = yylloc;]])
+])],
+ [b4_declare_parser_state_variables
+])b4_lac_if([[
+ 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;]b4_locations_if([[
+ 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)]b4_locations_if([, 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;]b4_push_if([[
+
+ if (!yyps->yynew)
+ {
+ yyn = yypact[yystate];
+ goto yyread_pushed_token;
+ }]])[
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;]b4_locations_if([[
+ yylsp = yyls = yylsa;]])[
+ yystacksize = YYINITDEPTH;]b4_lac_if([[
+
+ 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. */
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
+ [b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
+b4_user_initial_action
+b4_dollar_popdef[]dnl
+m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval;
+]])])dnl
+b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])[;
+]])dnl
+[ 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++;
+
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ *yyssp = (yytype_int16) yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
+
+# if defined 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;]b4_locations_if([
+ 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),]b4_locations_if([
+ &yyls1, yysize * sizeof (*yylsp),])[
+ &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;]b4_locations_if([
+ yyls = yyls1;])[
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* 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);]b4_locations_if([
+ YYSTACK_RELOCATE (yyls_alloc, yyls);])[
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;]b4_locations_if([
+ yylsp = yyls + yysize - 1;])[
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+ 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)
+ {]b4_push_if([[
+ if (!yyps->yynew)
+ {]b4_use_push_for_pull_if([], [[
+ YYDPRINTF ((stderr, "Return for a new token:\n"));]])[
+ yyresult = YYPUSH_MORE;
+ goto yypushreturn;
+ }
+ yyps->yynew = 0;]b4_pure_if([], [[
+ /* Restoring the pushed token is only necessary for the first
+ yypush_parse invocation since subsequent invocations don't overwrite
+ it before jumping to yyread_pushed_token. */
+ yychar = yypushed_char;
+ yylval = yypushed_val;]b4_locations_if([[
+ yylloc = yypushed_loc;]])])[
+yyread_pushed_token:]])[
+ YYDPRINTF ((stderr, "Reading a token: "));]b4_push_if([b4_pure_if([[
+ yychar = yypushed_char;
+ if (yypushed_val)
+ yylval = *yypushed_val;]b4_locations_if([[
+ if (yypushed_loc)
+ yylloc = *yypushed_loc;]])])], [[
+ yychar = ]b4_lex[;]])[
+ }
+
+ 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)]b4_lac_if([[
+ {
+ YY_LAC_ESTABLISH;
+ goto yydefault;
+ }]], [[
+ goto yydefault;]])[
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;]b4_lac_if([[
+ 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;]b4_lac_if([[
+ YY_LAC_DISCARD ("shift");]])[
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+]b4_locations_if([ *++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];
+
+]b4_locations_if(
+[[ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ yyerror_range[1] = yyloc;]])[
+ YY_REDUCE_PRINT (yyn);]b4_lac_if([[
+ {
+ int yychar_backup = yychar;
+ switch (yyn)
+ {
+]b4_user_actions[
+ default: break;
+ }
+ if (yychar_backup != yychar)
+ YY_LAC_DISCARD ("yychar change");
+ }]], [[
+ switch (yyn)
+ {
+ ]b4_user_actions[
+ default: break;
+ }]])[
+ /* 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;]b4_locations_if([
+ *++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. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
+
+ 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 (]b4_yyerror_args[YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \]b4_lac_if([[
+ yyesa, &yyes, &yyes_capacity, \]])[
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;]b4_lac_if([[
+ 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 (]b4_yyerror_args[yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+]b4_locations_if([[ yyerror_range[1] = yylloc;]])[
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
+ 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 when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+
+ /* 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;
+
+]b4_locations_if([[ yyerror_range[1] = *yylsp;]])[
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }]b4_lac_if([[
+
+ /* 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
+]b4_locations_if([[
+ yyerror_range[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;]])[
+
+ /* 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 ]b4_lac_if([[1]], [[!defined yyoverflow || YYERROR_VERBOSE]])[
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (]b4_yyerror_args[YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
+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]b4_locations_if([, &yylloc])[]b4_user_args[);
+ }
+ /* 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]b4_locations_if([, yylsp])[]b4_user_args[);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif]b4_lac_if([[
+ if (yyes != yyesa)
+ YYSTACK_FREE (yyes);]])b4_push_if([[
+ yyps->yynew = 1;
+
+
+/*-----------------------------------------.
+| yypushreturn -- ask for the next token. |
+`-----------------------------------------*/
+yypushreturn:]])[
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+]b4_epilogue[]dnl
+b4_output_end
+
+b4_defines_if([[
+]b4_output_begin([b4_spec_defines_file])[
+]b4_copyright([Bison interface for Yacc-like parsers in C])[
+]b4_disclaimer[
+]b4_shared_declarations[
+]b4_output_end[
+]])# b4_defines_if