Skip to content

Commit dc6144e

Browse files
committed
Correct tuple/struct confusion in the logic of the if constexpr chain in
perm_parser. Test case by Andreas Buhr. Fixes #268.
1 parent d873d7e commit dc6144e

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

include/boost/parser/parser.hpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3680,9 +3680,7 @@ namespace boost { namespace parser {
36803680
call(first, last, context, skip, flags, success, attr);
36813681
if (success)
36823682
detail::assign(retval, std::move(attr));
3683-
} else if constexpr (
3684-
detail::is_tuple<Attribute>{} ||
3685-
detail::is_struct_compatible_v<Attribute, result_t>) {
3683+
} else if constexpr (detail::is_tuple<Attribute>{}) {
36863684
call_impl(
36873685
first,
36883686
last,
@@ -3695,9 +3693,9 @@ namespace boost { namespace parser {
36953693

36963694
if (!success)
36973695
detail::assign(retval, Attribute());
3698-
} else if constexpr (detail::is_constructible_from_tuple_v<
3699-
Attribute,
3700-
result_t>) {
3696+
} else if constexpr (
3697+
detail::is_struct_compatible_v<Attribute, result_t> ||
3698+
detail::is_constructible_from_tuple_v<Attribute, result_t>) {
37013699
result_t temp_retval{};
37023700
call_impl(
37033701
first,
@@ -3710,10 +3708,16 @@ namespace boost { namespace parser {
37103708
indices);
37113709

37123710
if (success && detail::gen_attrs(flags)) {
3713-
detail::assign(
3714-
retval,
3715-
detail::make_from_tuple<Attribute>(
3716-
std::move(temp_retval)));
3711+
if constexpr (detail::is_struct_compatible_v<
3712+
Attribute,
3713+
result_t>) {
3714+
detail::assign(retval, temp_retval);
3715+
} else {
3716+
detail::assign(
3717+
retval,
3718+
detail::make_from_tuple<Attribute>(
3719+
std::move(temp_retval)));
3720+
}
37173721
}
37183722
} else {
37193723
#if 0 // TODO Seems incompatible with this parser.

test/github_issues.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,55 @@ void github_issue_248()
344344
}
345345
}
346346

347+
namespace github_issue_268_ {
348+
namespace bp = boost::parser;
349+
constexpr bp::rule<struct name, std::string_view> name = "name";
350+
auto name_def = bp::string_view[bp::lexeme[+(bp::lower | bp::upper | bp::digit | bp::char_("_"))]];
351+
BOOST_PARSER_DEFINE_RULES(name)
352+
constexpr bp::rule<struct qd_vec, std::vector<double>> qd_vec = "qd_vec";
353+
auto qd_vec_def = bp::lit("\"") >> bp::double_ % (bp::lit(",") | (bp::lit("\"") >> bp::lit(",") >> bp::lit("\""))) >> bp::lit('\"');
354+
BOOST_PARSER_DEFINE_RULES(qd_vec)
355+
struct lu_table_template_1
356+
{
357+
std::vector<double> index_1;
358+
std::string_view variable_1;
359+
};
360+
constexpr boost::parser::rule<struct lu_table_template_1_tag, lu_table_template_1> lu_table_template_1_rule = "lu_table_template_1";
361+
auto lu_table_template_1_rule_def = (bp::lit("index_1") >> '(' >> qd_vec >> ')' >> ';') >> (bp::lit("variable_1") >> ':' >> name >> ';');
362+
BOOST_PARSER_DEFINE_RULES(lu_table_template_1_rule)
363+
364+
constexpr boost::parser::rule<struct lu_table_template_1_permut_tag, lu_table_template_1> lu_table_template_1_permut_rule = "lu_table_template_1";
365+
auto lu_table_template_1_permut_rule_def = (bp::lit("index_1") >> '(' >> qd_vec >> ')' >> ';') || (bp::lit("variable_1") >> ':' >> name >> ';');
366+
BOOST_PARSER_DEFINE_RULES(lu_table_template_1_permut_rule)
367+
}
368+
369+
void github_issue_268()
370+
{
371+
namespace bp = boost::parser;
372+
using namespace github_issue_268_;
373+
std::string inputstring = "index_1 ( \"1\" ) ; variable_1 : bier;";
374+
375+
auto const def_result = bp::parse(
376+
inputstring, lu_table_template_1_rule_def, bp::blank, bp::trace::off);
377+
std::cout<< "seq_parser generates this type:\n" << typeid(def_result.value()).name() << std::endl;
378+
BOOST_TEST(def_result);
379+
380+
auto const permut_def_result = bp::parse(
381+
inputstring, lu_table_template_1_permut_rule_def, bp::blank, bp::trace::off);
382+
std::cout<< "permut_parser generates this type:\n" << typeid(permut_def_result.value()).name() << std::endl;
383+
BOOST_TEST(permut_def_result);
384+
385+
auto const result = bp::parse(
386+
inputstring, lu_table_template_1_rule, bp::blank, bp::trace::off);
387+
std::cout<< "seq_parser in rule generates this type:\n" << typeid(result.value()).name() << std::endl;
388+
BOOST_TEST(result);
389+
390+
auto const permut_result = bp::parse(
391+
inputstring, lu_table_template_1_permut_rule, bp::blank, bp::trace::off);
392+
std::cout<< "permut_parser generates this type:\n" << typeid(permut_result.value()).name() << std::endl;
393+
BOOST_TEST(permut_result);
394+
}
395+
347396
void github_issue_279()
348397
{
349398
namespace bp = boost::parser;
@@ -373,6 +422,7 @@ int main()
373422
github_issue_209();
374423
github_issue_223();
375424
github_issue_248();
425+
github_issue_268();
376426
github_issue_279();
377427
return boost::report_errors();
378428
}

0 commit comments

Comments
 (0)