mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
lalr1.cc: YY_ASSERT should use api.prefix
Working on the previous commit I realized that YY_ASSERT was used in the generated headers, so must follow api.prefix to avoid clashes when multiple C++ parser with variants are used. Actually many more macros should obey api.prefix (YY_CPLUSPLUS, YY_COPY, etc.). There was no complaint so far, so it's not urgent enough for 3.7.4, but it should be addressed in 3.8. * data/skeletons/variant.hh (b4_assert): New. Use it. * tests/local.at (AT_YYLEX_RETURN): Fix. * tests/headers.at: Make sure variant-based C++ parsers are checked too. This test did find that YY_ASSERT escaped renaming (before the fix in this commit).
This commit is contained in:
3
NEWS
3
NEWS
@@ -15,6 +15,9 @@ GNU Bison NEWS
|
||||
even when the `parse.assert` %define variable is not enabled. It no
|
||||
longer does.
|
||||
|
||||
The private internal macro YY_ASSERT now obeys the `api.prefix` %define
|
||||
variable.
|
||||
|
||||
** Changes
|
||||
|
||||
The YYBISON macro in generated "regular C parsers" (from the "yacc.c"
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
## variant. ##
|
||||
## --------- ##
|
||||
|
||||
# b4_assert
|
||||
# ---------
|
||||
# The name of YY_ASSERT.
|
||||
m4_define([b4_assert],
|
||||
[b4_api_PREFIX[]_ASSERT])
|
||||
|
||||
|
||||
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
|
||||
# ------------------------------------------------
|
||||
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
|
||||
@@ -72,9 +79,9 @@ m4_map([ b4_symbol_tag_comment], [$@])dnl
|
||||
# The needed includes for variants support.
|
||||
m4_define([b4_variant_includes],
|
||||
[b4_parse_assert_if([[#include <typeinfo>
|
||||
#ifndef YY_ASSERT
|
||||
#ifndef ]b4_assert[
|
||||
# include <cassert>
|
||||
# define YY_ASSERT assert
|
||||
# define ]b4_assert[ assert
|
||||
#endif
|
||||
]])])
|
||||
|
||||
@@ -111,7 +118,7 @@ m4_define([b4_value_type_declare],
|
||||
semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
|
||||
: yytypeid_ (&typeid (T))])[
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (sizeof (T) <= size);]])[
|
||||
]b4_assert[ (sizeof (T) <= size);]])[
|
||||
new (yyas_<T> ()) T (YY_MOVE (t));
|
||||
}
|
||||
|
||||
@@ -125,7 +132,7 @@ m4_define([b4_value_type_declare],
|
||||
/// Destruction, allowed only if empty.
|
||||
~semantic_type () YY_NOEXCEPT
|
||||
{]b4_parse_assert_if([
|
||||
YY_ASSERT (!yytypeid_);
|
||||
]b4_assert[ (!yytypeid_);
|
||||
])[}
|
||||
|
||||
# if 201103L <= YY_CPLUSPLUS
|
||||
@@ -134,8 +141,8 @@ m4_define([b4_value_type_declare],
|
||||
T&
|
||||
emplace (U&&... u)
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (!yytypeid_);
|
||||
YY_ASSERT (sizeof (T) <= size);
|
||||
]b4_assert[ (!yytypeid_);
|
||||
]b4_assert[ (sizeof (T) <= size);
|
||||
yytypeid_ = & typeid (T);]])[
|
||||
return *new (yyas_<T> ()) T (std::forward <U>(u)...);
|
||||
}
|
||||
@@ -145,8 +152,8 @@ m4_define([b4_value_type_declare],
|
||||
T&
|
||||
emplace ()
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (!yytypeid_);
|
||||
YY_ASSERT (sizeof (T) <= size);
|
||||
]b4_assert[ (!yytypeid_);
|
||||
]b4_assert[ (sizeof (T) <= size);
|
||||
yytypeid_ = & typeid (T);]])[
|
||||
return *new (yyas_<T> ()) T ();
|
||||
}
|
||||
@@ -156,8 +163,8 @@ m4_define([b4_value_type_declare],
|
||||
T&
|
||||
emplace (const T& t)
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (!yytypeid_);
|
||||
YY_ASSERT (sizeof (T) <= size);
|
||||
]b4_assert[ (!yytypeid_);
|
||||
]b4_assert[ (sizeof (T) <= size);
|
||||
yytypeid_ = & typeid (T);]])[
|
||||
return *new (yyas_<T> ()) T (t);
|
||||
}
|
||||
@@ -186,9 +193,9 @@ m4_define([b4_value_type_declare],
|
||||
T&
|
||||
as () YY_NOEXCEPT
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (yytypeid_);
|
||||
YY_ASSERT (*yytypeid_ == typeid (T));
|
||||
YY_ASSERT (sizeof (T) <= size);]])[
|
||||
]b4_assert[ (yytypeid_);
|
||||
]b4_assert[ (*yytypeid_ == typeid (T));
|
||||
]b4_assert[ (sizeof (T) <= size);]])[
|
||||
return *yyas_<T> ();
|
||||
}
|
||||
|
||||
@@ -197,9 +204,9 @@ m4_define([b4_value_type_declare],
|
||||
const T&
|
||||
as () const YY_NOEXCEPT
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (yytypeid_);
|
||||
YY_ASSERT (*yytypeid_ == typeid (T));
|
||||
YY_ASSERT (sizeof (T) <= size);]])[
|
||||
]b4_assert[ (yytypeid_);
|
||||
]b4_assert[ (*yytypeid_ == typeid (T));
|
||||
]b4_assert[ (sizeof (T) <= size);]])[
|
||||
return *yyas_<T> ();
|
||||
}
|
||||
|
||||
@@ -215,8 +222,8 @@ m4_define([b4_value_type_declare],
|
||||
void
|
||||
swap (self_type& that) YY_NOEXCEPT
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (yytypeid_);
|
||||
YY_ASSERT (*yytypeid_ == *that.yytypeid_);]])[
|
||||
]b4_assert[ (yytypeid_);
|
||||
]b4_assert[ (*yytypeid_ == *that.yytypeid_);]])[
|
||||
std::swap (as<T> (), that.as<T> ());
|
||||
}
|
||||
|
||||
@@ -421,7 +428,7 @@ m4_define([_b4_token_constructor_define],
|
||||
b4_locations_if([l]))[)
|
||||
#endif
|
||||
{]b4_parse_assert_if([[
|
||||
YY_ASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
|
||||
]b4_assert[ (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
|
||||
]])[}
|
||||
]])])
|
||||
|
||||
|
||||
@@ -204,17 +204,20 @@ AT_SETUP([Several parsers])
|
||||
# Generate and compile to *.o. Make sure there is no (allowed) YY*
|
||||
# nor yy* identifiers in the header after applying api.prefix. Check
|
||||
# that headers can be compiled by a C++ compiler.
|
||||
#
|
||||
# They should all use parse.assert to make sure that we don't even
|
||||
# conflict of YY_ASSERT.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} $2])
|
||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} %define parse.assert $2])
|
||||
AT_DATA_GRAMMAR([$1.y],
|
||||
[[%define api.prefix {$1_}
|
||||
%define parse.assert
|
||||
$2
|
||||
%define parse.error verbose
|
||||
%union
|
||||
{
|
||||
int integer;
|
||||
}
|
||||
%{
|
||||
]AT_VARIANT_IF([],
|
||||
[%union {int integer;}])[
|
||||
|
||||
%code {
|
||||
#include <stdio.h> /* printf. */
|
||||
]AT_PUSH_IF([[
|
||||
#if defined __GNUC__ && (7 == __GNUC__ || 9 == __GNUC__)
|
||||
@@ -223,8 +226,10 @@ $2
|
||||
]])[
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
%}
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
exp:
|
||||
'x' '1' { printf ("x1\n"); }
|
||||
| 'x' '2' { printf ("x2\n"); }
|
||||
@@ -235,9 +240,12 @@ exp:
|
||||
| 'x' '7' { printf ("x7\n"); }
|
||||
| 'x' '8' { printf ("x8\n"); }
|
||||
| 'x' '9' { printf ("x9\n"); }
|
||||
| 'x' 'a' { printf ("xa\n"); }
|
||||
| 'x' 'b' { printf ("xb\n"); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE(["$1"])[
|
||||
]])
|
||||
@@ -270,6 +278,8 @@ extern "C"
|
||||
#endif
|
||||
#include "x5.hh"
|
||||
#include "x9.hh"
|
||||
#include "xa.hh"
|
||||
#include "xb.hh"
|
||||
|
||||
#define RUN(S) \
|
||||
do { \
|
||||
@@ -292,6 +302,10 @@ main (void)
|
||||
RUN(x8_parse());
|
||||
x9_::parser p9;
|
||||
RUN(p9.parse());
|
||||
xa_::parser pa;
|
||||
RUN(pa.parse());
|
||||
xb_::parser pb;
|
||||
RUN(pb.parse());
|
||||
return 0;
|
||||
}
|
||||
]])# main.cc
|
||||
@@ -304,7 +318,9 @@ AT_TEST([x5], [%locations %debug %language "c++"])
|
||||
AT_TEST([x6], [%define api.pure])
|
||||
AT_TEST([x7], [%define api.push-pull both])
|
||||
AT_TEST([x8], [%define api.pure %define api.push-pull both])
|
||||
AT_TEST([x9], [%locations %code requires {#include "location.hh"} %define api.location.type {x5_::location} %debug %language "c++"])
|
||||
AT_TEST([x9], [%locations %code requires {#include "location.hh"} %define api.location.type {::x5_::location} %debug %language "c++"])
|
||||
AT_TEST([xa], [%locations %code requires {#include "location.hh"} %define api.location.type {::x5_::location} %language "c++" %define api.value.type variant])
|
||||
AT_TEST([xb], [%locations %define api.location.file none %language "c++" %define api.value.type variant])
|
||||
#AT_TEST([x5], [%locations %language "c++" %glr-parser])
|
||||
|
||||
# Check that api.prefix works properly:
|
||||
@@ -340,6 +356,8 @@ AT_PERL_CHECK([[-n -0777 -e '
|
||||
|YY_NULLPTR
|
||||
|YY_RVREF
|
||||
|YY_\w+_INCLUDED
|
||||
|FILE\ \*yyo # Function argument.
|
||||
|const\ yylocp # Function argument.
|
||||
)\b}{}gx;
|
||||
while (/^(.*YY.*)$/gm)
|
||||
{
|
||||
@@ -357,7 +375,7 @@ AT_PERL_CHECK([[-n -0777 -e '
|
||||
# Do this late, so that other checks have been performed.
|
||||
AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
|
||||
|
||||
AT_COMPILE_CXX([parser], [[x[1-9].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
|
||||
AT_COMPILE_CXX([parser], [[x[1-9a-b].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
|
||||
AT_PARSER_CHECK([parser], [0], [[expout]])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
@@ -351,7 +351,7 @@ AT_TOKEN_CTOR_IF(
|
||||
[m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]])
|
||||
m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]])
|
||||
m4_pushdef([AT_YYLEX_FORMALS], [])
|
||||
m4_pushdef([AT_YYLEX_RETURN], [yy::parser::symbol_type])
|
||||
m4_pushdef([AT_YYLEX_RETURN], [AT_NAMESPACE::parser::symbol_type])
|
||||
m4_pushdef([AT_YYLEX_ARGS], [])
|
||||
m4_pushdef([AT_USE_LEX_ARGS], [])
|
||||
m4_pushdef([AT_YYLEX_PRE_FORMALS], [])
|
||||
|
||||
Reference in New Issue
Block a user