Compare commits

...
22 Commits
Author SHA1 Message Date
Akim Demaille 8adec9c125 version 3.2.4
* NEWS: Record release date.
2018-12-24 17:45:02 +01:00
Akim Demaille cafa811a66 c++: also provide a copy constructor for symbol_type
Suggested by Wolfgang Thaller.
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00081.html

* data/c++.m4 (basic_symbol, by_type): Instead of provide either move
or copy constructor, always provide the copy one.
* tests/c++.at (C++ Variant-based Symbols Unit Tests): Check it.
2018-12-24 11:30:13 +01:00
Akim Demaille 07a187c5ee c++: fix double free when a symbol_type was moved
Currently the following piece of code crashes (with parse.assert),
because we don't record that s was moved-from, and we invoke its dtor.

    {
      auto s = parser::make_INT (42);
      auto s2 = std::move (s);
    }

Reported by Wolfgang Thaller.
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00077.html

* data/c++.m4 (by_type): Provide a move-ctor.
(basic_symbol): Be sure not to read a moved-from value.
* tests/c++.at (C++ Variant-based Symbols Unit Tests): Check this case.
2018-12-24 07:49:50 +01:00
Akim Demaille a81bcbb245 c++: style: improve tests
* tests/c++.at (C++ Variant-based Symbols Unit Tests): Provide better
assertions.
Use them.
Avoid useless Bison invocations.
2018-12-24 07:49:50 +01:00
Akim Demaille 96ef81cf07 c++: style: use consistently this/that instead of this/other
* data/c++.m4: here.
2018-12-23 19:39:47 +01:00
Akim Demaille fc54e6b9b3 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2018-12-18 23:07:55 +01:00
Akim Demaille cb3c595f6c version 3.2.3
* NEWS: Record release date.
2018-12-18 22:39:53 +01:00
Akim Demaille b741659d85 c++: fix token constructors for types with commas
Bitten by macros, again.
See 680b715518.

* data/variant.hh (_b4_symbol_constructor_declare)
(_b4_symbol_constructor_define): Do not use user types, which can
include commas as in `std::pair<int, int>`, to macros.

* tests/local.at: Adjust the lex related macros to support the
case of token constructors.
* tests/types.at: Also check token constructors on types with commas.
2018-12-18 19:15:41 +01:00
Akim Demaille 5e28cf53be maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2018-11-21 19:23:40 +01:00
Akim Demaille 5fb8b11152 version 3.2.2
* NEWS: Record release date.
2018-11-21 19:09:17 +01:00
Akim Demaille 2a1aefbf76 examples: remove useless includes
* examples/c++/variant-11.yy, examples/c++/variant.yy: here.
Fix warning when storing a long into an int.
2018-11-21 17:59:35 +01:00
Akim Demaille 734b0ce45d gnulib: update 2018-11-21 17:54:02 +01:00
Akim Demaille 59bcaebfae NEWS: update 2018-11-20 20:00:16 +01:00
Akim Demaille 680b715518 c++: using macros around user types breaks when they include comma
We may generate code such as

    basic_symbol (typename Base::kind_type t, YY_RVREF (std::pair<int,int>) v);

which, of course, breaks, because YY_RVREF sees two arguments.  Let's
not play tricks with _VA_ARGS__, I'm unsure about it portability.
Anyway, I plan to change more things in this area.

Reported by Sébastien Villemot.
http://lists.gnu.org/archive/html/bug-bison/2018-11/msg00014.html

* data/variant.hh (b4_basic_symbol_constructor_declare)
(b4_basic_symbol_constructor_define): Don't use macro on user types.
* tests/types.at: Check that we support pairs.
2018-11-20 19:57:09 +01:00
Akim Demaille 2eb1ad9ef3 glr.c: fix use of _Noreturn
In C++, [[noreturn]] must not be between "static" and the rest of the
function signature, it must precede it.  C's _Noreturn does not seem
to have such a constraint, but it is therefore compatible with the C++
constraint.  Since we #define _Noreturn as [[noreturn]] is modern C++,
be sure to push the _Noreturn first.

Unfortunately this was not caught by the test suite, because it always
loads config.h first, and config.h contains another definition of
_Noreturn that does not use [[noreturn]], and hides ours.  That's
probably a sign we should avoid always loading config.h.

