-*- Autoconf -*-
# C M4 Macros for Bison.
-# Copyright (C) 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+
+# Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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_pkgdatadir/[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. ##
## ---------------- ##
# -----------------
# 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.
+# api.push-pull.
m4_define([b4_identification],
[[/* Identify Bison output. */
#define YYBISON 1
/* Pull parsers. */
#define YYPULL ]b4_pull_flag])[
-
-/* Using locations. */
-#define YYLSP_NEEDED ]b4_locations_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.
-m4_define_default([b4_union_name], [YYSTYPE])
+m4_define_default([b4_union_name], [b4_api_PREFIX[]STYPE])
-# If the %name-prefix is not given, it is yy.
-m4_define_default([b4_prefix], [yy])
## ------------------------ ##
## Pure/impure interfaces. ##
# 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_fst($1_$2))dnl
+[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_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. YYID must be defined as an identity
+# function that suppresses warnings about constant conditions.
+m4_define([b4_table_value_equals],
+[m4_if(m4_eval($3 < m4_indir([b4_]$1[_min])
+ || m4_indir([b4_]$1[_max]) < $3), [1],
+ [[YYID (0)]],
+ [(!!(($2) == ($3)))])])
+
+
## ---------##
## Values. ##
## ---------##
+
+# b4_null_define
+# --------------
+# Portability issues: define a YY_NULL appropriate for the current
+# language (C, C++98, or C++11).
+m4_define([b4_null_define],
+[# ifndef YY_NULL
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULL nullptr
+# else
+# define YY_NULL 0
+# endif
+# endif[]dnl
+])
+
+
# b4_null
----------
-# Return a null pointer constant. NULL infringes on the user name
-# space in C, so use 0 rather than NULL.
-m4_define([b4_null], [0])
+# -------
+# Return a null pointer constant.
+m4_define([b4_null], [YY_NULL])
+
## ------------------------- ##
# -------------------------------------------------------
# Output the definition of the tokens (if there are) as #defines.
m4_define([b4_token_defines],
-[m4_if([$@], [[]], [],
+[m4_if([$#$1], [1], [],
[/* Tokens. */
m4_map([b4_token_define], [$@])])
])
# -----------------------------------------------------
# Output the definition of the tokens (if there are) as enums.
m4_define([b4_token_enums],
-[m4_if([$@], [[]], [],
-[/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
+[m4_if([$#$1], [1], [],
+[[/* Tokens. */
+#ifndef ]b4_api_PREFIX[TOKENTYPE
+# define ]b4_api_PREFIX[TOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
- enum yytokentype {
-m4_map_sep([ b4_token_enum], [,
+ enum ]b4_api_prefix[tokentype {
+]m4_map_sep([ b4_token_enum], [,
],
- [$@])
+ [$@])[
};
#endif
-])])
+]])])
# b4_token_enums_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
b4_c_ansi_function_def($@)
#else
$2
-$1 (b4_c_knr_formal_names(m4_shiftn(2, $@)))
-b4_c_knr_formal_decls(m4_shiftn(2, $@))
+$1 (b4_c_knr_formal_names(m4_shift2($@)))
+b4_c_knr_formal_decls(m4_shift2($@))
#endif[]dnl
])
# Declare the function NAME in ANSI.
m4_define([b4_c_ansi_function_def],
[$2
-$1 (b4_c_ansi_formals(m4_shiftn(2, $@)))[]dnl
+$1 (b4_c_ansi_formals(m4_shift2($@)))[]dnl
])
# --------------------------------------
# Output the arguments ANSI-C definition.
m4_define([b4_c_ansi_formals],
-[m4_case([$@],
- [], [void],
- [[]], [void],
+[m4_if([$#], [0], [void],
+ [$#$1], [1], [void],
[m4_map_sep([b4_c_ansi_formal], [, ], [$@])])])
m4_define([b4_c_ansi_formal],
# ----------------------------------------------------------------
# Declare the function NAME.
m4_define([b4_c_ansi_function_decl],
-[$2 $1 (b4_c_ansi_formals(m4_shiftn(2, $@)));[]dnl
+[$2 $1 (b4_c_ansi_formals(m4_shift2($@)));[]dnl
])
# -----------------------------------------------------------
# Call the function NAME with arguments NAME1, NAME2 etc.
m4_define([b4_c_function_call],
-[$1 (b4_c_args(m4_shiftn(2, $@)))[]dnl
+[$1 (b4_c_args(m4_shift2($@)))[]dnl
])
# SYMBOL-TAG, SYMBOL-NUM,
# SYMBOL-ACTION, SYMBOL-TYPENAME)
# -------------------------------------------------
+# Issue the code for a symbol action (e.g., %printer).
+#
+# Define b4_dollar_dollar([TYPE-NAME]), and b4_at_dollar, which are
+# invoked where $<TYPE-NAME>$ and @$ were specified by the user.
m4_define([b4_symbol_actions],
-[m4_pushdef([b4_dollar_dollar],
- [m4_ifval([$6], [(yyvaluep->$6)], [(*yyvaluep)])])dnl
-m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
+[b4_dollar_pushdef([(*yyvaluep)], [$6], [(*yylocationp)])dnl
case $4: /* $3 */
b4_syncline([$2], [$1])
$5;
b4_syncline([@oline@], [@ofile@])
break;
-m4_popdef([b4_at_dollar])dnl
-m4_popdef([b4_dollar_dollar])dnl
+b4_dollar_popdef[]dnl
])
b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
m4_ifset([b4_parse_param], [, b4_parse_param]))[
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
if (!yyvaluep)
return;
]b4_locations_if([ YYUSE (yylocationp);
YYFPRINTF (yyoutput, ")");
}]dnl
])
+
+## -------------- ##
+## Declarations. ##
+## -------------- ##
+
+# 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],
+[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
+]m4_ifdef([b4_stype],
+[[typedef union ]b4_union_name[
+{
+]b4_user_stype[
+} ]b4_api_PREFIX[STYPE;
+# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]],
+[m4_if(b4_tag_seen_flag, 0,
+[[typedef int ]b4_api_PREFIX[STYPE;
+# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
+# define ]b4_api_prefix[stype ]b4_api_PREFIX[STYPE /* obsolescent; will be withdrawn */
+# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
+#endif]b4_locations_if([[
+
+#if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED
+typedef struct ]b4_api_PREFIX[LTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} ]b4_api_PREFIX[LTYPE;
+# define ]b4_api_prefix[ltype ]b4_api_PREFIX[LTYPE /* obsolescent; will be withdrawn */
+# define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
+# define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
+#endif]])
+
+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],
+[[/* Enabling traces. */
+]m4_if(b4_api_prefix, [yy],
+[[#ifndef YYDEBUG
+# define YYDEBUG ]b4_debug_flag[
+#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_debug_flag[
+# 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 (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+]])
+
+# 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
+# define YY_LOCATION_PRINT(File, Loc) \
+ do { \
+ fprintf (File, "%d.%d", (Loc).first_line, (Loc).first_column); \
+ if ((Loc).first_line < (Loc).last_line) \
+ fprintf (File, "-%d.%d", (Loc).last_line, (Loc).last_column - 1); \
+ else if ((Loc).first_column < (Loc).last_column - 1) \
+ fprintf (File, "-%d", (Loc).last_column - 1); \
+ } while (0)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#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
+]])