[PATCH 3/5] lalr1.cc: YY_ASSERT should use api.prefix

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
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).
---
 NEWS                      |  3 +++
 data/skeletons/variant.hh | 45 ++++++++++++++++++++++-----------------
 tests/headers.at          | 36 +++++++++++++++++++++++--------
 tests/local.at            |  2 +-
 4 files changed, 57 insertions(+), 29 deletions(-)

diff --git a/NEWS b/NEWS
index c5775a69..8bdad6a6 100644
--- a/NEWS
+++ b/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"
diff --git a/data/skeletons/variant.hh b/data/skeletons/variant.hh
index 1fe40145..4734079b 100644
--- a/data/skeletons/variant.hh
+++ b/data/skeletons/variant.hh
@@ -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], [, ], [$@]))[);
       ]])[}
 ]])])
 
diff --git a/tests/headers.at b/tests/headers.at
index bf48120b..73a43454 100644
--- a/tests/headers.at
+++ b/tests/headers.at
@@ -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])
diff --git a/tests/local.at b/tests/local.at
index a4782362..91e1e734 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -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], [])
-- 
2.29.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.