* data/glr.c (yyFail, yyMemoryExhausted): here.
2018-11-20 18:47:45 +01:00
Akim Demaille 0360a35228 tests: run the api.value.type tests for all C++ standards
* tests/local.at (AT_LANG_FOR_EACH_STD): New.
(AT_REQUIRE_CXX_VERSION): Rename as...
(AT_REQUIRE_CXX_STD): this.
Accept an argument for what to do when the requirement is not met.
* tests/types.at (api.value.type): Check all the C++ stds.
2018-11-20 18:47:37 +01:00
Akim Demaille 2e053317c8 CI: split the ASAN job in two
The following commit introduce even more compilations/runs than
before, and with ASAN on, we go beyond to 50min credit from Travis.

* .travis.yml (Clang 7 libc++ and ASAN): Split in two.
2018-11-20 18:47:19 +01:00
Akim Demaille 33c788d37b c++: use YY_CPLUSPLUS
* data/c++.m4: here.
2018-11-20 18:47:08 +01:00
Akim Demaille c03d0d9625 c++: factor the handling of __cplusplus into YY_CPLUSPLUS
* data/c++.m4 (b4_cxx_portability): Define it.
Use it.
* data/lalr1.cc, data/variant.hh: Use it.
2018-11-20 18:46:52 +01:00
Akim Demaille bf7abf4849 tests: compile the C++ examples with warnings
* examples/c++/local.mk: Pass $(WARN_CXXFLAGS_TEST).
2018-11-20 18:46:27 +01:00
Akim Demaille 2731332150 tests: fix syncline tests
These tests are skipped with GCC:

    "\"".c:1:5: error: function declaration isn't a prototype [-Werror=strict-prototypes]
     int main() { return 0; }
         ^~~~

