bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Akim Demaille
Subject: [PATCH 3/5] lalr1.cc: YY_ASSERT should use api.prefix
Date: Wed, 11 Nov 2020 16:39:49 +0100

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]