diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2020-11-11 11:39:02 +0100 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2020-11-13 06:17:52 +0100 |
commit | 8b424b865e7fc1932131beff5298dfde0623ce28 (patch) | |
tree | 444b80c7c4ab3a0eaee9f3120f0a74f6008c480a | |
parent | f4431ea11541ebb6a0f4d6cec8f120bd0639dd4a (diff) | |
download | bison-8b424b865e7fc1932131beff5298dfde0623ce28.tar.gz |
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).
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | data/skeletons/variant.hh | 45 | ||||
-rw-r--r-- | tests/headers.at | 36 | ||||
-rw-r--r-- | tests/local.at | 2 |
4 files changed, 57 insertions, 29 deletions
@@ -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], []) |