* tests/synclines.at: Stop writing C++ in C.
* tests/local.at: Formatting changes.
2018-11-20 18:44:30 +01:00
Akim Demaille 554a12102e maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2018-11-20 18:42:44 +01:00
18 changed files with 318 additions and 106 deletions
+1 -1
View File
@@ -1 +1 @@
3.2
3.2.3
+22 -5
View File
@@ -30,7 +30,9 @@ matrix:
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'"
- name: "Clang 7 libc++ and ASAN"
# ASAN is time consuming, and we timeout the 50min granted by
# Travis if we run all the tests in on go. Run in two parts.
- name: "Clang 7 libc++ and ASAN part 1"
os: linux
addons:
apt:
@@ -43,7 +45,22 @@ matrix:
- libc++abi-7-dev
env:
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
- MATRIX_EVAL="CC='clang-7 -fsanitize=address' CXX='clang++-7 -fsanitize=address -stdlib=libc++'"
- MATRIX_EVAL="PART=1 CC='clang-7 -fsanitize=address' CXX='clang++-7 -fsanitize=address -stdlib=libc++'"
- name: "Clang 7 libc++ and ASAN part 2"
os: linux
addons:
apt:
sources:
- llvm-toolchain-trusty-7
- ubuntu-toolchain-r-test
packages:
- clang-7
- libc++-7-dev
- libc++abi-7-dev
env:
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
- MATRIX_EVAL="PART=2 CC='clang-7 -fsanitize=address' CXX='clang++-7 -fsanitize=address -stdlib=libc++'"
- name: "ICC"
os: linux
@@ -292,9 +309,9 @@ script:
- if [[ -f ~/.bashrc ]]; then source ~/.bashrc; fi
- ./configure --enable-gcc-warnings CC="$CC" CXX="$CXX" $CONFIGUREFLAGS || { cat config.log && false; }
- make -j2 $MAKE_ARGS
- make check VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }
- make maintainer-check-posix VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }
- make maintainer-check-g++ VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }
- if test ${PART-1} = 1; then make check VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }; fi
- if test ${PART-1} = 1; then make maintainer-check-posix VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }; fi
- if test ${PART-2} = 2; then make maintainer-check-g++ VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }; fi
after_script:
- if [[ $CC == "icc" ]]; then uninstall_intel_software; fi
+21
View File
@@ -1,5 +1,26 @@
GNU Bison NEWS
* Noteworthy changes in release 3.2.4 (2018-12-24) [stable]
** Bug fixes
Fix the move constructor of symbol_type.
Always provide a copy constructor for symbol_type, even in modern C++.
* Noteworthy changes in release 3.2.3 (2018-12-18) [stable]
** Bug fixes
Properly support token constructors in C++ with types that include commas
(e.g., std::pair<int, int>). A regression introduced in Bison 3.2.
* Noteworthy changes in release 3.2.2 (2018-11-21) [stable]
** Bug fixes
C++ portability issues.
* Noteworthy changes in release 3.2.1 (2018-11-09) [stable]
** Bug fixes
+2
View File
@@ -151,6 +151,7 @@ Roland Levillain [email protected]
Satya Kiran Popuri [email protected]
Sebastian Setzer [email protected]
Sebastien Fricker [email protected]
Sébastien Villemot [email protected]
Sergei Steshenko [email protected]
Shura [email protected]
Simon Sobisch [email protected]
@@ -178,6 +179,7 @@ Wayne Green [email protected]
Wei Song [email protected]
Wojciech Polak [email protected]
Wolfgang S. Kechel [email protected]
Wolfgang Thaller [email protected]
Wolfram Wagner [email protected]
Wwp [email protected]
xolodho [email protected]
+51 -15
View File
@@ -53,8 +53,14 @@ m4_define([b4_inline],
# b4_cxx_portability
# ------------------
m4_define([b4_cxx_portability],
[// Support move semantics when possible.
#if defined __cplusplus && 201103L <= __cplusplus
[#if defined __cplusplus
# define YY_CPLUSPLUS __cplusplus
#else
# define YY_CPLUSPLUS 199711L
#endif
// Support move semantics when possible.
#if 201103L <= YY_CPLUSPLUS
# define YY_MOVE std::move
# define YY_MOVE_OR_COPY move
# define YY_MOVE_REF(Type) Type&&
@@ -238,8 +244,13 @@ m4_define([b4_symbol_type_declare],
/// Default constructor.
basic_symbol ();
/// Move or copy constructor.
basic_symbol (YY_RVREF (basic_symbol) other);
#if 201103L <= YY_CPLUSPLUS
/// Move constructor.
basic_symbol (basic_symbol&& that);
#endif
/// Copy constructor.
basic_symbol (const basic_symbol& that);
]b4_variant_if([[
/// Constructor for valueless symbols, and symbols from each type.
@@ -272,9 +283,9 @@ m4_define([b4_symbol_type_declare],
location_type location;])[
private:
#if !defined __cplusplus || __cplusplus < 201103L
#if YY_CPLUSPLUS < 201103L
/// Assignment operator.
basic_symbol& operator= (const basic_symbol& other);
basic_symbol& operator= (const basic_symbol& that);
#endif
};
@@ -284,8 +295,13 @@ m4_define([b4_symbol_type_declare],
/// Default constructor.
by_type ();
#if 201103L <= YY_CPLUSPLUS
/// Move constructor.
by_type (by_type&& that);
#endif
/// Copy constructor.
by_type (const by_type& other);
by_type (const by_type& that);
/// The symbol type as needed by the constructor.
typedef token_type kind_type;
@@ -333,14 +349,26 @@ m4_define([b4_public_types_define],
, location ()])[
{}
#if 201103L <= YY_CPLUSPLUS
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (YY_RVREF (basic_symbol) other)
: Base (YY_MOVE (other))
, value (]b4_variant_if([], [YY_MOVE (other.value)]))b4_locations_if([
, location (YY_MOVE (other.location))])[
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
: Base (std::move (that))
, value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([
, location (std::move (that.location))])[
{]b4_variant_if([
b4_symbol_variant([other.type_get ()], [value], [YY_MOVE_OR_COPY],
[YY_MOVE (other.value)])])[
b4_symbol_variant([this->type_get ()], [value], [move],
[std::move (that.value)])])[
}
#endif
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
: Base (that)
, value (]b4_variant_if([], [that.value]))b4_locations_if([
, location (that.location)])[
{]b4_variant_if([
b4_symbol_variant([this->type_get ()], [value], [copy],
[that.value])])[
}
]b4_variant_if([[
@@ -417,8 +445,16 @@ m4_define([b4_public_types_define],
: type (empty_symbol)
{}
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (const by_type& other)
: type (other.type)
#if 201103L <= YY_CPLUSPLUS
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (by_type&& that)
: type (that.type)
{
that.clear ();
}
#endif
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (const by_type& that)
: type (that.type)
{}
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (token_type t)
+2 -2
View File
@@ -706,7 +706,7 @@ struct yyGLRStack {
static void yyexpandGLRStack (yyGLRStack* yystackp);
#endif
static _Noreturn void
_Noreturn static void
yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
{
if (yymsg != YY_NULLPTR)
@@ -714,7 +714,7 @@ yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
YYLONGJMP (yystackp->yyexception_buffer, 1);
}
static _Noreturn void
_Noreturn static void
yyMemoryExhausted (yyGLRStack* yystackp)
{
YYLONGJMP (yystackp->yyexception_buffer, 2);
+4 -4
View File
@@ -336,7 +336,7 @@ m4_define([b4_shared_declarations],
stack_symbol_type (YY_RVREF (stack_symbol_type) that);
/// Steal the contents from \a sym to build this.
stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) sym);
#if !defined __cplusplus || __cplusplus < 201103L
#if YY_CPLUSPLUS < 201103L
/// Assignment, needed by push_back by some old implementations.
/// Moves the contents of that.
stack_symbol_type& operator= (stack_symbol_type& that);
@@ -612,7 +612,7 @@ m4_if(b4_prefix, [yy], [],
{]b4_variant_if([
b4_symbol_variant([that.type_get ()],
[value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[
#if defined __cplusplus && 201103L <= __cplusplus
#if 201103L <= YY_CPLUSPLUS
// that is emptied.
that.state = empty_state;
#endif
@@ -627,7 +627,7 @@ m4_if(b4_prefix, [yy], [],
that.type = empty_symbol;
}
#if !defined __cplusplus || __cplusplus < 201103L
#if YY_CPLUSPLUS < 201103L
]b4_parser_class_name[::stack_symbol_type&
]b4_parser_class_name[::stack_symbol_type::operator= (stack_symbol_type& that)
{
@@ -685,7 +685,7 @@ m4_if(b4_prefix, [yy], [],
void
]b4_parser_class_name[::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
{
#if defined __cplusplus && 201103L <= __cplusplus
#if 201103L <= YY_CPLUSPLUS
yypush_ (m, stack_symbol_type (s, std::move (sym)));
#else
stack_symbol_type ss (s, sym);
+61 -22
View File
@@ -125,7 +125,7 @@ m4_define([b4_variant_define],
return *new (yyas_<T> ()) T ();
}
# if defined __cplusplus && 201103L <= __cplusplus
# if 201103L <= YY_CPLUSPLUS
/// Instantiate a \a T in here from \a t.
template <typename T, typename U>
T&
@@ -213,7 +213,7 @@ m4_define([b4_variant_define],
void
move (self_type& other)
{
# if defined __cplusplus && 201103L <= __cplusplus
# if 201103L <= YY_CPLUSPLUS
emplace<T> (std::move (other.as<T> ()));
# else
emplace<T> ();
@@ -222,7 +222,7 @@ m4_define([b4_variant_define],
other.destroy<T> ();
}
# if defined __cplusplus && 201103L <= __cplusplus
# if 201103L <= YY_CPLUSPLUS
/// Move the content of \a other to this.
template <typename T>
void
@@ -335,13 +335,21 @@ m4_define([b4_symbol_value_template],
# these SYMBOL-NUMBERS. Use at class-level.
m4_define([_b4_symbol_constructor_declare],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ static
[#if 201103L <= YY_CPLUSPLUS
static
symbol_type
make_[]_b4_symbol([$1], [id]) (dnl
b4_join(b4_symbol_if([$1], [has_type],
[YY_COPY (b4_symbol([$1], [type])) v]),
b4_locations_if([YY_COPY (location_type) l])));
[b4_symbol([$1], [type]) v]),
b4_locations_if([location_type l])));
#else
static
symbol_type
make_[]_b4_symbol([$1], [id]) (dnl
b4_join(b4_symbol_if([$1], [has_type],
[const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l])));
#endif
])])])
@@ -360,18 +368,31 @@ b4_symbol_foreach([_b4_symbol_constructor_declare])])
# Define symbol constructor for this SYMBOL-NUMBER.
m4_define([_b4_symbol_constructor_define],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ inline
[# if 201103L <= YY_CPLUSPLUS
inline
b4_parser_class_name::symbol_type
b4_parser_class_name::make_[]_b4_symbol([$1], [id]) (dnl
b4_join(b4_symbol_if([$1], [has_type],
[YY_COPY (b4_symbol([$1], [type])) v]),
b4_locations_if([YY_COPY (location_type) l])))
[b4_symbol([$1], [type]) v]),
b4_locations_if([location_type l])))
{
return symbol_type (b4_join([token::b4_symbol([$1], [id])],
b4_symbol_if([$1], [has_type], [YY_MOVE (v)]),
b4_locations_if([YY_MOVE (l)])));
b4_symbol_if([$1], [has_type], [std::move (v)]),
b4_locations_if([std::move (l)])));
}
#else
inline
b4_parser_class_name::symbol_type
b4_parser_class_name::make_[]_b4_symbol([$1], [id]) (dnl
b4_join(b4_symbol_if([$1], [has_type],
[const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l])))
{
return symbol_type (b4_join([token::b4_symbol([$1], [id])],
b4_symbol_if([$1], [has_type], [v]),
b4_locations_if([l])));
}
#endif
])])])
@@ -379,26 +400,44 @@ b4_join(b4_symbol_if([$1], [has_type],
# -----------------------------------
# Generate a constructor declaration for basic_symbol from given type.
m4_define([b4_basic_symbol_constructor_declare],
[[ basic_symbol (]b4_join(
[[# if 201103L <= YY_CPLUSPLUS
basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], [YY_RVREF (b4_symbol([$1], [type])) v]),
b4_locations_if([YY_RVREF (location_type) l]))[);
b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
b4_locations_if([location_type&& l]))[);
#else
basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l]))[);
#endif
]])
# b4_basic_symbol_constructor_define
# ----------------------------------
# Generate a constructor implementation for basic_symbol from given type.
m4_define([b4_basic_symbol_constructor_define],
[[ template <typename Base>
[[# if 201103L <= YY_CPLUSPLUS
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], [YY_RVREF (b4_symbol([$1], [type])) v]),
b4_locations_if([YY_RVREF (location_type) l]))[)
b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
b4_locations_if([location_type&& l]))[)
: Base (t)]b4_symbol_if([$1], [has_type], [
, value (YY_MOVE (v))])[]b4_locations_if([
, location (YY_MOVE (l))])[
, value (std::move (v))])[]b4_locations_if([
, location (std::move (l))])[
{}
#else
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l]))[)
: Base (t)]b4_symbol_if([$1], [has_type], [
, value (v)])[]b4_locations_if([
, location (l)])[
{}
#endif
]])
# b4_symbol_constructor_define
+2 -2
View File
@@ -32,7 +32,7 @@ if ENABLE_CXX14
check_PROGRAMS += %D%/simple
nodist_%C%_simple_SOURCES = $(simple_sources)
%C%_simple_CXXFLAGS = $(CXX11_CXXFLAGS)
%C%_simple_CXXFLAGS = $(CXX11_CXXFLAGS) $(WARN_CXXFLAGS_TEST)
# Don't use gnulib's system headers.
%C%_simple_CPPFLAGS = -I$(top_builddir)
TESTS += %D%/simple.test
@@ -58,7 +58,7 @@ EXTRA_DIST += %D%/variant.test
if ENABLE_CXX11
check_PROGRAMS += %D%/variant-11
nodist_%C%_variant_11_SOURCES = %D%/variant-11.yy
%C%_variant_11_CXXFLAGS = $(CXX11_CXXFLAGS)
%C%_variant_11_CXXFLAGS = $(CXX11_CXXFLAGS) $(WARN_CXXFLAGS_TEST)
# Don't use gnulib's system headers.
%C%_variant_11_CPPFLAGS = -I$(top_builddir)
TESTS += %D%/variant-11.test
+5 -3
View File
@@ -37,9 +37,8 @@
%code // *.cc
{
#include <algorithm>
#include <climits> // INT_MIN, INT_MAX
#include <iostream>
#include <iterator>
#include <sstream>
namespace yy
@@ -141,7 +140,10 @@ int
main (int argc, const char *argv[])
{
if (2 <= argc && isdigit (*argv[1]))
max = strtol (argv[1], nullptr, 10);
{
auto maxl = strtol (argv[1], nullptr, 10);
max = INT_MIN <= maxl && maxl <= INT_MAX ? int(maxl) : 4;
}
auto&& p = yy::parser{};
p.set_debug_level (!!getenv ("YYDEBUG"));
return p.parse ();
-2
View File
@@ -33,9 +33,7 @@ typedef std::vector<std::string> strings_type;
%code // *.cc
{
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
namespace yy
+1 -1
Submodule gnulib updated: a79f2a2871...48a6c46b0b
+1
View File
@@ -190,3 +190,4 @@
/localtime-buffer.m4
/sys_resource_h.m4
/timespec.m4
/intl-thread-locale.m4
+39 -13
View File
@@ -103,7 +103,7 @@ AT_KEYWORDS([variant])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
# Store strings and integers in a vector of strings.
AT_DATA_GRAMMAR([list.y],
AT_DATA_GRAMMAR([list.yy],
[[%skeleton "lalr1.cc"
%define api.value.type variant
%define parse.assert
@@ -142,24 +142,52 @@ exp: "int" { $$.push_back ($1); }
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[
template <typename Exp, typename Eff>
void assert_eq (const Exp& exp, const Eff& eff)
{
if (getenv ("DEBUG"))
std::cerr << "Assert: " << exp << " == " << eff << '\n';
if (exp != eff)
std::cerr << "Assertion failed: " << exp << " != " << eff << '\n';
}
int main()
{
using yy::parser;
// symbol_type: construction, accessor.
{
parser::symbol_type s = parser::make_INT(12);
std::cerr << s.value.as<int>() << '\n';
parser::symbol_type s = parser::make_INT (12);
assert_eq (s.value.as<int> (), 12);
}
// symbol_type: move constructor.
#if 201103L <= YY_CPLUSPLUS
{
auto s = parser::make_INT (42);
auto s2 = std::move (s);
assert_eq (s2.value.as<int> (), 42);
// Used to crash here, because s was improperly cleared, and
// its destructor tried to delete its (moved) value.
}
#endif
// symbol_type: copy constructor.
{
parser::symbol_type s = parser::make_INT (51);
parser::symbol_type s2 = s;
assert_eq (s.value.as<int> (), 51);
assert_eq (s2.value.as<int> (), 51);
}
// stack_symbol_type: construction, accessor.
{
#if defined __cplusplus && 201103L <= __cplusplus
#if 201103L <= YY_CPLUSPLUS
auto ss = parser::stack_symbol_type(1, parser::make_INT(123));
#else
parser::symbol_type s = parser::make_INT(123);
parser::symbol_type s = parser::make_INT (123);
parser::stack_symbol_type ss(1, s);
#endif
std::cerr << ss.value.as<int>() << '\n';
assert_eq (ss.value.as<int> (), 123);
}
// Pushing on the stack.
@@ -170,7 +198,7 @@ int main()
const int mucho = 1700;
for (int i = 0; i < mucho; ++i)
{
#if defined __cplusplus && 201103L <= __cplusplus
#if 201103L <= YY_CPLUSPLUS
st.push(parser::stack_symbol_type{1, parser::make_INT (i)});
#else
parser::symbol_type s = parser::make_INT (i);
@@ -180,19 +208,17 @@ int main()
}
for (int i = mucho - 1; 0 <= i; --i)
{
assert (st[0].value.as<int>() == i);
assert_eq (st[0].value.as<int>(), i);
st.pop ();
}
}
}
]])
AT_BISON_CHECK([[-o list.cc list.yy]])
AT_FOR_EACH_CXX([
AT_FULL_COMPILE([list])
AT_PARSER_CHECK([./list], 0, [],
[12
123
])
AT_COMPILE_CXX([list])
AT_PARSER_CHECK([./list])
])
AT_BISON_OPTION_POPDEFS
+1
View File
@@ -317,6 +317,7 @@ AT_CHECK([[$PERL -n -0777 -e '
|YYUSE
|YY_ATTRIBUTE(?:_PURE|_UNUSED)?
|YY_COPY
|YY_CPLUSPLUS
|YY_IGNORE_MAYBE_UNINITIALIZED_(?:BEGIN|END)
|YY_INITIAL_VALUE
|YY_MOVE
+58 -31
View File
@@ -248,16 +248,25 @@ m4_pushdef([AT_YYLTYPE],
[AT_CXX_IF([AT_NAMESPACE[::parser::location_type]],
[AT_API_PREFIX[LTYPE]])])
AT_PURE_LEX_IF(
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_ARGS], [])
m4_pushdef([AT_USE_LEX_ARGS], [])
m4_pushdef([AT_YYLEX_PRE_FORMALS], [])
m4_pushdef([AT_YYLEX_PRE_ARGS], [])],
[AT_PURE_LEX_IF(
[m4_pushdef([AT_LOC], [(*llocp)])
m4_pushdef([AT_VAL], [(*lvalp)])
m4_pushdef([AT_YYLEX_FORMALS],
[AT_YYSTYPE *lvalp[]AT_LOCATION_IF([, AT_YYLTYPE *llocp])])
m4_pushdef([AT_YYLEX_RETURN], [int])
m4_pushdef([AT_YYLEX_ARGS],
[lvalp[]AT_LOCATION_IF([, llocp])])
m4_pushdef([AT_USE_LEX_ARGS],
[(void) lvalp;AT_LOCATION_IF([(void) llocp])])
[(void) lvalp;AT_LOCATION_IF([(void) llocp;])])
m4_pushdef([AT_YYLEX_PRE_FORMALS],
[AT_YYLEX_FORMALS, ])
m4_pushdef([AT_YYLEX_PRE_ARGS],
@@ -266,11 +275,12 @@ AT_PURE_LEX_IF(
[m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]])
m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]])
m4_pushdef([AT_YYLEX_FORMALS], [void])
m4_pushdef([AT_YYLEX_RETURN], [int])
m4_pushdef([AT_YYLEX_ARGS], [])
m4_pushdef([AT_USE_LEX_ARGS], [])
m4_pushdef([AT_USE_LEX_ARGS], [])
m4_pushdef([AT_YYLEX_PRE_FORMALS], [])
m4_pushdef([AT_YYLEX_PRE_ARGS], [])
])
])])
# Handle the different types of location components.
@@ -403,7 +413,7 @@ $2])
# ACTION may compute yylval for instance, using "res" as token type,
# and "toknum" as the number of calls to yylex (starting at 0).
m4_define([AT_YYLEX_PROTOTYPE],
[int AT_NAME_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl
[AT_YYLEX_RETURN AT_NAME_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl
])
m4_define([AT_YYLEX_DECLARE_EXTERN],
@@ -424,15 +434,15 @@ static
[[static int const input[] = ]$1])[;
static size_t toknum = 0;
int res;
]AT_USE_LEX_ARGS[;
]AT_USE_LEX_ARGS[
assert (toknum < sizeof input / sizeof input[0]);
res = input[toknum++];
]$2[;]AT_LOCATION_IF([[
]$2[;]AT_TOKEN_CTOR_IF([], [[
]AT_LOCATION_IF([[
]AT_LOC_FIRST_LINE[ = ]AT_LOC_LAST_LINE[ = 1;
]AT_LOC_FIRST_COLUMN[ = ]AT_LOC_LAST_COLUMN[ = ]AT_CXX_IF([(unsigned )], [(int)])[toknum;]])[
return res;
}]dnl
])
return res;]])[
}]])
# AT_YYERROR_FORMALS
# AT_YYERROR_PROTOTYPE
@@ -539,6 +549,9 @@ main (int argc, char const* argv[])
return ]AT_NAME_PREFIX[parse ();
}]])
m4_define([AT_LANG_FOR_EACH_STD(c)],
[$1])
## ----- ##
## C++. ##
@@ -573,21 +586,24 @@ main (int argc, char const* argv[])
return p.parse ();
}]])
m4_define([AT_LANG_FOR_EACH_STD(c++)],
[AT_FOR_EACH_CXX([$1])])
m4_define([AT_FOR_EACH_CXX],
[[at_for_each_cxx_CXXFLAGS_save=$CXXFLAGS
for at_cxx_std in '' \
${CXX98_CXXFLAGS:+"$CXX98_CXXFLAGS"} \
${CXX03_CXXFLAGS:+"$CXX03_CXXFLAGS"} \
${CXX11_CXXFLAGS:+"$CXX11_CXXFLAGS"} \
${CXX14_CXXFLAGS:+"$CXX14_CXXFLAGS"} \
${CXX17_CXXFLAGS:+"$CXX17_CXXFLAGS"} \
${CXX2A_CXXFLAGS:+"$CXX2A_CXXFLAGS"}
[[at_for_each_std_CXXFLAGS_save=$CXXFLAGS
for at_std in '' \
${CXX98_CXXFLAGS:+"$CXX98_CXXFLAGS"} \
${CXX03_CXXFLAGS:+"$CXX03_CXXFLAGS"} \
${CXX11_CXXFLAGS:+"$CXX11_CXXFLAGS"} \
${CXX14_CXXFLAGS:+"$CXX14_CXXFLAGS"} \
${CXX17_CXXFLAGS:+"$CXX17_CXXFLAGS"} \
${CXX2A_CXXFLAGS:+"$CXX2A_CXXFLAGS"}
do
]AS_ECHO(["======== Testing with C++ standard flags: '$at_cxx_std'"])[
CXXFLAGS="$at_for_each_cxx_CXXFLAGS_save $at_cxx_std"
CXXFLAGS="$at_for_each_std_CXXFLAGS_save $at_std"
]$1[
done
CXXFLAGS=$at_for_each_cxx_CXXFLAGS_save
CXXFLAGS=$at_for_each_std_CXXFLAGS_save
]])
## ------ ##
@@ -619,7 +635,8 @@ m4_define([AT_MAIN_DEFINE(java)],
}
}]])
m4_define([AT_LANG_FOR_EACH_STD(java)],
[$1])
## --------------- ##
## Running Bison. ##
@@ -819,6 +836,11 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
[[0]], [ignore], [ignore])])
# AT_LANG_FOR_EACH_STD(BODY)
# -------------------------------
m4_define([AT_LANG_FOR_EACH_STD], [AT_LANG_DISPATCH([$0], $@)])
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c], [EXTRA-COMPILER-FLAGS])
# ---------------------------------------------------------------------
# Compile SOURCES into OUTPUT. Skip if compiler does not work.
@@ -904,11 +926,11 @@ AT_PARSER_CHECK([./c-and-cxx])
])
# AT_REQUIRE_CXX_VERSION(STD)
# ---------------------------
# AT_REQUIRE_CXX_STD(STD, [IF-FAIL = SKIP])
# -----------------------------------------
# Skip unless this compiler supports at least C++ STD (e.g., "11",
# "14", etc.).
m4_define([AT_REQUIRE_CXX_VERSION],
m4_define([AT_REQUIRE_CXX_STD],
[AT_DATA([check.cc],
[[int main ()
{
@@ -920,14 +942,19 @@ m4_define([AT_REQUIRE_CXX_VERSION],
[17], [201703],
[2a], [201709],
[m4_fatal([$0: invalid arguments: $@])])[
return 77;
return 1;
#else
return 0;
#endif
}
]])
AT_COMPILE_CXX([check])
AT_CHECK([@&t@./check])
AT_CHECK([@&t@./check], [ignore])
m4_ifval([$2],
[if test $at_status != 0; then
$2
fi],
[SKIP_IF([test $at_status != 0])])
])
@@ -940,11 +967,11 @@ m4_define([AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR],
[[#include <iostream>
#include <stdexcept>
void foo()
void foo ()
{
try
{
throw std::runtime_error("foo");
throw std::runtime_error ("foo");
}
catch (...)
{
@@ -953,11 +980,11 @@ void foo()
}
}
int main()
int main ()
{
try
{
foo();
foo ();
}
catch (...)
{
+1 -1
View File
@@ -396,7 +396,7 @@ AT_BISON_OPTION_PUSHDEFS([%skeleton "$1"])
# properly to the linker, and is unable to save a file named this way.
# Don't try with such compilers.
AT_DATA([\"\\\"\".c],
[[int main() { return 0; }
[[int main (void) { return 0; }
]])
AT_CHECK([AT_CXX_IF([$CXX $CXXFLAGS], [$CC $CFLAGS]) $CPPFLAGS \"\\\"\".c -o \"\\\"\" ||
+46 -4
View File
@@ -78,7 +78,7 @@ m4_pushdef([_AT_TEST],
[
AT_SETUP([$1])
AT_KEYWORDS([api.value.type])
$7
AT_BISON_OPTION_PUSHDEFS([%debug $1 $2])
AT_DATA_GRAMMAR([test.y],
[[%debug
@@ -104,9 +104,12 @@ start: $3;
]AT_MAIN_DEFINE[
]])
AT_FULL_COMPILE([[test]])
AT_PARSER_CHECK([[./test]], 0, [[$6
AT_LANG_FOR_EACH_STD([
$7
AT_FULL_COMPILE([[test]])
AT_PARSER_CHECK([[./test]], 0, [[$6
]])
])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
@@ -267,6 +270,44 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
AT_VAL.build<std::string> ("two");],
[10, two])
# Test a regression where we passed user types (we can include
# commas) to a CPP macro.
AT_TEST([%skeleton "]b4_skel["
%define api.value.type variant],
[%token <std::pair<int, int>> '1';
%token <std::pair<std::string, std::string>> '2';],
['1' '2'
{
std::cout << $1.first << ':' << $1.second << ", "
<< $2.first << ':' << $2.second << '\n';
}],
["12"],
[if (res == '1')
AT_VAL.build (std::make_pair (10, 11));
else if (res == '2')
AT_VAL.build (std::make_pair<std::string, std::string> ("two", "deux"));],
[10:11, two:deux])
AT_TEST([%skeleton "]b4_skel["
%code requires { #include <memory> }
%define api.value.type variant
%define api.token.constructor],
[[%token <std::unique_ptr<int>> ONE;
%token <std::pair<int, int>> TWO;
%token EOI 0;]],
[ONE TWO { std::cout << *$1 << ", "
<< $2.first << ", "
<< $2.second << '\n'; }],
["12"],
[[if (res == '1')
return yy::parser::make_ONE (std::make_unique<int> (10));
else if (res == '2')
return yy::parser::make_TWO (std::make_pair<int, int> (21, 22));
else
return yy::parser::make_EOI ()]],
[10, 21, 22],
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])
# Move-only types.
AT_TEST([%skeleton "]b4_skel["
%code requires { #include <memory> }
@@ -282,7 +323,8 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
]AT_VAL[.emplace <std::unique_ptr<std::string>>
(std::make_unique <std::string> ("two"));]],
[10, two],
[AT_REQUIRE_CXX_VERSION(14)])])
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])
])
])