From 5d6d2f7b844bf7b75c49f36e2aa2de460ecd40e8 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Sat, 26 Jul 2025 20:15:15 -0500 Subject: [PATCH] Add missing special case for parsing a sequence of optionals, writing the results into a sequence container of Ts. Fixes #223. --- include/boost/parser/parser.hpp | 2 ++ test/github_issues.cpp | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index e94757dd..09ea1bc9 100644 --- a/include/boost/parser/parser.hpp +++ b/include/boost/parser/parser.hpp @@ -2809,6 +2809,8 @@ namespace boost { namespace parser { { if constexpr (is_nope_v) { return nope{}; + } else if constexpr (is_optional_v) { + return ParserAttr{}; } else { using value_type = range_value_t; return std::conditional_t< diff --git a/test/github_issues.cpp b/test/github_issues.cpp index af6727c2..6996cd45 100644 --- a/test/github_issues.cpp +++ b/test/github_issues.cpp @@ -258,6 +258,41 @@ void github_issue_209() std::end(bp::detail::char_set::chars))); } +void github_issue_223() +{ + namespace bp = boost::parser; + + // failing case + { + std::vector v; + const auto parser = *('x' | bp::char_('y')); + bp::parse("xy", parser, bp::ws, v); + + BOOST_TEST(v.size() == 1); + BOOST_TEST(v == std::vector({'y'})); + + std::cout << "v.size()=" << v.size() << "\n"; + for (auto c : v) { + std::cout << std::hex << (int)c << ' '; + } + std::cout << "\n"; + + // the assert fails since there are two elements in the vector: '\0' + // and 'y'. Seems pretty surprising to me + } + + // working case + { + const auto parser = *('x' | bp::char_('y')); + const auto result = bp::parse("xy", parser, bp::ws); + + BOOST_TEST(result->size() == 1); + BOOST_TEST(*result == std::vector>({'y'})); + + // success, the vector has only one 'y' element + } +} + int main() { @@ -268,5 +303,6 @@ int main() github_issue_90(); github_issue_125(); github_issue_209(); + github_issue_223(); return boost::report_errors(); }