From fcd257abca28e5fb405bef7640b2c74b63287139 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Sat, 14 Dec 2024 15:28:53 -0600 Subject: [PATCH] Generalize with_parser_mods(), so that some functions can be recursive, and others can be non-recursive. See #160. --- include/boost/parser/parser.hpp | 138 ++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 34 deletions(-) diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index 32fe8afa..68d9ef4e 100644 --- a/include/boost/parser/parser.hpp +++ b/include/boost/parser/parser.hpp @@ -2965,14 +2965,19 @@ namespace boost { namespace parser { template auto modify_parsers(F f, tuple parsers) { - return modify_parsers_impl( - f, - parsers, - std::make_integer_sequence{}); + if constexpr (f.recursive) { + return modify_parsers_impl( + f, + parsers, + std::make_integer_sequence{}); + } else { + return parsers; + } } inline constexpr struct omit_attr_t { + static constexpr std::true_type recursive{}; template constexpr auto operator()(parser_modifiers const &) const { @@ -3293,7 +3298,11 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - if constexpr (std::is_same_v) { + if constexpr (!f.recursive) { + return parser::repeat_parser( + parser_, detail::nope{}, min_, max_, f(mods_)); + } else if constexpr (std:: + is_same_v) { return parser::repeat_parser( parser_.with_parser_mods(f), detail::nope{}, @@ -3333,8 +3342,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::zero_plus_parser( - this->parser_.with_parser_mods(f), f(this->mods_)); + if constexpr (f.recursive) { + return parser::zero_plus_parser( + this->parser_.with_parser_mods(f), f(this->mods_)); + } else { + return parser::zero_plus_parser(this->parser_, f(this->mods_)); + } } }; @@ -3353,8 +3366,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::one_plus_parser( - this->parser_.with_parser_mods(f), f(this->mods_)); + if constexpr (f.recursive) { + return parser::one_plus_parser( + this->parser_.with_parser_mods(f), f(this->mods_)); + } else { + return parser::one_plus_parser(this->parser_, f(this->mods_)); + } } }; @@ -3377,10 +3394,15 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::delimited_seq_parser( - this->parser_.with_parser_mods(f), - this->delimiter_parser_.with_parser_mods(f), - f(this->mods_)); + if constexpr (f.recursive) { + return parser::delimited_seq_parser( + this->parser_.with_parser_mods(f), + this->delimiter_parser_.with_parser_mods(f), + f(this->mods_)); + } else { + return parser::delimited_seq_parser( + this->parser_, this->delimiter_parser_, f(this->mods_)); + } } }; @@ -3458,11 +3480,18 @@ namespace boost { namespace parser { } //] + //[ opt_parser_with_parser_mods template constexpr auto with_parser_mods(F f) const { - return parser::opt_parser(parser_.with_parser_mods(f), f(mods_)); + if constexpr (f.recursive) { + return parser::opt_parser( + parser_.with_parser_mods(f), f(mods_)); + } else { + return parser::opt_parser(parser_, f(mods_)); + } } + //] //[ opt_parser_end Parser parser_; @@ -4895,8 +4924,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::action_parser( - parser_.with_parser_mods(f), action_, f(mods_)); + if constexpr (f.recursive) { + return parser::action_parser( + parser_.with_parser_mods(f), action_, f(mods_)); + } else { + return parser::action_parser(parser_, action_, f(mods_)); + } } Parser parser_; @@ -4970,8 +5003,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F2 f) const { - return parser::transform_parser( - parser_.with_parser_mods(f), f_, f(mods_)); + if constexpr (f.recursive) { + return parser::transform_parser( + parser_.with_parser_mods(f), f_, f(mods_)); + } else { + return parser::transform_parser(parser_, f_, f(mods_)); + } } Parser parser_; @@ -5047,7 +5084,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::raw_parser(parser_.with_parser_mods(f), f(mods_)); + if constexpr (f.recursive) { + return parser::raw_parser( + parser_.with_parser_mods(f), f(mods_)); + } else { + return parser::raw_parser(parser_, f(mods_)); + } } Parser parser_; @@ -5147,8 +5189,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::string_view_parser( - parser_.with_parser_mods(f), f(mods_)); + if constexpr (f.recursive) { + return parser::string_view_parser( + parser_.with_parser_mods(f), f(mods_)); + } else { + return parser::string_view_parser(parser_, f(mods_)); + } } Parser parser_; @@ -5216,7 +5262,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::lexeme_parser(parser_.with_parser_mods(f), f(mods_)); + if constexpr (f.recursive) { + return parser::lexeme_parser( + parser_.with_parser_mods(f), f(mods_)); + } else { + return parser::lexeme_parser(parser_, f(mods_)); + } } Parser parser_; @@ -5282,8 +5333,12 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::no_case_parser( - parser_.with_parser_mods(f), f(mods_)); + if constexpr (f.recursive) { + return parser::no_case_parser( + parser_.with_parser_mods(f), f(mods_)); + } else { + return parser::no_case_parser(parser_, f(mods_)); + } } Parser parser_; @@ -5362,10 +5417,14 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::skip_parser( - parser_.with_parser_mods(f), - skip_parser_.with_parser_mods(f), - f(mods_)); + if constexpr (f.recursive) { + return parser::skip_parser( + parser_.with_parser_mods(f), + skip_parser_.with_parser_mods(f), + f(mods_)); + } else { + return parser::skip_parser(parser_, skip_parser_, f(mods_)); + } } Parser parser_; @@ -5435,10 +5494,16 @@ namespace boost { namespace parser { constexpr auto with_parser_mods(F f) const { auto mods = f(mods_); - return expect_parser< - decltype(parser_.with_parser_mods(f)), - FailOnMatch, - decltype(mods)>{parser_.with_parser_mods(f), std::move(mods)}; + if constexpr (f.recursive) { + return expect_parser< + decltype(parser_.with_parser_mods(f)), + FailOnMatch, + decltype(mods)>{ + parser_.with_parser_mods(f), std::move(mods)}; + } else { + return expect_parser{ + parser_, std::move(mods)}; + } } Parser parser_; @@ -8876,8 +8941,13 @@ namespace boost { namespace parser { template constexpr auto with_parser_mods(F f) const { - return parser::switch_parser( - switch_value_, or_parser_with_parser_mods(f), f(mods_)); + if constexpr (f.recursive) { + return parser::switch_parser( + switch_value_, or_parser_.with_parser_mods(f), f(mods_)); + } else { + return parser::switch_parser( + switch_value_, or_parser_, f(mods_)); + } } SwitchValue switch_value_;