From 3c65bcf187efea3a3fef39cc91509e9bc4194d15 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Fri, 13 Dec 2024 23:01:35 -0600 Subject: [PATCH] WIP --- include/boost/parser/parser.hpp | 160 ++++++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 37 deletions(-) diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index 1c5a1484..0c6f62b9 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 { @@ -2980,6 +2985,25 @@ namespace boost { namespace parser { } } omit_attr; + template + struct action_t + { + static constexpr std::false_type recursive{}; + template + constexpr auto + operator()(parser_modifiers const &) const + { + return parser_modifiers{action}; + } + Action action; + }; + + template + constexpr auto action(Action action) + { + return action_t{std::move(action)}; + } + template using final_attribute_type_impl = std::conditional_t; @@ -3421,7 +3445,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{}, @@ -3461,8 +3489,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_)); + } } }; @@ -3481,8 +3513,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_)); + } } }; @@ -3505,10 +3541,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_)); + } } }; @@ -3589,7 +3630,12 @@ namespace boost { namespace parser { 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 @@ -4914,8 +4960,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_; @@ -4989,8 +5039,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_; @@ -5066,7 +5120,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_; @@ -5166,8 +5225,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_; @@ -5235,7 +5298,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_; @@ -5301,8 +5369,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_; @@ -5381,10 +5453,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_; @@ -5454,10 +5530,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_; @@ -6091,9 +6173,8 @@ namespace boost { namespace parser { template constexpr auto operator[](Action action) const { - using action_parser_t = - action_parser>; - return parser::parser_interface{action_parser_t{parser_, action}}; + return parser::parser_interface{ + parser_.with_parser_mods(detail::action(std::move(action)))}; } /** Returns `parser_((Arg &&)arg, (Args &&)args...)`. This is useful @@ -8895,8 +8976,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_;