From 63884d2efa6dc9993e14595a472aaf54330ac97a Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Thu, 22 Feb 2024 00:09:29 -0600 Subject: [PATCH] Fix an error in seq_parser when a non-attribute parser fails internally, after the successful parse of an adjacent attribute-generating parser. Since the non-attribute parser points to the same spot in the output tuple, if the non-attribute parser fails internally, it is likely to do "out_attr = decltype(out_attr)()", which erases the previous seuccessfully generated attribute. --- include/boost/parser/parser.hpp | 6 +++++- test/parser.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index b8bc9d68..ec83f7a1 100644 --- a/include/boost/parser/parser.hpp +++ b/include/boost/parser/parser.hpp @@ -3914,10 +3914,11 @@ namespace boost { namespace parser { last, &context, &skip, - flags, + flags_ = flags, &success, &retval](auto const & parser_index_merged_and_backtrack) { + auto flags = flags_; using namespace literals; detail::skip(first, last, skip, flags); if (!success) // Someone earlier already failed... @@ -3969,6 +3970,9 @@ namespace boost { namespace parser { container>; constexpr bool attr_container = container; + if constexpr (detail::is_nope_v) + flags = detail::disable_attrs(flags); + if constexpr ( (out_container == attr_container && !was_merged_into_adjacent_container) || diff --git a/test/parser.cpp b/test/parser.cpp index 03691c69..3dc2faf9 100644 --- a/test/parser.cpp +++ b/test/parser.cpp @@ -2167,6 +2167,13 @@ TEST(parser, combined_seq_and_or) EXPECT_EQ(chars, "xyz"); } } + + { + constexpr auto parser = int_ >> -(lit('a') | 'b'); + auto result = parse("34b", parser); + EXPECT_TRUE(result); + EXPECT_EQ(*result, 34); + } } TEST(parser, eol_)